]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/log/include/boost/log/utility/string_literal.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / log / include / boost / log / utility / string_literal.hpp
CommitLineData
7c673cae
FG
1/*
2 * Copyright Andrey Semashev 2007 - 2016.
3 * Distributed under the Boost Software License, Version 1.0.
4 * (See accompanying file LICENSE_1_0.txt or copy at
5 * http://www.boost.org/LICENSE_1_0.txt)
6 */
7/*!
8 * \file string_literal.hpp
9 * \author Andrey Semashev
10 * \date 24.06.2007
11 *
12 * The header contains implementation of a constant string literal wrapper.
13 */
14
15#ifndef BOOST_LOG_UTILITY_STRING_LITERAL_HPP_INCLUDED_
16#define BOOST_LOG_UTILITY_STRING_LITERAL_HPP_INCLUDED_
17
18#include <cstddef>
19#include <stdexcept>
20#include <iosfwd>
21#include <ios> // std::streamsize
22#include <string>
23#include <iterator>
24#include <boost/throw_exception.hpp>
25#include <boost/type_traits/is_same.hpp>
26#include <boost/log/detail/config.hpp>
27#include <boost/log/utility/string_literal_fwd.hpp>
28#include <boost/log/detail/sfinae_tools.hpp>
29#include <boost/log/detail/header.hpp>
30
31#ifdef BOOST_HAS_PRAGMA_ONCE
32#pragma once
33#endif
34
35namespace boost {
36
37BOOST_LOG_OPEN_NAMESPACE
38
39/*!
40 * \brief String literal wrapper
41 *
42 * The \c basic_string_literal is a thin wrapper around a constant string literal.
43 * It provides interface similar to STL strings, but because of read-only nature
44 * of string literals, lacks ability to modify string contents. However,
45 * \c basic_string_literal objects can be assigned to and cleared.
46 *
47 * The main advantage of this class comparing to other string classes is that
48 * it doesn't dynamically allocate memory and therefore is fast, thin and exception safe.
49 */
50template< typename CharT, typename TraitsT >
51class basic_string_literal
52{
53 //! Self type
54 typedef basic_string_literal< CharT, TraitsT > this_type;
55
56public:
57 typedef CharT value_type;
58 typedef TraitsT traits_type;
59
60 typedef std::size_t size_type;
61 typedef std::ptrdiff_t difference_type;
62 typedef const value_type* const_pointer;
63 typedef value_type const& const_reference;
64 typedef const value_type* const_iterator;
65 typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
66
67 //! Corresponding STL string type
68 typedef std::basic_string< value_type, traits_type > string_type;
69
70private:
71 //! Pointer to the beginning of the literal
72 const_pointer m_pStart;
73 //! Length
74 size_type m_Len;
75
76 //! Empty string literal to support \c clear
77#if !defined(BOOST_LOG_NO_CXX11_CONSTEXPR_DATA_MEMBER_BRACE_INITIALIZERS)
78 static constexpr value_type g_EmptyString[1] = { 0 };
79#else
80 static const value_type g_EmptyString[1];
81#endif
82
83public:
84 /*!
85 * Constructor
86 *
87 * \post <tt>empty() == true</tt>
88 */
89 BOOST_CONSTEXPR basic_string_literal() BOOST_NOEXCEPT : m_pStart(g_EmptyString), m_Len(0) { }
90
91 /*!
92 * Constructor from a string literal
93 *
94 * \post <tt>*this == p</tt>
95 * \param p A zero-terminated constant sequence of characters
96 */
97 template< typename T, size_type LenV >
98 BOOST_CONSTEXPR basic_string_literal(T(&p)[LenV]
99 //! \cond
100 , typename boost::enable_if_c< is_same< T, const value_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()
101 //! \endcond
102 ) BOOST_NOEXCEPT
103 : m_pStart(p), m_Len(LenV - 1)
104 {
105 }
106
107 /*!
108 * Copy constructor
109 *
110 * \post <tt>*this == that</tt>
111 * \param that Source literal to copy string from
112 */
113 BOOST_CONSTEXPR basic_string_literal(basic_string_literal const& that) BOOST_NOEXCEPT : m_pStart(that.m_pStart), m_Len(that.m_Len) {}
114
115 /*!
116 * Assignment operator
117 *
118 * \post <tt>*this == that</tt>
119 * \param that Source literal to copy string from
120 */
121 BOOST_CXX14_CONSTEXPR this_type& operator= (this_type const& that) BOOST_NOEXCEPT
122 {
123 return assign(that);
124 }
125 /*!
126 * Assignment from a string literal
127 *
128 * \post <tt>*this == p</tt>
129 * \param p A zero-terminated constant sequence of characters
130 */
131 template< typename T, size_type LenV >
132 BOOST_CXX14_CONSTEXPR
133#ifndef BOOST_LOG_DOXYGEN_PASS
134 typename boost::enable_if_c<
135 is_same< T, const value_type >::value,
136 this_type&
137 >::type
138#else
139 this_type&
140#endif // BOOST_LOG_DOXYGEN_PASS
141 operator= (T(&p)[LenV]) BOOST_NOEXCEPT
142 {
143 return assign(p);
144 }
145
146 /*!
147 * Lexicographical comparison (equality)
148 *
149 * \param that Comparand
150 * \return \c true if the comparand string equals to this string, \c false otherwise
151 */
152 bool operator== (this_type const& that) const BOOST_NOEXCEPT
153 {
154 return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) == 0);
155 }
156 /*!
157 * Lexicographical comparison (equality)
158 *
159 * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
160 * \return \c true if the comparand string equals to this string, \c false otherwise
161 */
162 bool operator== (const_pointer str) const BOOST_NOEXCEPT
163 {
164 return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) == 0);
165 }
166 /*!
167 * Lexicographical comparison (equality)
168 *
169 * \param that Comparand
170 * \return \c true if the comparand string equals to this string, \c false otherwise
171 */
172 bool operator== (string_type const& that) const BOOST_NOEXCEPT
173 {
174 return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) == 0);
175 }
176
177 /*!
178 * Lexicographical comparison (inequality)
179 *
180 * \param that Comparand
181 * \return \c true if the comparand string is not equal to this string, \c false otherwise
182 */
183 bool operator!= (this_type const& that) const BOOST_NOEXCEPT
184 {
185 return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) != 0);
186 }
187 /*!
188 * Lexicographical comparison (inequality)
189 *
190 * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
191 * \return \c true if the comparand string is not equal to this string, \c false otherwise
192 */
193 bool operator!= (const_pointer str) const BOOST_NOEXCEPT
194 {
195 return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) != 0);
196 }
197 /*!
198 * Lexicographical comparison (inequality)
199 *
200 * \param that Comparand
201 * \return \c true if the comparand string is not equal to this string, \c false otherwise
202 */
203 bool operator!= (string_type const& that) const BOOST_NOEXCEPT
204 {
205 return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) != 0);
206 }
207
208 /*!
209 * Lexicographical comparison (less ordering)
210 *
211 * \param that Comparand
212 * \return \c true if this string is less than the comparand, \c false otherwise
213 */
214 bool operator< (this_type const& that) const BOOST_NOEXCEPT
215 {
216 return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) < 0);
217 }
218 /*!
219 * Lexicographical comparison (less ordering)
220 *
221 * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
222 * \return \c true if this string is less than the comparand, \c false otherwise
223 */
224 bool operator< (const_pointer str) const BOOST_NOEXCEPT
225 {
226 return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) < 0);
227 }
228 /*!
229 * Lexicographical comparison (less ordering)
230 *
231 * \param that Comparand
232 * \return \c true if this string is less than the comparand, \c false otherwise
233 */
234 bool operator< (string_type const& that) const BOOST_NOEXCEPT
235 {
236 return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) < 0);
237 }
238
239 /*!
240 * Lexicographical comparison (less or equal ordering)
241 *
242 * \param that Comparand
243 * \return \c true if this string is less or equal to the comparand, \c false otherwise
244 */
245 bool operator<= (this_type const& that) const BOOST_NOEXCEPT
246 {
247 return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) <= 0);
248 }
249 /*!
250 * Lexicographical comparison (less or equal ordering)
251 *
252 * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
253 * \return \c true if this string is less or equal to the comparand, \c false otherwise
254 */
255 bool operator<= (const_pointer str) const BOOST_NOEXCEPT
256 {
257 return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) <= 0);
258 }
259 /*!
260 * Lexicographical comparison (less or equal ordering)
261 *
262 * \param that Comparand
263 * \return \c true if this string is less or equal to the comparand, \c false otherwise
264 */
265 bool operator<= (string_type const& that) const BOOST_NOEXCEPT
266 {
267 return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) <= 0);
268 }
269
270 /*!
271 * Lexicographical comparison (greater ordering)
272 *
273 * \param that Comparand
274 * \return \c true if this string is greater than the comparand, \c false otherwise
275 */
276 bool operator> (this_type const& that) const BOOST_NOEXCEPT
277 {
278 return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) > 0);
279 }
280 /*!
281 * Lexicographical comparison (greater ordering)
282 *
283 * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
284 * \return \c true if this string is greater than the comparand, \c false otherwise
285 */
286 bool operator> (const_pointer str) const BOOST_NOEXCEPT
287 {
288 return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) > 0);
289 }
290 /*!
291 * Lexicographical comparison (greater ordering)
292 *
293 * \param that Comparand
294 * \return \c true if this string is greater than the comparand, \c false otherwise
295 */
296 bool operator> (string_type const& that) const BOOST_NOEXCEPT
297 {
298 return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) > 0);
299 }
300
301 /*!
302 * Lexicographical comparison (greater or equal ordering)
303 *
304 * \param that Comparand
305 * \return \c true if this string is greater or equal to the comparand, \c false otherwise
306 */
307 bool operator>= (this_type const& that) const BOOST_NOEXCEPT
308 {
309 return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) >= 0);
310 }
311 /*!
312 * Lexicographical comparison (greater or qual ordering)
313 *
314 * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
315 * \return \c true if this string is greater or equal to the comparand, \c false otherwise
316 */
317 bool operator>= (const_pointer str) const BOOST_NOEXCEPT
318 {
319 return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) >= 0);
320 }
321 /*!
322 * Lexicographical comparison (greater or equal ordering)
323 *
324 * \param that Comparand
325 * \return \c true if this string is greater or equal to the comparand, \c false otherwise
326 */
327 bool operator>= (string_type const& that) const BOOST_NOEXCEPT
328 {
329 return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) >= 0);
330 }
331
332 /*!
333 * Subscript operator
334 *
335 * \pre <tt>i < size()</tt>
336 * \param i Requested character index
337 * \return Constant reference to the requested character
338 */
339 BOOST_CONSTEXPR const_reference operator[] (size_type i) const BOOST_NOEXCEPT
340 {
341 return m_pStart[i];
342 }
343 /*!
344 * Checked subscript
345 *
346 * \param i Requested character index
347 * \return Constant reference to the requested character
348 *
349 * \b Throws: An <tt>std::exception</tt>-based exception if index \a i is out of string boundaries
350 */
351 const_reference at(size_type i) const
352 {
353 if (BOOST_UNLIKELY(i >= m_Len))
354 BOOST_THROW_EXCEPTION(std::out_of_range("basic_string_literal::at: the index value is out of range"));
355 return m_pStart[i];
356 }
357
358 /*!
359 * \return Pointer to the beginning of the literal
360 */
361 BOOST_CONSTEXPR const_pointer c_str() const BOOST_NOEXCEPT { return m_pStart; }
362 /*!
363 * \return Pointer to the beginning of the literal
364 */
365 BOOST_CONSTEXPR const_pointer data() const BOOST_NOEXCEPT { return m_pStart; }
366 /*!
367 * \return Length of the literal
368 */
369 BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT { return m_Len; }
370 /*!
371 * \return Length of the literal
372 */
373 BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT { return m_Len; }
374
375 /*!
376 * \return \c true if the literal is an empty string, \c false otherwise
377 */
378 BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT
379 {
380 return (m_Len == 0);
381 }
382
383 /*!
384 * \return Iterator that points to the first character of the literal
385 */
386 BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT { return m_pStart; }
387 /*!
388 * \return Iterator that points after the last character of the literal
389 */
390 BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT { return m_pStart + m_Len; }
391 /*!
392 * \return Reverse iterator that points to the last character of the literal
393 */
394 const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
395 /*!
396 * \return Reverse iterator that points before the first character of the literal
397 */
398 const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
399
400 /*!
401 * \return STL string constructed from the literal
402 */
403 string_type str() const
404 {
405 return string_type(m_pStart, m_Len);
406 }
407
408 /*!
409 * The method clears the literal
410 *
411 * \post <tt>empty() == true</tt>
412 */
413 BOOST_CXX14_CONSTEXPR void clear() BOOST_NOEXCEPT
414 {
415 m_pStart = g_EmptyString;
416 m_Len = 0;
417 }
418 /*!
419 * The method swaps two literals
420 */
421 BOOST_CXX14_CONSTEXPR void swap(this_type& that) BOOST_NOEXCEPT
422 {
423 const_pointer p = m_pStart;
424 m_pStart = that.m_pStart;
425 that.m_pStart = p;
426
427 size_type l = m_Len;
428 m_Len = that.m_Len;
429 that.m_Len = l;
430 }
431
432 /*!
433 * Assignment from another literal
434 *
435 * \post <tt>*this == that</tt>
436 * \param that Source literal to copy string from
437 */
438 BOOST_CXX14_CONSTEXPR this_type& assign(this_type const& that) BOOST_NOEXCEPT
439 {
440 m_pStart = that.m_pStart;
441 m_Len = that.m_Len;
442 return *this;
443 }
444 /*!
445 * Assignment from another literal
446 *
447 * \post <tt>*this == p</tt>
448 * \param p A zero-terminated constant sequence of characters
449 */
450 template< typename T, size_type LenV >
451 BOOST_CXX14_CONSTEXPR
452#ifndef BOOST_LOG_DOXYGEN_PASS
453 typename boost::enable_if_c<
454 is_same< T, const value_type >::value,
455 this_type&
456 >::type
457#else
458 this_type&
459#endif // BOOST_LOG_DOXYGEN_PASS
460 assign(T(&p)[LenV]) BOOST_NOEXCEPT
461 {
462 m_pStart = p;
463 m_Len = LenV - 1;
464 return *this;
465 }
466
467 /*!
468 * The method copies the literal or its portion to an external buffer
469 *
470 * \pre <tt>pos <= size()</tt>
471 * \param str Pointer to the external buffer beginning. Must not be NULL.
472 * The buffer must have enough capacity to accommodate the requested number of characters.
473 * \param n Maximum number of characters to copy
474 * \param pos Starting position to start copying from
475 * \return Number of characters copied
476 *
477 * \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
478 */
479 size_type copy(value_type* str, size_type n, size_type pos = 0) const
480 {
481 if (BOOST_UNLIKELY(pos > m_Len))
482 BOOST_THROW_EXCEPTION(std::out_of_range("basic_string_literal::copy: the position is out of range"));
483
484 size_type len = m_Len - pos;
485 if (len > n)
486 len = n;
487 traits_type::copy(str, m_pStart + pos, len);
488 return len;
489 }
490
491 /*!
492 * Lexicographically compares the argument string to a part of this string
493 *
494 * \pre <tt>pos <= size()</tt>
495 * \param pos Starting position within this string to perform comparison to
496 * \param n Length of the substring of this string to perform comparison to
497 * \param str Comparand. Must point to a sequence of characters, must not be NULL.
498 * \param len Number of characters in the sequence \a str.
499 * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
500 * a positive value if this string is greater than the comparand.
501 *
502 * \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
503 */
504 int compare(size_type pos, size_type n, const_pointer str, size_type len) const
505 {
506 if (BOOST_UNLIKELY(pos > m_Len))
507 BOOST_THROW_EXCEPTION(std::out_of_range("basic_string_literal::compare: the position is out of range"));
508
509 size_type compare_size = m_Len - pos;
510 if (compare_size > len)
511 compare_size = len;
512 if (compare_size > n)
513 compare_size = n;
514 return compare_internal(m_pStart + pos, compare_size, str, compare_size);
515 }
516 /*!
517 * Lexicographically compares the argument string to a part of this string
518 *
519 * \pre <tt>pos <= size()</tt>
520 * \param pos Starting position within this string to perform comparison to
521 * \param n Length of the substring of this string to perform comparison to
522 * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
523 * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
524 * a positive value if this string is greater than the comparand.
525 *
526 * \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
527 */
528 int compare(size_type pos, size_type n, const_pointer str) const BOOST_NOEXCEPT
529 {
530 return compare(pos, n, str, traits_type::length(str));
531 }
532 /*!
533 * Lexicographically compares the argument string literal to a part of this string
534 *
535 * \pre <tt>pos <= size()</tt>
536 * \param pos Starting position within this string to perform comparison to
537 * \param n Length of the substring of this string to perform comparison to
538 * \param that Comparand
539 * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
540 * a positive value if this string is greater than the comparand.
541 *
542 * \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
543 */
544 int compare(size_type pos, size_type n, this_type const& that) const BOOST_NOEXCEPT
545 {
546 return compare(pos, n, that.c_str(), that.size());
547 }
548 /*!
549 * Lexicographically compares the argument string to this string
550 *
551 * \param str Comparand. Must point to a sequence of characters, must not be NULL.
552 * \param len Number of characters in the sequence \a str.
553 * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
554 * a positive value if this string is greater than the comparand.
555 */
556 int compare(const_pointer str, size_type len) const BOOST_NOEXCEPT
557 {
558 return compare(0, m_Len, str, len);
559 }
560 /*!
561 * Lexicographically compares the argument string to this string
562 *
563 * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
564 * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
565 * a positive value if this string is greater than the comparand.
566 */
567 int compare(const_pointer str) const BOOST_NOEXCEPT
568 {
569 return compare(0, m_Len, str, traits_type::length(str));
570 }
571 /*!
572 * Lexicographically compares the argument string to this string
573 *
574 * \param that Comparand
575 * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
576 * a positive value if this string is greater than the comparand.
577 */
578 int compare(this_type const& that) const BOOST_NOEXCEPT
579 {
580 return compare(0, m_Len, that.c_str(), that.size());
581 }
582
583private:
584#ifndef BOOST_LOG_DOXYGEN_PASS
585 //! Internal comparison implementation
586 static int compare_internal(const_pointer pLeft, size_type LeftLen, const_pointer pRight, size_type RightLen) BOOST_NOEXCEPT
587 {
588 if (pLeft != pRight)
589 {
590 const int result = traits_type::compare(pLeft, pRight, (LeftLen < RightLen ? LeftLen : RightLen));
591 if (result != 0)
592 return result;
593 }
594 return LeftLen < RightLen ? -1 : (LeftLen > RightLen ? 1 : 0);
595 }
596#endif // BOOST_LOG_DOXYGEN_PASS
597};
598
599#if !defined(BOOST_LOG_NO_CXX11_CONSTEXPR_DATA_MEMBER_BRACE_INITIALIZERS)
600template< typename CharT, typename TraitsT >
601constexpr typename basic_string_literal< CharT, TraitsT >::value_type
602basic_string_literal< CharT, TraitsT >::g_EmptyString[1];
603#else
604template< typename CharT, typename TraitsT >
605const typename basic_string_literal< CharT, TraitsT >::value_type
606basic_string_literal< CharT, TraitsT >::g_EmptyString[1] = { 0 };
607#endif
608
609namespace aux {
610
611template< typename CharT, typename TraitsT >
612inline void insert_fill_chars(std::basic_ostream< CharT, TraitsT >& strm, std::size_t n)
613{
614 enum { chunk_size = 8 };
615 CharT fill_chars[chunk_size];
616 const CharT filler = strm.fill();
617 for (unsigned int i = 0; i < chunk_size; ++i)
618 fill_chars[i] = filler;
619 for (; n >= chunk_size && strm.good(); n -= chunk_size)
620 strm.write(fill_chars, static_cast< std::size_t >(chunk_size));
621 if (n > 0 && strm.good())
622 strm.write(fill_chars, n);
623}
624
625template< typename CharT, typename TraitsT >
626void insert_aligned(std::basic_ostream< CharT, TraitsT >& strm, const CharT* p, std::size_t size)
627{
628 const std::size_t alignment_size = static_cast< std::size_t >(strm.width()) - size;
629 const bool align_left = (strm.flags() & std::basic_ostream< CharT, TraitsT >::adjustfield) == std::basic_ostream< CharT, TraitsT >::left;
630 if (align_left)
631 {
632 strm.write(p, size);
633 if (strm.good())
634 aux::insert_fill_chars(strm, alignment_size);
635 }
636 else
637 {
638 aux::insert_fill_chars(strm, alignment_size);
639 if (strm.good())
640 strm.write(p, size);
641 }
642}
643
644} // namespace aux
645
646//! Output operator
647template< typename CharT, typename StrmTraitsT, typename LitTraitsT >
648inline std::basic_ostream< CharT, StrmTraitsT >& operator<< (
649 std::basic_ostream< CharT, StrmTraitsT >& strm, basic_string_literal< CharT, LitTraitsT > const& lit)
650{
651 if (strm.good())
652 {
653 const std::size_t size = lit.size();
654 const std::size_t w = static_cast< std::size_t >(strm.width());
655 if (w <= size)
656 strm.write(lit.c_str(), static_cast< std::streamsize >(size));
657 else
658 aux::insert_aligned(strm, lit.c_str(), lit.size());
659 strm.width(0);
660 }
661 return strm;
662}
663
664//! External swap
665template< typename CharT, typename TraitsT >
666inline BOOST_CXX14_CONSTEXPR void swap(basic_string_literal< CharT, TraitsT >& left, basic_string_literal< CharT, TraitsT >& right) BOOST_NOEXCEPT
667{
668 left.swap(right);
669}
670
671//! Creates a string literal wrapper from a constant string literal
672#ifdef BOOST_LOG_USE_CHAR
673template< typename T, std::size_t LenV >
674inline BOOST_CONSTEXPR
675#ifndef BOOST_LOG_DOXYGEN_PASS
676typename boost::enable_if_c<
677 is_same< T, const char >::value,
678 string_literal
679>::type
680#else
681basic_string_literal< T >
682#endif // BOOST_LOG_DOXYGEN_PASS
683str_literal(T(&p)[LenV]) BOOST_NOEXCEPT
684{
685 return string_literal(p);
686}
687#endif
688
689#ifndef BOOST_LOG_DOXYGEN_PASS
690
691#ifdef BOOST_LOG_USE_WCHAR_T
692template< typename T, std::size_t LenV >
693inline BOOST_CONSTEXPR typename boost::enable_if_c<
694 is_same< T, const wchar_t >::value,
695 wstring_literal
696>::type
697str_literal(T(&p)[LenV]) BOOST_NOEXCEPT
698{
699 return wstring_literal(p);
700}
701#endif
702
703#endif // BOOST_LOG_DOXYGEN_PASS
704
705BOOST_LOG_CLOSE_NAMESPACE // namespace log
706
707} // namespace boost
708
709#include <boost/log/detail/footer.hpp>
710
711#endif // BOOST_LOG_UTILITY_STRING_LITERAL_HPP_INCLUDED_