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