Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:29

0001 /*
0002  *          Copyright Andrey Semashev 2007 - 2016.
0003  * Distributed under the Boost Software License, Version 1.0.
0004  *    (See accompanying file LICENSE_1_0.txt or copy at
0005  *          http://www.boost.org/LICENSE_1_0.txt)
0006  */
0007 /*!
0008  * \file   string_literal.hpp
0009  * \author Andrey Semashev
0010  * \date   24.06.2007
0011  *
0012  * The header contains implementation of a constant string literal wrapper.
0013  */
0014 
0015 #ifndef BOOST_LOG_UTILITY_STRING_LITERAL_HPP_INCLUDED_
0016 #define BOOST_LOG_UTILITY_STRING_LITERAL_HPP_INCLUDED_
0017 
0018 #include <cstddef>
0019 #include <stdexcept>
0020 #include <iosfwd>
0021 #include <ios> // std::streamsize
0022 #include <string>
0023 #include <iterator>
0024 #include <boost/throw_exception.hpp>
0025 #include <boost/type_traits/is_same.hpp>
0026 #include <boost/log/detail/config.hpp>
0027 #include <boost/log/utility/string_literal_fwd.hpp>
0028 #include <boost/log/detail/sfinae_tools.hpp>
0029 #include <boost/log/detail/header.hpp>
0030 
0031 #ifdef BOOST_HAS_PRAGMA_ONCE
0032 #pragma once
0033 #endif
0034 
0035 namespace boost {
0036 
0037 BOOST_LOG_OPEN_NAMESPACE
0038 
0039 /*!
0040  * \brief String literal wrapper
0041  *
0042  * The \c basic_string_literal is a thin wrapper around a constant string literal.
0043  * It provides interface similar to STL strings, but because of read-only nature
0044  * of string literals, lacks ability to modify string contents. However,
0045  * \c basic_string_literal objects can be assigned to and cleared.
0046  *
0047  * The main advantage of this class comparing to other string classes is that
0048  * it doesn't dynamically allocate memory and therefore is fast, thin and exception safe.
0049  */
0050 template< typename CharT, typename TraitsT >
0051 class basic_string_literal
0052 {
0053     //! Self type
0054     typedef basic_string_literal< CharT, TraitsT > this_type;
0055 
0056 public:
0057     typedef CharT value_type;
0058     typedef TraitsT traits_type;
0059 
0060     typedef std::size_t size_type;
0061     typedef std::ptrdiff_t difference_type;
0062     typedef const value_type* const_pointer;
0063     typedef value_type const& const_reference;
0064     typedef const value_type* const_iterator;
0065     typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
0066 
0067     //! Corresponding STL string type
0068     typedef std::basic_string< value_type, traits_type > string_type;
0069 
0070 private:
0071     //! Pointer to the beginning of the literal
0072     const_pointer m_pStart;
0073     //! Length
0074     size_type m_Len;
0075 
0076     //! Empty string literal to support \c clear
0077 #if !defined(BOOST_LOG_NO_CXX11_CONSTEXPR_DATA_MEMBER_BRACE_INITIALIZERS)
0078     static constexpr value_type g_EmptyString[1] = { 0 };
0079 #else
0080     static const value_type g_EmptyString[1];
0081 #endif
0082 
0083 public:
0084     /*!
0085      * Constructor
0086      *
0087      * \post <tt>empty() == true</tt>
0088      */
0089     BOOST_CONSTEXPR basic_string_literal() BOOST_NOEXCEPT : m_pStart(g_EmptyString), m_Len(0) { }
0090 
0091     /*!
0092      * Constructor from a string literal
0093      *
0094      * \post <tt>*this == p</tt>
0095      * \param p A zero-terminated constant sequence of characters
0096      */
0097     template< typename T, size_type LenV >
0098     BOOST_CONSTEXPR basic_string_literal(T(&p)[LenV]
0099         //! \cond
0100         , typename boost::enable_if_c< is_same< T, const value_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()
0101         //! \endcond
0102         ) BOOST_NOEXCEPT
0103         : m_pStart(p), m_Len(LenV - 1)
0104     {
0105     }
0106 
0107     /*!
0108      * Copy constructor
0109      *
0110      * \post <tt>*this == that</tt>
0111      * \param that Source literal to copy string from
0112      */
0113     BOOST_CONSTEXPR basic_string_literal(basic_string_literal const& that) BOOST_NOEXCEPT : m_pStart(that.m_pStart), m_Len(that.m_Len) {}
0114 
0115     /*!
0116      * Assignment operator
0117      *
0118      * \post <tt>*this == that</tt>
0119      * \param that Source literal to copy string from
0120      */
0121     BOOST_CXX14_CONSTEXPR this_type& operator= (this_type const& that) BOOST_NOEXCEPT
0122     {
0123         return assign(that);
0124     }
0125     /*!
0126      * Assignment from a string literal
0127      *
0128      * \post <tt>*this == p</tt>
0129      * \param p A zero-terminated constant sequence of characters
0130      */
0131     template< typename T, size_type LenV >
0132     BOOST_CXX14_CONSTEXPR
0133 #ifndef BOOST_LOG_DOXYGEN_PASS
0134     typename boost::enable_if_c<
0135         is_same< T, const value_type >::value,
0136         this_type&
0137     >::type
0138 #else
0139     this_type&
0140 #endif // BOOST_LOG_DOXYGEN_PASS
0141     operator= (T(&p)[LenV]) BOOST_NOEXCEPT
0142     {
0143         return assign(p);
0144     }
0145 
0146     /*!
0147      * Lexicographical comparison (equality)
0148      *
0149      * \param that Comparand
0150      * \return \c true if the comparand string equals to this string, \c false otherwise
0151      */
0152     bool operator== (this_type const& that) const BOOST_NOEXCEPT
0153     {
0154         return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) == 0);
0155     }
0156     /*!
0157      * Lexicographical comparison (equality)
0158      *
0159      * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
0160      * \return \c true if the comparand string equals to this string, \c false otherwise
0161      */
0162     bool operator== (const_pointer str) const BOOST_NOEXCEPT
0163     {
0164         return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) == 0);
0165     }
0166     /*!
0167      * Lexicographical comparison (equality)
0168      *
0169      * \param that Comparand
0170      * \return \c true if the comparand string equals to this string, \c false otherwise
0171      */
0172     bool operator== (string_type const& that) const BOOST_NOEXCEPT
0173     {
0174         return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) == 0);
0175     }
0176 
0177     /*!
0178      * Lexicographical comparison (inequality)
0179      *
0180      * \param that Comparand
0181      * \return \c true if the comparand string is not equal to this string, \c false otherwise
0182      */
0183     bool operator!= (this_type const& that) const BOOST_NOEXCEPT
0184     {
0185         return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) != 0);
0186     }
0187     /*!
0188      * Lexicographical comparison (inequality)
0189      *
0190      * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
0191      * \return \c true if the comparand string is not equal to this string, \c false otherwise
0192      */
0193     bool operator!= (const_pointer str) const BOOST_NOEXCEPT
0194     {
0195         return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) != 0);
0196     }
0197     /*!
0198      * Lexicographical comparison (inequality)
0199      *
0200      * \param that Comparand
0201      * \return \c true if the comparand string is not equal to this string, \c false otherwise
0202      */
0203     bool operator!= (string_type const& that) const BOOST_NOEXCEPT
0204     {
0205         return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) != 0);
0206     }
0207 
0208     /*!
0209      * Lexicographical comparison (less ordering)
0210      *
0211      * \param that Comparand
0212      * \return \c true if this string is less than the comparand, \c false otherwise
0213      */
0214     bool operator< (this_type const& that) const BOOST_NOEXCEPT
0215     {
0216         return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) < 0);
0217     }
0218     /*!
0219      * Lexicographical comparison (less ordering)
0220      *
0221      * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
0222      * \return \c true if this string is less than the comparand, \c false otherwise
0223      */
0224     bool operator< (const_pointer str) const BOOST_NOEXCEPT
0225     {
0226         return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) < 0);
0227     }
0228     /*!
0229      * Lexicographical comparison (less ordering)
0230      *
0231      * \param that Comparand
0232      * \return \c true if this string is less than the comparand, \c false otherwise
0233      */
0234     bool operator< (string_type const& that) const BOOST_NOEXCEPT
0235     {
0236         return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) < 0);
0237     }
0238 
0239     /*!
0240      * Lexicographical comparison (less or equal ordering)
0241      *
0242      * \param that Comparand
0243      * \return \c true if this string is less or equal to the comparand, \c false otherwise
0244      */
0245     bool operator<= (this_type const& that) const BOOST_NOEXCEPT
0246     {
0247         return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) <= 0);
0248     }
0249     /*!
0250      * Lexicographical comparison (less or equal ordering)
0251      *
0252      * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
0253      * \return \c true if this string is less or equal to the comparand, \c false otherwise
0254      */
0255     bool operator<= (const_pointer str) const BOOST_NOEXCEPT
0256     {
0257         return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) <= 0);
0258     }
0259     /*!
0260      * Lexicographical comparison (less or equal ordering)
0261      *
0262      * \param that Comparand
0263      * \return \c true if this string is less or equal to the comparand, \c false otherwise
0264      */
0265     bool operator<= (string_type const& that) const BOOST_NOEXCEPT
0266     {
0267         return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) <= 0);
0268     }
0269 
0270     /*!
0271      * Lexicographical comparison (greater ordering)
0272      *
0273      * \param that Comparand
0274      * \return \c true if this string is greater than the comparand, \c false otherwise
0275      */
0276     bool operator> (this_type const& that) const BOOST_NOEXCEPT
0277     {
0278         return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) > 0);
0279     }
0280     /*!
0281      * Lexicographical comparison (greater ordering)
0282      *
0283      * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
0284      * \return \c true if this string is greater than the comparand, \c false otherwise
0285      */
0286     bool operator> (const_pointer str) const BOOST_NOEXCEPT
0287     {
0288         return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) > 0);
0289     }
0290     /*!
0291      * Lexicographical comparison (greater ordering)
0292      *
0293      * \param that Comparand
0294      * \return \c true if this string is greater than the comparand, \c false otherwise
0295      */
0296     bool operator> (string_type const& that) const BOOST_NOEXCEPT
0297     {
0298         return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) > 0);
0299     }
0300 
0301     /*!
0302      * Lexicographical comparison (greater or equal ordering)
0303      *
0304      * \param that Comparand
0305      * \return \c true if this string is greater or equal to the comparand, \c false otherwise
0306      */
0307     bool operator>= (this_type const& that) const BOOST_NOEXCEPT
0308     {
0309         return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) >= 0);
0310     }
0311     /*!
0312      * Lexicographical comparison (greater or qual ordering)
0313      *
0314      * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
0315      * \return \c true if this string is greater or equal to the comparand, \c false otherwise
0316      */
0317     bool operator>= (const_pointer str) const BOOST_NOEXCEPT
0318     {
0319         return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) >= 0);
0320     }
0321     /*!
0322      * Lexicographical comparison (greater or equal ordering)
0323      *
0324      * \param that Comparand
0325      * \return \c true if this string is greater or equal to the comparand, \c false otherwise
0326      */
0327     bool operator>= (string_type const& that) const BOOST_NOEXCEPT
0328     {
0329         return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) >= 0);
0330     }
0331 
0332     /*!
0333      * Subscript operator
0334      *
0335      * \pre <tt>i < size()</tt>
0336      * \param i Requested character index
0337      * \return Constant reference to the requested character
0338      */
0339     BOOST_CONSTEXPR const_reference operator[] (size_type i) const BOOST_NOEXCEPT
0340     {
0341         return m_pStart[i];
0342     }
0343     /*!
0344      * Checked subscript
0345      *
0346      * \param i Requested character index
0347      * \return Constant reference to the requested character
0348      *
0349      * \b Throws: An <tt>std::exception</tt>-based exception if index \a i is out of string boundaries
0350      */
0351     const_reference at(size_type i) const
0352     {
0353         if (BOOST_UNLIKELY(i >= m_Len))
0354             BOOST_THROW_EXCEPTION(std::out_of_range("basic_string_literal::at: the index value is out of range"));
0355         return m_pStart[i];
0356     }
0357 
0358     /*!
0359      * \return Pointer to the beginning of the literal
0360      */
0361     BOOST_CONSTEXPR const_pointer c_str() const BOOST_NOEXCEPT { return m_pStart; }
0362     /*!
0363      * \return Pointer to the beginning of the literal
0364      */
0365     BOOST_CONSTEXPR const_pointer data() const BOOST_NOEXCEPT { return m_pStart; }
0366     /*!
0367      * \return Length of the literal
0368      */
0369     BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT { return m_Len; }
0370     /*!
0371      * \return Length of the literal
0372      */
0373     BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT { return m_Len; }
0374 
0375     /*!
0376      * \return \c true if the literal is an empty string, \c false otherwise
0377      */
0378     BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT
0379     {
0380         return (m_Len == 0);
0381     }
0382 
0383     /*!
0384      * \return Iterator that points to the first character of the literal
0385      */
0386     BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT { return m_pStart; }
0387     /*!
0388      * \return Iterator that points after the last character of the literal
0389      */
0390     BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT { return m_pStart + m_Len; }
0391     /*!
0392      * \return Reverse iterator that points to the last character of the literal
0393      */
0394     const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
0395     /*!
0396      * \return Reverse iterator that points before the first character of the literal
0397      */
0398     const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
0399 
0400     /*!
0401      * \return STL string constructed from the literal
0402      */
0403     string_type str() const
0404     {
0405         return string_type(m_pStart, m_Len);
0406     }
0407 
0408     /*!
0409      * The method clears the literal
0410      *
0411      * \post <tt>empty() == true</tt>
0412      */
0413     BOOST_CXX14_CONSTEXPR void clear() BOOST_NOEXCEPT
0414     {
0415         m_pStart = g_EmptyString;
0416         m_Len = 0;
0417     }
0418     /*!
0419      * The method swaps two literals
0420      */
0421     BOOST_CXX14_CONSTEXPR void swap(this_type& that) BOOST_NOEXCEPT
0422     {
0423         const_pointer p = m_pStart;
0424         m_pStart = that.m_pStart;
0425         that.m_pStart = p;
0426 
0427         size_type l = m_Len;
0428         m_Len = that.m_Len;
0429         that.m_Len = l;
0430     }
0431 
0432     /*!
0433      * Assignment from another literal
0434      *
0435      * \post <tt>*this == that</tt>
0436      * \param that Source literal to copy string from
0437      */
0438     BOOST_CXX14_CONSTEXPR this_type& assign(this_type const& that) BOOST_NOEXCEPT
0439     {
0440         m_pStart = that.m_pStart;
0441         m_Len = that.m_Len;
0442         return *this;
0443     }
0444     /*!
0445      * Assignment from another literal
0446      *
0447      * \post <tt>*this == p</tt>
0448      * \param p A zero-terminated constant sequence of characters
0449      */
0450     template< typename T, size_type LenV >
0451     BOOST_CXX14_CONSTEXPR
0452 #ifndef BOOST_LOG_DOXYGEN_PASS
0453     typename boost::enable_if_c<
0454         is_same< T, const value_type >::value,
0455         this_type&
0456     >::type
0457 #else
0458     this_type&
0459 #endif // BOOST_LOG_DOXYGEN_PASS
0460     assign(T(&p)[LenV]) BOOST_NOEXCEPT
0461     {
0462         m_pStart = p;
0463         m_Len = LenV - 1;
0464         return *this;
0465     }
0466 
0467     /*!
0468      * The method copies the literal or its portion to an external buffer
0469      *
0470      * \pre <tt>pos <= size()</tt>
0471      * \param str Pointer to the external buffer beginning. Must not be NULL.
0472      *            The buffer must have enough capacity to accommodate the requested number of characters.
0473      * \param n Maximum number of characters to copy
0474      * \param pos Starting position to start copying from
0475      * \return Number of characters copied
0476      *
0477      * \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
0478      */
0479     size_type copy(value_type* str, size_type n, size_type pos = 0) const
0480     {
0481         if (BOOST_UNLIKELY(pos > m_Len))
0482             BOOST_THROW_EXCEPTION(std::out_of_range("basic_string_literal::copy: the position is out of range"));
0483 
0484         size_type len = m_Len - pos;
0485         if (len > n)
0486             len = n;
0487         traits_type::copy(str, m_pStart + pos, len);
0488         return len;
0489     }
0490 
0491     /*!
0492      * Lexicographically compares the argument string to a part of this string
0493      *
0494      * \pre <tt>pos <= size()</tt>
0495      * \param pos Starting position within this string to perform comparison to
0496      * \param n Length of the substring of this string to perform comparison to
0497      * \param str Comparand. Must point to a sequence of characters, must not be NULL.
0498      * \param len Number of characters in the sequence \a str.
0499      * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
0500      *         a positive value if this string is greater than the comparand.
0501      *
0502      * \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
0503      */
0504     int compare(size_type pos, size_type n, const_pointer str, size_type len) const
0505     {
0506         if (BOOST_UNLIKELY(pos > m_Len))
0507             BOOST_THROW_EXCEPTION(std::out_of_range("basic_string_literal::compare: the position is out of range"));
0508 
0509         size_type compare_size = m_Len - pos;
0510         if (compare_size > len)
0511             compare_size = len;
0512         if (compare_size > n)
0513             compare_size = n;
0514         return compare_internal(m_pStart + pos, compare_size, str, compare_size);
0515     }
0516     /*!
0517      * Lexicographically compares the argument string to a part of this string
0518      *
0519      * \pre <tt>pos <= size()</tt>
0520      * \param pos Starting position within this string to perform comparison to
0521      * \param n Length of the substring of this string to perform comparison to
0522      * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
0523      * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
0524      *         a positive value if this string is greater than the comparand.
0525      *
0526      * \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
0527      */
0528     int compare(size_type pos, size_type n, const_pointer str) const BOOST_NOEXCEPT
0529     {
0530         return compare(pos, n, str, traits_type::length(str));
0531     }
0532     /*!
0533      * Lexicographically compares the argument string literal to a part of this string
0534      *
0535      * \pre <tt>pos <= size()</tt>
0536      * \param pos Starting position within this string to perform comparison to
0537      * \param n Length of the substring of this string to perform comparison to
0538      * \param that Comparand
0539      * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
0540      *         a positive value if this string is greater than the comparand.
0541      *
0542      * \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
0543      */
0544     int compare(size_type pos, size_type n, this_type const& that) const BOOST_NOEXCEPT
0545     {
0546         return compare(pos, n, that.c_str(), that.size());
0547     }
0548     /*!
0549      * Lexicographically compares the argument string to this string
0550      *
0551      * \param str Comparand. Must point to a sequence of characters, must not be NULL.
0552      * \param len Number of characters in the sequence \a str.
0553      * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
0554      *         a positive value if this string is greater than the comparand.
0555      */
0556     int compare(const_pointer str, size_type len) const BOOST_NOEXCEPT
0557     {
0558         return compare(0, m_Len, str, len);
0559     }
0560     /*!
0561      * Lexicographically compares the argument string to this string
0562      *
0563      * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
0564      * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
0565      *         a positive value if this string is greater than the comparand.
0566      */
0567     int compare(const_pointer str) const BOOST_NOEXCEPT
0568     {
0569         return compare(0, m_Len, str, traits_type::length(str));
0570     }
0571     /*!
0572      * Lexicographically compares the argument string to this string
0573      *
0574      * \param that Comparand
0575      * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
0576      *         a positive value if this string is greater than the comparand.
0577      */
0578     int compare(this_type const& that) const BOOST_NOEXCEPT
0579     {
0580         return compare(0, m_Len, that.c_str(), that.size());
0581     }
0582 
0583 private:
0584 #ifndef BOOST_LOG_DOXYGEN_PASS
0585     //! Internal comparison implementation
0586     static int compare_internal(const_pointer pLeft, size_type LeftLen, const_pointer pRight, size_type RightLen) BOOST_NOEXCEPT
0587     {
0588         if (pLeft != pRight)
0589         {
0590             const int result = traits_type::compare(pLeft, pRight, (LeftLen < RightLen ? LeftLen : RightLen));
0591             if (result != 0)
0592                 return result;
0593         }
0594         return LeftLen < RightLen ? -1 : (LeftLen > RightLen ? 1 : 0);
0595     }
0596 #endif // BOOST_LOG_DOXYGEN_PASS
0597 };
0598 
0599 #if !defined(BOOST_LOG_NO_CXX11_CONSTEXPR_DATA_MEMBER_BRACE_INITIALIZERS)
0600 template< typename CharT, typename TraitsT >
0601 constexpr typename basic_string_literal< CharT, TraitsT >::value_type
0602 basic_string_literal< CharT, TraitsT >::g_EmptyString[1];
0603 #else
0604 template< typename CharT, typename TraitsT >
0605 const typename basic_string_literal< CharT, TraitsT >::value_type
0606 basic_string_literal< CharT, TraitsT >::g_EmptyString[1] = { 0 };
0607 #endif
0608 
0609 namespace aux {
0610 
0611 template< typename CharT, typename TraitsT >
0612 inline void insert_fill_chars(std::basic_ostream< CharT, TraitsT >& strm, std::size_t n)
0613 {
0614     enum { chunk_size = 8 };
0615     CharT fill_chars[chunk_size];
0616     const CharT filler = strm.fill();
0617     for (unsigned int i = 0; i < chunk_size; ++i)
0618         fill_chars[i] = filler;
0619     for (; n >= chunk_size && strm.good(); n -= chunk_size)
0620         strm.write(fill_chars, static_cast< std::size_t >(chunk_size));
0621     if (n > 0 && strm.good())
0622         strm.write(fill_chars, n);
0623 }
0624 
0625 template< typename CharT, typename TraitsT >
0626 void insert_aligned(std::basic_ostream< CharT, TraitsT >& strm, const CharT* p, std::size_t size)
0627 {
0628     const std::size_t alignment_size = static_cast< std::size_t >(strm.width()) - size;
0629     const bool align_left = (strm.flags() & std::basic_ostream< CharT, TraitsT >::adjustfield) == std::basic_ostream< CharT, TraitsT >::left;
0630     if (align_left)
0631     {
0632         strm.write(p, size);
0633         if (strm.good())
0634             aux::insert_fill_chars(strm, alignment_size);
0635     }
0636     else
0637     {
0638         aux::insert_fill_chars(strm, alignment_size);
0639         if (strm.good())
0640             strm.write(p, size);
0641     }
0642 }
0643 
0644 } // namespace aux
0645 
0646 //! Output operator
0647 template< typename CharT, typename StrmTraitsT, typename LitTraitsT >
0648 inline std::basic_ostream< CharT, StrmTraitsT >& operator<< (
0649     std::basic_ostream< CharT, StrmTraitsT >& strm, basic_string_literal< CharT, LitTraitsT > const& lit)
0650 {
0651     if (strm.good())
0652     {
0653         const std::size_t size = lit.size();
0654         const std::size_t w = static_cast< std::size_t >(strm.width());
0655         if (w <= size)
0656             strm.write(lit.c_str(), static_cast< std::streamsize >(size));
0657         else
0658             aux::insert_aligned(strm, lit.c_str(), lit.size());
0659         strm.width(0);
0660     }
0661     return strm;
0662 }
0663 
0664 //! External swap
0665 template< typename CharT, typename TraitsT >
0666 inline BOOST_CXX14_CONSTEXPR void swap(basic_string_literal< CharT, TraitsT >& left, basic_string_literal< CharT, TraitsT >& right) BOOST_NOEXCEPT
0667 {
0668     left.swap(right);
0669 }
0670 
0671 //! Creates a string literal wrapper from a constant string literal
0672 #ifdef BOOST_LOG_USE_CHAR
0673 template< typename T, std::size_t LenV >
0674 inline BOOST_CONSTEXPR
0675 #ifndef BOOST_LOG_DOXYGEN_PASS
0676 typename boost::enable_if_c<
0677     is_same< T, const char >::value,
0678     string_literal
0679 >::type
0680 #else
0681 basic_string_literal< T >
0682 #endif // BOOST_LOG_DOXYGEN_PASS
0683 str_literal(T(&p)[LenV]) BOOST_NOEXCEPT
0684 {
0685     return string_literal(p);
0686 }
0687 #endif
0688 
0689 #ifndef BOOST_LOG_DOXYGEN_PASS
0690 
0691 #ifdef BOOST_LOG_USE_WCHAR_T
0692 template< typename T, std::size_t LenV >
0693 inline BOOST_CONSTEXPR typename boost::enable_if_c<
0694     is_same< T, const wchar_t >::value,
0695     wstring_literal
0696 >::type
0697 str_literal(T(&p)[LenV]) BOOST_NOEXCEPT
0698 {
0699     return wstring_literal(p);
0700 }
0701 #endif
0702 
0703 #endif // BOOST_LOG_DOXYGEN_PASS
0704 
0705 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0706 
0707 } // namespace boost
0708 
0709 #include <boost/log/detail/footer.hpp>
0710 
0711 #endif // BOOST_LOG_UTILITY_STRING_LITERAL_HPP_INCLUDED_