File indexing completed on 2025-01-18 09:30:28
0001 #ifndef BOOST_CORE_STRING_VIEW_HPP_INCLUDED
0002 #define BOOST_CORE_STRING_VIEW_HPP_INCLUDED
0003
0004
0005
0006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
0007 # pragma once
0008 #endif
0009
0010
0011
0012
0013
0014
0015
0016 #include <boost/core/enable_if.hpp>
0017 #include <boost/core/detail/is_same.hpp>
0018 #include <boost/assert.hpp>
0019 #include <boost/assert/source_location.hpp>
0020 #include <boost/throw_exception.hpp>
0021 #include <boost/config.hpp>
0022 #include <string>
0023 #include <algorithm>
0024 #include <utility>
0025 #include <stdexcept>
0026 #include <cstddef>
0027 #include <cstring>
0028 #include <climits>
0029 #include <iosfwd>
0030 #include <ios>
0031 #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
0032 # include <string_view>
0033 #endif
0034 #if !defined(BOOST_NO_CXX20_HDR_CONCEPTS)
0035 # include <type_traits>
0036 #endif
0037
0038 namespace boost
0039 {
0040
0041
0042 template<class Ch, class Tr> class basic_string_view;
0043
0044
0045 template<class It> std::size_t hash_range( It, It );
0046
0047 namespace core
0048 {
0049 namespace detail
0050 {
0051
0052 template<class Ch> struct sv_to_uchar
0053 {
0054 typedef Ch type;
0055 };
0056
0057 template<> struct sv_to_uchar<char>
0058 {
0059 typedef unsigned char type;
0060 };
0061
0062 #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 406
0063 # pragma GCC diagnostic push
0064 # pragma GCC diagnostic ignored "-Wtype-limits"
0065 #endif
0066
0067 template<class Ch> BOOST_CXX14_CONSTEXPR std::size_t find_first_of( Ch const* p_, std::size_t n_, Ch const* s, std::size_t pos, std::size_t n ) BOOST_NOEXCEPT
0068 {
0069 typedef typename sv_to_uchar<Ch>::type UCh;
0070
0071 unsigned char table[ 256 ] = {};
0072
0073 bool use_table = true;
0074
0075 for( std::size_t j = 0; j < n; ++j )
0076 {
0077 UCh ch = s[ j ];
0078
0079 if( ch >= 0 && ch < 256 )
0080 {
0081 table[ ch ] = 1;
0082 }
0083 else
0084 {
0085 use_table = false;
0086 break;
0087 }
0088 }
0089
0090 if( use_table )
0091 {
0092 for( std::size_t i = pos; i < n_; ++i )
0093 {
0094 UCh ch = p_[ i ];
0095 if( ch >= 0 && ch < 256 && table[ ch ] ) return i;
0096 }
0097 }
0098 else if( n >= 16 )
0099 {
0100 for( std::size_t i = pos; i < n_; ++i )
0101 {
0102 Ch ch = p_[ i ];
0103 if( std::char_traits<Ch>::find( s, n, ch ) != 0 ) return i;
0104 }
0105 }
0106 else
0107 {
0108 for( std::size_t i = pos; i < n_; ++i )
0109 {
0110 Ch ch = p_[ i ];
0111
0112 for( std::size_t j = 0; j < n; ++j )
0113 {
0114 if( s[ j ] == ch ) return i;
0115 }
0116 }
0117 }
0118
0119 return static_cast<std::size_t>( -1 );
0120 }
0121
0122 template<class Ch> BOOST_CXX14_CONSTEXPR std::size_t find_last_of( Ch const* p_, Ch const* s, std::size_t pos, std::size_t n ) BOOST_NOEXCEPT
0123 {
0124 typedef typename sv_to_uchar<Ch>::type UCh;
0125
0126 unsigned char table[ 256 ] = {};
0127
0128 bool use_table = true;
0129
0130 for( std::size_t j = 0; j < n; ++j )
0131 {
0132 UCh ch = s[ j ];
0133
0134 if( ch >= 0 && ch < 256 )
0135 {
0136 table[ ch ] = 1;
0137 }
0138 else
0139 {
0140 use_table = false;
0141 break;
0142 }
0143 }
0144
0145 std::size_t const npos = static_cast< std::size_t >( -1 );
0146
0147 std::size_t i = pos;
0148
0149 if( use_table )
0150 {
0151 do
0152 {
0153 UCh ch = p_[ i ];
0154
0155 if( ch >= 0 && ch < 256 && table[ ch ] ) return i;
0156
0157 --i;
0158 }
0159 while( i != npos );
0160 }
0161 else if( n >= 16 )
0162 {
0163 do
0164 {
0165 Ch ch = p_[ i ];
0166
0167 if( std::char_traits<Ch>::find( s, n, ch ) != 0 ) return i;
0168
0169 --i;
0170 }
0171 while( i != npos );
0172 }
0173 else
0174 {
0175 do
0176 {
0177 Ch ch = p_[ i ];
0178
0179 for( std::size_t j = 0; j < n; ++j )
0180 {
0181 if( s[ j ] == ch ) return i;
0182 }
0183
0184 --i;
0185 }
0186 while( i != npos );
0187 }
0188
0189 return npos;
0190 }
0191
0192 template<class Ch> BOOST_CXX14_CONSTEXPR std::size_t find_first_not_of( Ch const* p_, std::size_t n_, Ch const* s, std::size_t pos, std::size_t n ) BOOST_NOEXCEPT
0193 {
0194 typedef typename sv_to_uchar<Ch>::type UCh;
0195
0196 unsigned char table[ 256 ] = {};
0197
0198 bool use_table = true;
0199
0200 for( std::size_t j = 0; j < n; ++j )
0201 {
0202 UCh ch = s[ j ];
0203
0204 if( ch >= 0 && ch < 256 )
0205 {
0206 table[ ch ] = 1;
0207 }
0208 else
0209 {
0210 use_table = false;
0211 break;
0212 }
0213 }
0214
0215 if( use_table )
0216 {
0217 for( std::size_t i = pos; i < n_; ++i )
0218 {
0219 UCh ch = p_[ i ];
0220 if( !( ch >= 0 && ch < 256 && table[ ch ] ) ) return i;
0221 }
0222 }
0223 else if( n >= 16 )
0224 {
0225 for( std::size_t i = pos; i < n_; ++i )
0226 {
0227 Ch ch = p_[ i ];
0228 if( std::char_traits<Ch>::find( s, n, ch ) == 0 ) return i;
0229 }
0230 }
0231 else
0232 {
0233 for( std::size_t i = pos; i < n_; ++i )
0234 {
0235 Ch ch = p_[ i ];
0236
0237 bool r = false;
0238
0239 for( std::size_t j = 0; j < n; ++j )
0240 {
0241 if( s[ j ] == ch )
0242 {
0243 r = true;
0244 break;
0245 }
0246 }
0247
0248 if( !r ) return i;
0249 }
0250 }
0251
0252 return static_cast<std::size_t>( -1 );
0253 }
0254
0255 template<class Ch> BOOST_CXX14_CONSTEXPR std::size_t find_last_not_of( Ch const* p_, Ch const* s, std::size_t pos, std::size_t n ) BOOST_NOEXCEPT
0256 {
0257 typedef typename sv_to_uchar<Ch>::type UCh;
0258
0259 unsigned char table[ 256 ] = {};
0260
0261 bool use_table = true;
0262
0263 for( std::size_t j = 0; j < n; ++j )
0264 {
0265 UCh ch = s[ j ];
0266
0267 if( ch >= 0 && ch < 256 )
0268 {
0269 table[ ch ] = 1;
0270 }
0271 else
0272 {
0273 use_table = false;
0274 break;
0275 }
0276 }
0277
0278 std::size_t const npos = static_cast< std::size_t >( -1 );
0279
0280 std::size_t i = pos;
0281
0282 if( use_table )
0283 {
0284 do
0285 {
0286 UCh ch = p_[ i ];
0287
0288 if( !( ch >= 0 && ch < 256 && table[ ch ] ) ) return i;
0289
0290 --i;
0291 }
0292 while( i != npos );
0293 }
0294 else if( n >= 16 )
0295 {
0296 do
0297 {
0298 Ch ch = p_[ i ];
0299
0300 if( std::char_traits<Ch>::find( s, n, ch ) == 0 ) return i;
0301
0302 --i;
0303 }
0304 while( i != npos );
0305 }
0306 else
0307 {
0308 do
0309 {
0310 Ch ch = p_[ i ];
0311
0312 bool r = false;
0313
0314 for( std::size_t j = 0; j < n; ++j )
0315 {
0316 if( s[ j ] == ch )
0317 {
0318 r = true;
0319 break;
0320 }
0321 }
0322
0323 if( !r ) return i;
0324
0325 --i;
0326 }
0327 while( i != npos );
0328 }
0329
0330 return npos;
0331 }
0332
0333 #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 406
0334 # pragma GCC diagnostic pop
0335 #endif
0336
0337 }
0338
0339 template<class Ch> class basic_string_view
0340 {
0341 private:
0342
0343 Ch const* p_;
0344 std::size_t n_;
0345
0346 public:
0347
0348
0349
0350 typedef std::char_traits<Ch> traits_type;
0351 typedef Ch value_type;
0352 typedef Ch* pointer;
0353 typedef Ch const* const_pointer;
0354 typedef Ch& reference;
0355 typedef Ch const& const_reference;
0356 typedef Ch const* const_iterator;
0357 typedef const_iterator iterator;
0358 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
0359 typedef const_reverse_iterator reverse_iterator;
0360 typedef std::size_t size_type;
0361 typedef std::ptrdiff_t difference_type;
0362
0363
0364
0365 BOOST_STATIC_CONSTEXPR size_type npos = static_cast<size_type>( -1 );
0366
0367 public:
0368
0369
0370
0371 BOOST_CONSTEXPR basic_string_view() BOOST_NOEXCEPT: p_(), n_()
0372 {
0373 }
0374
0375 BOOST_CONSTEXPR basic_string_view( Ch const* str ) BOOST_NOEXCEPT: p_( str ), n_( traits_type::length( str ) )
0376 {
0377 }
0378
0379 BOOST_CONSTEXPR basic_string_view( Ch const* str, size_type len ) BOOST_NOEXCEPT: p_( str ), n_( len )
0380 {
0381 }
0382
0383 template<class End> BOOST_CXX14_CONSTEXPR basic_string_view( Ch const* first, End last,
0384 typename boost::enable_if<boost::core::detail::is_same<End, Ch const*> >::type* = 0 ) BOOST_NOEXCEPT: p_( first ), n_( last - first )
0385 {
0386 BOOST_ASSERT( last - first >= 0 );
0387 }
0388
0389 template<class A> basic_string_view( std::basic_string<Ch, std::char_traits<Ch>, A> const& str ) BOOST_NOEXCEPT: p_( str.data() ), n_( str.size() )
0390 {
0391 }
0392
0393 #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
0394
0395 basic_string_view( std::basic_string_view<Ch, std::char_traits<Ch> > const& str ) BOOST_NOEXCEPT: p_( str.data() ), n_( str.size() )
0396 {
0397 }
0398
0399 #endif
0400
0401 template<class Ch2> basic_string_view( boost::basic_string_view<Ch2, std::char_traits<Ch2> > const& str,
0402 typename boost::enable_if<boost::core::detail::is_same<Ch, Ch2> >::type* = 0 ) BOOST_NOEXCEPT: p_( str.data() ), n_( str.size() )
0403 {
0404 }
0405
0406 #if !defined(BOOST_NO_CXX11_NULLPTR)
0407 # if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
0408
0409 basic_string_view( std::nullptr_t ) = delete;
0410
0411 # else
0412
0413 private:
0414
0415 basic_string_view( std::nullptr_t );
0416
0417 public:
0418
0419 # endif
0420 #endif
0421
0422
0423
0424
0425
0426 template<class A> operator std::basic_string<Ch, std::char_traits<Ch>, A>() const
0427 {
0428 return std::basic_string<Ch, std::char_traits<Ch>, A>( data(), size() );
0429 }
0430
0431 #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
0432
0433 template<class Ch2, class En = typename boost::enable_if<boost::core::detail::is_same<Ch2, Ch> >::type>
0434 operator std::basic_string_view<Ch2>() const BOOST_NOEXCEPT
0435 {
0436 return std::basic_string_view<Ch>( data(), size() );
0437 }
0438
0439 #endif
0440
0441 template<class Ch2> operator boost::basic_string_view<Ch2,
0442 typename boost::enable_if<boost::core::detail::is_same<Ch2, Ch>, std::char_traits<Ch> >::type> () const BOOST_NOEXCEPT
0443 {
0444 return boost::basic_string_view< Ch, std::char_traits<Ch> >( data(), size() );
0445 }
0446
0447
0448
0449 BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT
0450 {
0451 return p_;
0452 }
0453
0454 BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT
0455 {
0456 return p_ + n_;
0457 }
0458
0459 BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT
0460 {
0461 return p_;
0462 }
0463
0464 BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT
0465 {
0466 return p_ + n_;
0467 }
0468
0469 BOOST_CONSTEXPR const_reverse_iterator rbegin() const BOOST_NOEXCEPT
0470 {
0471 return const_reverse_iterator( end() );
0472 }
0473
0474 BOOST_CONSTEXPR const_reverse_iterator rend() const BOOST_NOEXCEPT
0475 {
0476 return const_reverse_iterator( begin() );
0477 }
0478
0479 BOOST_CONSTEXPR const_reverse_iterator crbegin() const BOOST_NOEXCEPT
0480 {
0481 return const_reverse_iterator( end() );
0482 }
0483
0484 BOOST_CONSTEXPR const_reverse_iterator crend() const BOOST_NOEXCEPT
0485 {
0486 return const_reverse_iterator( begin() );
0487 }
0488
0489
0490
0491 BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT
0492 {
0493 return n_;
0494 }
0495
0496 BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT
0497 {
0498 return n_;
0499 }
0500
0501 BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT
0502 {
0503 return npos / sizeof( Ch );
0504 }
0505
0506 BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT
0507 {
0508 return n_ == 0;
0509 }
0510
0511
0512
0513 BOOST_CXX14_CONSTEXPR const_reference operator[]( size_type pos ) const BOOST_NOEXCEPT
0514 {
0515 BOOST_ASSERT( pos < size() );
0516 return p_[ pos ];
0517 }
0518
0519 BOOST_CXX14_CONSTEXPR const_reference at( size_type pos ) const
0520 {
0521 if( pos >= size() )
0522 {
0523 boost::throw_exception( std::out_of_range( "basic_string_view::at" ), BOOST_CURRENT_LOCATION );
0524 }
0525
0526 return p_[ pos ];
0527 }
0528
0529 BOOST_CXX14_CONSTEXPR const_reference front() const BOOST_NOEXCEPT
0530 {
0531 BOOST_ASSERT( !empty() );
0532 return p_[ 0 ];
0533 }
0534
0535 BOOST_CXX14_CONSTEXPR const_reference back() const BOOST_NOEXCEPT
0536 {
0537 BOOST_ASSERT( !empty() );
0538 return p_[ n_ - 1 ];
0539 }
0540
0541 BOOST_CONSTEXPR const_pointer data() const BOOST_NOEXCEPT
0542 {
0543 return p_;
0544 }
0545
0546
0547
0548 BOOST_CXX14_CONSTEXPR void remove_prefix( size_type n ) BOOST_NOEXCEPT
0549 {
0550 BOOST_ASSERT( n <= size() );
0551
0552 p_ += n;
0553 n_ -= n;
0554 }
0555
0556 BOOST_CXX14_CONSTEXPR void remove_suffix( size_type n ) BOOST_NOEXCEPT
0557 {
0558 BOOST_ASSERT( n <= size() );
0559
0560 n_ -= n;
0561 }
0562
0563 BOOST_CXX14_CONSTEXPR void swap( basic_string_view& s ) BOOST_NOEXCEPT
0564 {
0565 std::swap( p_, s.p_ );
0566 std::swap( n_, s.n_ );
0567 }
0568
0569
0570
0571 BOOST_CXX14_CONSTEXPR size_type copy( Ch* s, size_type n, size_type pos = 0 ) const
0572 {
0573 if( pos > size() )
0574 {
0575 boost::throw_exception( std::out_of_range( "basic_string_view::copy" ), BOOST_CURRENT_LOCATION );
0576 }
0577
0578 std::size_t rlen = (std::min)( n, size() - pos );
0579
0580 traits_type::copy( s, data() + pos, rlen );
0581
0582 return rlen;
0583 }
0584
0585 BOOST_CXX14_CONSTEXPR basic_string_view substr( size_type pos = 0, size_type n = npos ) const
0586 {
0587 if( pos > size() )
0588 {
0589 boost::throw_exception( std::out_of_range( "basic_string_view::substr" ), BOOST_CURRENT_LOCATION );
0590 }
0591
0592 std::size_t rlen = (std::min)( n, size() - pos );
0593
0594 return basic_string_view( data() + pos, rlen );
0595 }
0596
0597
0598
0599 BOOST_CXX14_CONSTEXPR int compare( basic_string_view str ) const BOOST_NOEXCEPT
0600 {
0601 std::size_t rlen = (std::min)( size(), str.size() );
0602
0603 int cmp = traits_type::compare( data(), str.data(), rlen );
0604
0605 if( cmp != 0 ) return cmp;
0606
0607 if( size() == str.size() ) return 0;
0608
0609 return size() < str.size()? -1: +1;
0610 }
0611
0612 BOOST_CONSTEXPR int compare( size_type pos1, size_type n1, basic_string_view str ) const
0613 {
0614 return substr( pos1, n1 ).compare( str );
0615 }
0616
0617 BOOST_CONSTEXPR int compare( size_type pos1, size_type n1, basic_string_view str, size_type pos2, size_type n2 ) const
0618 {
0619 return substr( pos1, n1 ).compare( str.substr( pos2, n2 ) );
0620 }
0621
0622 BOOST_CONSTEXPR int compare( Ch const* s ) const BOOST_NOEXCEPT
0623 {
0624 return compare( basic_string_view( s ) );
0625 }
0626
0627 BOOST_CONSTEXPR int compare( size_type pos1, size_type n1, Ch const* s ) const
0628 {
0629 return substr( pos1, n1 ).compare( basic_string_view( s ) );
0630 }
0631
0632 BOOST_CONSTEXPR int compare( size_type pos1, size_type n1, Ch const* s, size_type n2 ) const
0633 {
0634 return substr( pos1, n1 ).compare( basic_string_view( s, n2 ) );
0635 }
0636
0637
0638
0639 BOOST_CONSTEXPR bool starts_with( basic_string_view x ) const BOOST_NOEXCEPT
0640 {
0641 return size() >= x.size() && traits_type::compare( data(), x.data(), x.size() ) == 0;
0642 }
0643
0644 BOOST_CONSTEXPR bool starts_with( Ch x ) const BOOST_NOEXCEPT
0645 {
0646 return !empty() && front() == x;
0647 }
0648
0649 BOOST_CONSTEXPR bool starts_with( Ch const* x ) const BOOST_NOEXCEPT
0650 {
0651 return starts_with( basic_string_view( x ) );
0652 }
0653
0654
0655
0656 BOOST_CONSTEXPR bool ends_with( basic_string_view x ) const BOOST_NOEXCEPT
0657 {
0658 return size() >= x.size() && traits_type::compare( data() + size() - x.size(), x.data(), x.size() ) == 0;
0659 }
0660
0661 BOOST_CONSTEXPR bool ends_with( Ch x ) const BOOST_NOEXCEPT
0662 {
0663 return !empty() && back() == x;
0664 }
0665
0666 BOOST_CONSTEXPR bool ends_with( Ch const* x ) const BOOST_NOEXCEPT
0667 {
0668 return ends_with( basic_string_view( x ) );
0669 }
0670
0671
0672
0673 BOOST_CONSTEXPR size_type find( basic_string_view str, size_type pos = 0 ) const BOOST_NOEXCEPT
0674 {
0675 return find( str.data(), pos, str.size() );
0676 }
0677
0678 BOOST_CXX14_CONSTEXPR size_type find( Ch c, size_type pos = 0 ) const BOOST_NOEXCEPT
0679 {
0680 if( pos >= size() ) return npos;
0681
0682 Ch const* r = traits_type::find( data() + pos, size() - pos, c );
0683
0684 return r? r - data(): npos;
0685 }
0686
0687 BOOST_CXX14_CONSTEXPR size_type find( Ch const* s, size_type pos, size_type n ) const BOOST_NOEXCEPT
0688 {
0689 if( n == 1 ) return find( s[0], pos );
0690
0691 if( pos + n > size() ) return npos;
0692 if( n == 0 ) return pos;
0693
0694 Ch const* p = data() + pos;
0695 Ch const* last = data() + size() - n + 1;
0696
0697 for( ;; )
0698 {
0699 p = traits_type::find( p, last - p, s[0] );
0700
0701 if( p == 0 ) break;
0702
0703 if( traits_type::compare( p + 1, s + 1, n - 1 ) == 0 ) return p - data();
0704
0705 ++p;
0706 }
0707
0708 return npos;
0709 }
0710
0711 BOOST_CONSTEXPR size_type find( Ch const* s, size_type pos = 0 ) const BOOST_NOEXCEPT
0712 {
0713 return find( s, pos, traits_type::length( s ) );
0714 }
0715
0716
0717
0718 BOOST_CONSTEXPR size_type rfind( basic_string_view str, size_type pos = npos ) const BOOST_NOEXCEPT
0719 {
0720 return rfind( str.data(), pos, str.size() );
0721 }
0722
0723 BOOST_CXX14_CONSTEXPR size_type rfind( Ch c, size_type pos = npos ) const BOOST_NOEXCEPT
0724 {
0725 size_type n = size();
0726
0727 if( n == 0 )
0728 {
0729 return npos;
0730 }
0731
0732 if( pos > n - 1 )
0733 {
0734 pos = n - 1;
0735 }
0736
0737 do
0738 {
0739 if( p_[ pos ] == c ) return pos;
0740 --pos;
0741 }
0742 while( pos != npos );
0743
0744 return npos;
0745 }
0746
0747 BOOST_CXX14_CONSTEXPR size_type rfind( Ch const* s, size_type pos, size_type n ) const BOOST_NOEXCEPT
0748 {
0749 if( n > size() ) return npos;
0750
0751 if( pos > size() - n )
0752 {
0753 pos = size() - n;
0754 }
0755
0756 if( n == 0 ) return pos;
0757
0758 for( ;; )
0759 {
0760 size_type xpos = rfind( s[0], pos );
0761
0762 if( xpos == npos ) return npos;
0763
0764 if( traits_type::compare( data() + xpos, s, n ) == 0 ) return xpos;
0765
0766 if( xpos == 0 ) return npos;
0767
0768 pos = xpos - 1;
0769 }
0770 }
0771
0772 BOOST_CONSTEXPR size_type rfind( Ch const* s, size_type pos = npos ) const BOOST_NOEXCEPT
0773 {
0774 return rfind( s, pos, traits_type::length( s ) );
0775 }
0776
0777
0778
0779 BOOST_CXX14_CONSTEXPR size_type find_first_of( basic_string_view str, size_type pos = 0 ) const BOOST_NOEXCEPT
0780 {
0781 return find_first_of( str.data(), pos, str.size() );
0782 }
0783
0784 BOOST_CONSTEXPR size_type find_first_of( Ch c, size_type pos = 0 ) const BOOST_NOEXCEPT
0785 {
0786 return find( c, pos );
0787 }
0788
0789 BOOST_CXX14_CONSTEXPR size_type find_first_of( Ch const* s, size_type pos, size_type n ) const BOOST_NOEXCEPT
0790 {
0791 if( n == 0 || pos >= size() ) return npos;
0792 if( n == 1 ) return find( s[0], pos );
0793
0794 return detail::find_first_of( data(), size(), s, pos, n );
0795 }
0796
0797 BOOST_CXX14_CONSTEXPR size_type find_first_of( Ch const* s, size_type pos = 0 ) const BOOST_NOEXCEPT
0798 {
0799 return find_first_of( s, pos, traits_type::length( s ) );
0800 }
0801
0802
0803
0804 BOOST_CXX14_CONSTEXPR size_type find_last_of( basic_string_view str, size_type pos = npos ) const BOOST_NOEXCEPT
0805 {
0806 return find_last_of( str.data(), pos, str.size() );
0807 }
0808
0809 BOOST_CONSTEXPR size_type find_last_of( Ch c, size_type pos = npos ) const BOOST_NOEXCEPT
0810 {
0811 return rfind( c, pos );
0812 }
0813
0814 BOOST_CXX14_CONSTEXPR size_type find_last_of( Ch const* s, size_type pos, size_type n ) const BOOST_NOEXCEPT
0815 {
0816 if( n == 1 )
0817 {
0818 return rfind( s[0], pos );
0819 }
0820
0821 size_type m = size();
0822
0823 if( m == 0 )
0824 {
0825 return npos;
0826 }
0827
0828 if( pos > m - 1 )
0829 {
0830 pos = m - 1;
0831 }
0832
0833 return detail::find_last_of( data(), s, pos, n );
0834 }
0835
0836 BOOST_CXX14_CONSTEXPR size_type find_last_of( Ch const* s, size_type pos = npos ) const BOOST_NOEXCEPT
0837 {
0838 return find_last_of( s, pos, traits_type::length( s ) );
0839 }
0840
0841
0842
0843 BOOST_CXX14_CONSTEXPR size_type find_first_not_of( basic_string_view str, size_type pos = 0 ) const BOOST_NOEXCEPT
0844 {
0845 return find_first_not_of( str.data(), pos, str.size() );
0846 }
0847
0848 BOOST_CXX14_CONSTEXPR size_type find_first_not_of( Ch c, size_type pos = 0 ) const BOOST_NOEXCEPT
0849 {
0850 for( std::size_t i = pos; i < n_; ++i )
0851 {
0852 if( p_[ i ] != c ) return i;
0853 }
0854
0855 return npos;
0856 }
0857
0858 BOOST_CXX14_CONSTEXPR size_type find_first_not_of( Ch const* s, size_type pos, size_type n ) const BOOST_NOEXCEPT
0859 {
0860 if( pos >= size() ) return npos;
0861 if( n == 1 ) return find_first_not_of( s[0], pos );
0862
0863 return detail::find_first_not_of( data(), size(), s, pos, n );
0864 }
0865
0866 BOOST_CXX14_CONSTEXPR size_type find_first_not_of( Ch const* s, size_type pos = 0 ) const BOOST_NOEXCEPT
0867 {
0868 return find_first_not_of( s, pos, traits_type::length( s ) );
0869 }
0870
0871
0872
0873 BOOST_CXX14_CONSTEXPR size_type find_last_not_of( basic_string_view str, size_type pos = npos ) const BOOST_NOEXCEPT
0874 {
0875 return find_last_not_of( str.data(), pos, str.size() );
0876 }
0877
0878 BOOST_CXX14_CONSTEXPR size_type find_last_not_of( Ch c, size_type pos = npos ) const BOOST_NOEXCEPT
0879 {
0880 size_type m = size();
0881
0882 if( m == 0 )
0883 {
0884 return npos;
0885 }
0886
0887 if( pos > m - 1 )
0888 {
0889 pos = m - 1;
0890 }
0891
0892 do
0893 {
0894 if( p_[ pos ] != c ) return pos;
0895 --pos;
0896 }
0897 while( pos != npos );
0898
0899 return npos;
0900 }
0901
0902 BOOST_CXX14_CONSTEXPR size_type find_last_not_of( Ch const* s, size_type pos, size_type n ) const BOOST_NOEXCEPT
0903 {
0904 if( n == 1 )
0905 {
0906 return find_last_not_of( s[0], pos );
0907 }
0908
0909 size_type m = size();
0910
0911 if( m == 0 )
0912 {
0913 return npos;
0914 }
0915
0916 if( pos > m - 1 )
0917 {
0918 pos = m - 1;
0919 }
0920
0921 return detail::find_last_not_of( data(), s, pos, n );
0922 }
0923
0924 BOOST_CXX14_CONSTEXPR size_type find_last_not_of( Ch const* s, size_type pos = npos ) const BOOST_NOEXCEPT
0925 {
0926 return find_last_not_of( s, pos, traits_type::length( s ) );
0927 }
0928
0929
0930
0931 BOOST_CONSTEXPR bool contains( basic_string_view sv ) const BOOST_NOEXCEPT
0932 {
0933 return find( sv ) != npos;
0934 }
0935
0936 BOOST_CXX14_CONSTEXPR bool contains( Ch c ) const BOOST_NOEXCEPT
0937 {
0938 Ch const* p = data();
0939 size_type n = size();
0940
0941 if( n >= 16 )
0942 {
0943 return traits_type::find( p, n, c ) != 0;
0944 }
0945 else
0946 {
0947 for( size_type i = 0; i < n; ++i )
0948 {
0949 if( p[ i ] == c ) return true;
0950 }
0951
0952 return false;
0953 }
0954 }
0955
0956 BOOST_CONSTEXPR bool contains( Ch const* s ) const BOOST_NOEXCEPT
0957 {
0958 return find( s ) != npos;
0959 }
0960
0961
0962
0963 BOOST_CXX14_CONSTEXPR friend bool operator==( basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
0964 {
0965 return sv1.size() == sv2.size() && traits_type::compare( sv1.data(), sv2.data(), sv1.size() ) == 0;
0966 }
0967
0968 BOOST_CXX14_CONSTEXPR friend bool operator!=( basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
0969 {
0970 return !( sv1 == sv2 );
0971 }
0972
0973 BOOST_CXX14_CONSTEXPR friend bool operator<( basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
0974 {
0975 return sv1.compare( sv2 ) < 0;
0976 }
0977
0978 BOOST_CXX14_CONSTEXPR friend bool operator<=( basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
0979 {
0980 return sv1.compare( sv2 ) <= 0;
0981 }
0982
0983 BOOST_CXX14_CONSTEXPR friend bool operator>( basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
0984 {
0985 return sv1.compare( sv2 ) > 0;
0986 }
0987
0988 BOOST_CXX14_CONSTEXPR friend bool operator>=( basic_string_view sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
0989 {
0990 return sv1.compare( sv2 ) >= 0;
0991 }
0992
0993 #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
0994
0995
0996
0997
0998
0999 BOOST_CXX14_CONSTEXPR friend bool operator==( basic_string_view sv1, std::basic_string_view<Ch> sv2 ) BOOST_NOEXCEPT
1000 {
1001 return sv1.size() == sv2.size() && traits_type::compare( sv1.data(), sv2.data(), sv1.size() ) == 0;
1002 }
1003
1004 BOOST_CXX14_CONSTEXPR friend bool operator==( std::basic_string_view<Ch> sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1005 {
1006 return sv1.size() == sv2.size() && traits_type::compare( sv1.data(), sv2.data(), sv1.size() ) == 0;
1007 }
1008
1009 BOOST_CXX14_CONSTEXPR friend bool operator!=( basic_string_view sv1, std::basic_string_view<Ch> sv2 ) BOOST_NOEXCEPT
1010 {
1011 return !( sv1 == sv2 );
1012 }
1013
1014 BOOST_CXX14_CONSTEXPR friend bool operator!=( std::basic_string_view<Ch> sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1015 {
1016 return !( sv1 == sv2 );
1017 }
1018
1019 BOOST_CXX14_CONSTEXPR friend bool operator<( basic_string_view sv1, std::basic_string_view<Ch> sv2 ) BOOST_NOEXCEPT
1020 {
1021 return sv1.compare( sv2 ) < 0;
1022 }
1023
1024 BOOST_CXX14_CONSTEXPR friend bool operator<( std::basic_string_view<Ch> sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1025 {
1026 return sv1.compare( sv2 ) < 0;
1027 }
1028
1029 BOOST_CXX14_CONSTEXPR friend bool operator<=( basic_string_view sv1, std::basic_string_view<Ch> sv2 ) BOOST_NOEXCEPT
1030 {
1031 return sv1.compare( sv2 ) <= 0;
1032 }
1033
1034 BOOST_CXX14_CONSTEXPR friend bool operator<=( std::basic_string_view<Ch> sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1035 {
1036 return sv1.compare( sv2 ) <= 0;
1037 }
1038
1039 BOOST_CXX14_CONSTEXPR friend bool operator>( basic_string_view sv1, std::basic_string_view<Ch> sv2 ) BOOST_NOEXCEPT
1040 {
1041 return sv1.compare( sv2 ) > 0;
1042 }
1043
1044 BOOST_CXX14_CONSTEXPR friend bool operator>( std::basic_string_view<Ch> sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1045 {
1046 return sv1.compare( sv2 ) > 0;
1047 }
1048
1049 BOOST_CXX14_CONSTEXPR friend bool operator>=( basic_string_view sv1, std::basic_string_view<Ch> sv2 ) BOOST_NOEXCEPT
1050 {
1051 return sv1.compare( sv2 ) >= 0;
1052 }
1053
1054 BOOST_CXX14_CONSTEXPR friend bool operator>=( std::basic_string_view<Ch> sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1055 {
1056 return sv1.compare( sv2 ) >= 0;
1057 }
1058
1059
1060
1061 BOOST_CXX14_CONSTEXPR friend bool operator==( basic_string_view sv1, Ch const* sv2 ) BOOST_NOEXCEPT
1062 {
1063 return sv1 == basic_string_view( sv2 );
1064 }
1065
1066 BOOST_CXX14_CONSTEXPR friend bool operator==( Ch const* sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1067 {
1068 return basic_string_view( sv1 ) == sv2;
1069 }
1070
1071 BOOST_CXX14_CONSTEXPR friend bool operator!=( basic_string_view sv1, Ch const* sv2 ) BOOST_NOEXCEPT
1072 {
1073 return !( sv1 == sv2 );
1074 }
1075
1076 BOOST_CXX14_CONSTEXPR friend bool operator!=( Ch const* sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1077 {
1078 return !( sv1 == sv2 );
1079 }
1080
1081 BOOST_CXX14_CONSTEXPR friend bool operator<( basic_string_view sv1, Ch const* sv2 ) BOOST_NOEXCEPT
1082 {
1083 return sv1.compare( sv2 ) < 0;
1084 }
1085
1086 BOOST_CXX14_CONSTEXPR friend bool operator<( Ch const* sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1087 {
1088 return sv2.compare( sv1 ) > 0;
1089 }
1090
1091 BOOST_CXX14_CONSTEXPR friend bool operator<=( basic_string_view sv1, Ch const* sv2 ) BOOST_NOEXCEPT
1092 {
1093 return sv1.compare( sv2 ) <= 0;
1094 }
1095
1096 BOOST_CXX14_CONSTEXPR friend bool operator<=( Ch const* sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1097 {
1098 return sv2.compare( sv1 ) >= 0;
1099 }
1100
1101 BOOST_CXX14_CONSTEXPR friend bool operator>( basic_string_view sv1, Ch const* sv2 ) BOOST_NOEXCEPT
1102 {
1103 return sv1.compare( sv2 ) > 0;
1104 }
1105
1106 BOOST_CXX14_CONSTEXPR friend bool operator>( Ch const* sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1107 {
1108 return sv2.compare( sv1 ) < 0;
1109 }
1110
1111 BOOST_CXX14_CONSTEXPR friend bool operator>=( basic_string_view sv1, Ch const* sv2 ) BOOST_NOEXCEPT
1112 {
1113 return sv1.compare( sv2 ) >= 0;
1114 }
1115
1116 BOOST_CXX14_CONSTEXPR friend bool operator>=( Ch const* sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1117 {
1118 return sv2.compare( sv1 ) <= 0;
1119 }
1120
1121
1122
1123 template<class A> BOOST_CXX14_CONSTEXPR friend bool operator==( basic_string_view sv1, std::basic_string<Ch, std::char_traits<Ch>, A> const& sv2 ) BOOST_NOEXCEPT
1124 {
1125 return sv1.size() == sv2.size() && traits_type::compare( sv1.data(), sv2.data(), sv1.size() ) == 0;
1126 }
1127
1128 template<class A> BOOST_CXX14_CONSTEXPR friend bool operator==( std::basic_string<Ch, std::char_traits<Ch>, A> const& sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1129 {
1130 return sv1.size() == sv2.size() && traits_type::compare( sv1.data(), sv2.data(), sv1.size() ) == 0;
1131 }
1132
1133 template<class A> BOOST_CXX14_CONSTEXPR friend bool operator!=( basic_string_view sv1, std::basic_string<Ch, std::char_traits<Ch>, A> const& sv2 ) BOOST_NOEXCEPT
1134 {
1135 return !( sv1 == sv2 );
1136 }
1137
1138 template<class A> BOOST_CXX14_CONSTEXPR friend bool operator!=( std::basic_string<Ch, std::char_traits<Ch>, A> const& sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1139 {
1140 return !( sv1 == sv2 );
1141 }
1142
1143 template<class A> BOOST_CXX14_CONSTEXPR friend bool operator<( basic_string_view sv1, std::basic_string<Ch, std::char_traits<Ch>, A> const& sv2 ) BOOST_NOEXCEPT
1144 {
1145 return sv1.compare( sv2 ) < 0;
1146 }
1147
1148 template<class A> BOOST_CXX14_CONSTEXPR friend bool operator<( std::basic_string<Ch, std::char_traits<Ch>, A> const& sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1149 {
1150 return sv2.compare( sv1 ) > 0;
1151 }
1152
1153 template<class A> BOOST_CXX14_CONSTEXPR friend bool operator<=( basic_string_view sv1, std::basic_string<Ch, std::char_traits<Ch>, A> const& sv2 ) BOOST_NOEXCEPT
1154 {
1155 return sv1.compare( sv2 ) <= 0;
1156 }
1157
1158 template<class A> BOOST_CXX14_CONSTEXPR friend bool operator<=( std::basic_string<Ch, std::char_traits<Ch>, A> const& sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1159 {
1160 return sv2.compare( sv1 ) >= 0;
1161 }
1162
1163 template<class A> BOOST_CXX14_CONSTEXPR friend bool operator>( basic_string_view sv1, std::basic_string<Ch, std::char_traits<Ch>, A> const& sv2 ) BOOST_NOEXCEPT
1164 {
1165 return sv1.compare( sv2 ) > 0;
1166 }
1167
1168 template<class A> BOOST_CXX14_CONSTEXPR friend bool operator>( std::basic_string<Ch, std::char_traits<Ch>, A> const& sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1169 {
1170 return sv2.compare( sv1 ) < 0;
1171 }
1172
1173 template<class A> BOOST_CXX14_CONSTEXPR friend bool operator>=( basic_string_view sv1, std::basic_string<Ch, std::char_traits<Ch>, A> const& sv2 ) BOOST_NOEXCEPT
1174 {
1175 return sv1.compare( sv2 ) >= 0;
1176 }
1177
1178 template<class A> BOOST_CXX14_CONSTEXPR friend bool operator>=( std::basic_string<Ch, std::char_traits<Ch>, A> const& sv1, basic_string_view sv2 ) BOOST_NOEXCEPT
1179 {
1180 return sv2.compare( sv1 ) <= 0;
1181 }
1182
1183 #endif
1184
1185 inline friend std::size_t hash_value( basic_string_view const& sv )
1186 {
1187 return boost::hash_range( sv.begin(), sv.end() );
1188 }
1189 };
1190
1191
1192
1193 template<class Ch> std::basic_ostream<Ch>& operator<<( std::basic_ostream<Ch>& os, basic_string_view<Ch> str )
1194 {
1195 Ch const* p = str.data();
1196 std::streamsize n = str.size();
1197
1198 std::streamsize m = os.width();
1199
1200 if( n >= m )
1201 {
1202 os.write( p, n );
1203 }
1204 else if( ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::left )
1205 {
1206 os.write( p, n );
1207
1208 os.width( m - n );
1209 os << "";
1210 }
1211 else
1212 {
1213 os.width( m - n );
1214 os << "";
1215
1216 os.write( p, n );
1217 }
1218
1219 os.width( 0 );
1220 return os;
1221 }
1222
1223 #if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
1224 template<class Ch> BOOST_CONSTEXPR_OR_CONST std::size_t basic_string_view<Ch>::npos;
1225 #endif
1226
1227
1228
1229 typedef basic_string_view<char> string_view;
1230 typedef basic_string_view<wchar_t> wstring_view;
1231
1232 #if !defined(BOOST_NO_CXX11_CHAR16_T)
1233 typedef basic_string_view<char16_t> u16string_view;
1234 #endif
1235
1236 #if !defined(BOOST_NO_CXX11_CHAR32_T)
1237 typedef basic_string_view<char32_t> u32string_view;
1238 #endif
1239
1240 #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
1241 typedef basic_string_view<char8_t> u8string_view;
1242 #endif
1243
1244 }
1245 }
1246
1247
1248
1249
1250 #if !defined(BOOST_NO_CXX20_HDR_CONCEPTS)
1251
1252 template<class Ch, class A, template<class> class Q1, template<class> class Q2>
1253 struct std::basic_common_reference<
1254 boost::core::basic_string_view<Ch>,
1255 std::basic_string<Ch, std::char_traits<Ch>, A>,
1256 Q1, Q2>
1257 {
1258 using type = boost::core::basic_string_view<Ch>;
1259 };
1260
1261 template<class Ch, class A, template<class> class Q1, template<class> class Q2>
1262 struct std::basic_common_reference<
1263 std::basic_string<Ch, std::char_traits<Ch>, A>,
1264 boost::core::basic_string_view<Ch>,
1265 Q1, Q2>
1266 {
1267 using type = boost::core::basic_string_view<Ch>;
1268 };
1269
1270 #endif
1271
1272 #endif