File indexing completed on 2025-01-18 09:39:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
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
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 template< typename CharT, typename TraitsT >
0051 class basic_string_literal
0052 {
0053
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
0068 typedef std::basic_string< value_type, traits_type > string_type;
0069
0070 private:
0071
0072 const_pointer m_pStart;
0073
0074 size_type m_Len;
0075
0076
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
0086
0087
0088
0089 BOOST_CONSTEXPR basic_string_literal() BOOST_NOEXCEPT : m_pStart(g_EmptyString), m_Len(0) { }
0090
0091
0092
0093
0094
0095
0096
0097 template< typename T, size_type LenV >
0098 BOOST_CONSTEXPR basic_string_literal(T(&p)[LenV]
0099
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
0102 ) BOOST_NOEXCEPT
0103 : m_pStart(p), m_Len(LenV - 1)
0104 {
0105 }
0106
0107
0108
0109
0110
0111
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
0117
0118
0119
0120
0121 BOOST_CXX14_CONSTEXPR this_type& operator= (this_type const& that) BOOST_NOEXCEPT
0122 {
0123 return assign(that);
0124 }
0125
0126
0127
0128
0129
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
0141 operator= (T(&p)[LenV]) BOOST_NOEXCEPT
0142 {
0143 return assign(p);
0144 }
0145
0146
0147
0148
0149
0150
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
0158
0159
0160
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
0168
0169
0170
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
0179
0180
0181
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
0189
0190
0191
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
0199
0200
0201
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
0210
0211
0212
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
0220
0221
0222
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
0230
0231
0232
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
0241
0242
0243
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
0251
0252
0253
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
0261
0262
0263
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
0272
0273
0274
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
0282
0283
0284
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
0292
0293
0294
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
0303
0304
0305
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
0313
0314
0315
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
0323
0324
0325
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
0334
0335
0336
0337
0338
0339 BOOST_CONSTEXPR const_reference operator[] (size_type i) const BOOST_NOEXCEPT
0340 {
0341 return m_pStart[i];
0342 }
0343
0344
0345
0346
0347
0348
0349
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
0360
0361 BOOST_CONSTEXPR const_pointer c_str() const BOOST_NOEXCEPT { return m_pStart; }
0362
0363
0364
0365 BOOST_CONSTEXPR const_pointer data() const BOOST_NOEXCEPT { return m_pStart; }
0366
0367
0368
0369 BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT { return m_Len; }
0370
0371
0372
0373 BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT { return m_Len; }
0374
0375
0376
0377
0378 BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT
0379 {
0380 return (m_Len == 0);
0381 }
0382
0383
0384
0385
0386 BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT { return m_pStart; }
0387
0388
0389
0390 BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT { return m_pStart + m_Len; }
0391
0392
0393
0394 const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
0395
0396
0397
0398 const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
0399
0400
0401
0402
0403 string_type str() const
0404 {
0405 return string_type(m_pStart, m_Len);
0406 }
0407
0408
0409
0410
0411
0412
0413 BOOST_CXX14_CONSTEXPR void clear() BOOST_NOEXCEPT
0414 {
0415 m_pStart = g_EmptyString;
0416 m_Len = 0;
0417 }
0418
0419
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
0434
0435
0436
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
0446
0447
0448
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
0460 assign(T(&p)[LenV]) BOOST_NOEXCEPT
0461 {
0462 m_pStart = p;
0463 m_Len = LenV - 1;
0464 return *this;
0465 }
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
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
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
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
0518
0519
0520
0521
0522
0523
0524
0525
0526
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
0534
0535
0536
0537
0538
0539
0540
0541
0542
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
0550
0551
0552
0553
0554
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
0562
0563
0564
0565
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
0573
0574
0575
0576
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
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
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 }
0645
0646
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
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
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
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
0704
0705 BOOST_LOG_CLOSE_NAMESPACE
0706
0707 }
0708
0709 #include <boost/log/detail/footer.hpp>
0710
0711 #endif