464namespace
nonstd {
namespace sv_lite {
471template<
typename CharT >
472inline nssv_constexpr14 int compare( CharT
const * s1, CharT
const * s2, std::size_t count )
474 while ( count-- != 0 )
476 if ( *s1 < *s2 )
return -1;
477 if ( *s1 > *s2 )
return +1;
483#if nssv_HAVE_BUILTIN_MEMCMP
487inline nssv_constexpr14 int compare(
char const * s1,
char const * s2, std::size_t count )
494#if nssv_HAVE_BUILTIN_STRLEN
505#if defined(__OPTIMIZE__)
510template<
typename CharT >
511inline nssv_constexpr std::size_t length( CharT * s, std::size_t result = 0 )
513 return *s ==
'\0' ? result : length( s + 1, result + 1 );
520template<
typename CharT >
523 std::size_t result = 0;
524 while ( *s++ !=
'\0' )
538 class Traits = std::char_traits<CharT>
540class basic_string_view;
551class basic_string_view
556 typedef Traits traits_type;
557 typedef CharT value_type;
559 typedef CharT * pointer;
560 typedef CharT
const * const_pointer;
561 typedef CharT & reference;
562 typedef CharT
const & const_reference;
564 typedef const_pointer iterator;
565 typedef const_pointer const_iterator;
566 typedef std::reverse_iterator< const_iterator > reverse_iterator;
567 typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
569 typedef std::size_t size_type;
570 typedef std::ptrdiff_t difference_type;
579#if nssv_CPP11_OR_GREATER
583 : data_( other.data_)
584 , size_( other.size_)
595#if nssv_CPP17_OR_GREATER
596 , size_( Traits::length(s) )
597#elif nssv_CPP11_OR_GREATER
598 , size_( detail::length(s) )
600 , size_( Traits::length(s) )
606#if nssv_CPP11_OR_GREATER
647 return data_at( pos );
652#if nssv_CONFIG_NO_EXCEPTIONS
653 assert( pos < size() );
657 throw std::out_of_range(
"nonstd::string_view::at()");
660 return data_at( pos );
663 nssv_constexpr const_reference front()
const {
return data_at( 0 ); }
664 nssv_constexpr const_reference back()
const {
return data_at( size() - 1 ); }
672 assert( n <= size() );
679 assert( n <= size() );
686 swap( data_, other.data_ );
687 swap( size_, other.size_ );
692 size_type copy( CharT * dest, size_type n, size_type pos = 0 )
const
694#if nssv_CONFIG_NO_EXCEPTIONS
695 assert( pos <= size() );
699 throw std::out_of_range(
"nonstd::string_view::copy()");
702 const size_type rlen = (std::min)( n, size() - pos );
704 (void) Traits::copy( dest, data() + pos, rlen );
709 nssv_constexpr14 basic_string_view substr( size_type pos = 0, size_type n = npos )
const
711#if nssv_CONFIG_NO_EXCEPTIONS
712 assert( pos <= size() );
716 throw std::out_of_range(
"nonstd::string_view::substr()");
719 return basic_string_view( data() + pos, (std::min)( n, size() - pos ) );
726#if nssv_CPP17_OR_GREATER
727 if (
const int result = Traits::compare( data(), other.data(), (std::min)( size(), other.size() ) ) )
729 if (
const int result = detail::compare( data(), other.data(), (std::min)( size(), other.size() ) ) )
735 return size() == other.size() ? 0 : size() < other.size() ? -1 : 1;
738 nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other )
const
740 return substr( pos1, n1 ).compare( other );
743 nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other, size_type pos2, size_type n2 )
const
745 return substr( pos1, n1 ).compare( other.substr( pos2, n2 ) );
750 return compare( basic_string_view( s ) );
753 nssv_constexpr int compare( size_type pos1, size_type n1, CharT
const * s )
const
755 return substr( pos1, n1 ).compare( basic_string_view( s ) );
758 nssv_constexpr int compare( size_type pos1, size_type n1, CharT
const * s, size_type n2 )
const
760 return substr( pos1, n1 ).compare( basic_string_view( s, n2 ) );
769 return size() >= v.size() && compare( 0, v.size(), v ) == 0;
774 return starts_with( basic_string_view( &c, 1 ) );
779 return starts_with( basic_string_view( s ) );
786 return size() >= v.size() && compare( size() - v.size(), npos, v ) == 0;
791 return ends_with( basic_string_view( &c, 1 ) );
796 return ends_with( basic_string_view( s ) );
803 return assert( v.size() == 0 || v.data() !=
nssv_nullptr )
806 : to_pos( std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
811 return find( basic_string_view( &c, 1 ), pos );
814 nssv_constexpr14 size_type find( CharT
const * s, size_type pos, size_type n )
const
816 return find( basic_string_view( s, n ), pos );
821 return find( basic_string_view( s ), pos );
828 if ( size() < v.size() )
835 return (std::min)( size(), pos );
838 const_iterator last = cbegin() + (std::min)( size() - v.size(), pos ) + v.size();
839 const_iterator result = std::find_end( cbegin(), last, v.cbegin(), v.cend(), Traits::eq );
841 return result != last ? size_type( result - cbegin() ) : npos;
846 return rfind( basic_string_view( &c, 1 ), pos );
849 nssv_constexpr14 size_type rfind( CharT
const * s, size_type pos, size_type n )
const
851 return rfind( basic_string_view( s, n ), pos );
854 nssv_constexpr14 size_type rfind( CharT
const * s, size_type pos = npos )
const
856 return rfind( basic_string_view( s ), pos );
865 : to_pos( std::find_first_of( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
870 return find_first_of( basic_string_view( &c, 1 ), pos );
873 nssv_constexpr size_type find_first_of( CharT
const * s, size_type pos, size_type n )
const
875 return find_first_of( basic_string_view( s, n ), pos );
878 nssv_constexpr size_type find_first_of( CharT
const * s, size_type pos = 0 )
const
880 return find_first_of( basic_string_view( s ), pos );
890 ? find_last_of( v, size() - 1 )
891 : to_pos( std::find_first_of( const_reverse_iterator( cbegin() + pos + 1 ), crend(), v.cbegin(), v.cend(), Traits::eq ) );
896 return find_last_of( basic_string_view( &c, 1 ), pos );
899 nssv_constexpr size_type find_last_of( CharT
const * s, size_type pos, size_type count )
const
901 return find_last_of( basic_string_view( s, count ), pos );
904 nssv_constexpr size_type find_last_of( CharT
const * s, size_type pos = npos )
const
906 return find_last_of( basic_string_view( s ), pos );
915 : to_pos( std::find_if( cbegin() + pos, cend(), not_in_view( v ) ) );
920 return find_first_not_of( basic_string_view( &c, 1 ), pos );
923 nssv_constexpr size_type find_first_not_of( CharT
const * s, size_type pos, size_type count )
const
925 return find_first_not_of( basic_string_view( s, count ), pos );
928 nssv_constexpr size_type find_first_not_of( CharT
const * s, size_type pos = 0 )
const
930 return find_first_not_of( basic_string_view( s ), pos );
940 ? find_last_not_of( v, size() - 1 )
941 : to_pos( std::find_if( const_reverse_iterator( cbegin() + pos + 1 ), crend(), not_in_view( v ) ) );
946 return find_last_not_of( basic_string_view( &c, 1 ), pos );
949 nssv_constexpr size_type find_last_not_of( CharT
const * s, size_type pos, size_type count )
const
951 return find_last_not_of( basic_string_view( s, count ), pos );
954 nssv_constexpr size_type find_last_not_of( CharT
const * s, size_type pos = npos )
const
956 return find_last_not_of( basic_string_view( s ), pos );
961#if nssv_CPP17_OR_GREATER
963#elif nssv_CPP11_OR_GREATER
964 enum : size_type { npos = size_type(-1) };
966 enum { npos = size_type(-1) };
972 const basic_string_view v;
974 nssv_constexpr explicit not_in_view( basic_string_view v_ ) : v( v_ ) {}
978 return npos == v.find_first_of( c );
984 return it == cend() ? npos : size_type( it - cbegin() );
987 nssv_constexpr size_type to_pos( const_reverse_iterator it )
const
989 return it == crend() ? npos : size_type( crend() - it - 1 );
994#if nssv_BETWEEN( nssv_COMPILER_GNUC_VERSION, 1, 500 )
997 return assert( pos < size() ), data_[pos];
1002 const_pointer data_;
1006#if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
1008 template<
class Allocator >
1009 basic_string_view( std::basic_string<CharT, Traits, Allocator>
const & s )
nssv_noexcept
1014#if nssv_HAVE_EXPLICIT_CONVERSION
1016 template<
class Allocator >
1017 explicit operator std::basic_string<CharT, Traits, Allocator>()
const
1019 return to_string( Allocator() );
1024#if nssv_CPP11_OR_GREATER
1026 template<
class Allocator = std::allocator<CharT> >
1027 std::basic_string<CharT, Traits, Allocator>
1028 to_string( Allocator
const & a = Allocator() )
const
1030 return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
1035 std::basic_string<CharT, Traits>
1038 return std::basic_string<CharT, Traits>( begin(), end() );
1041 template<
class Allocator >
1042 std::basic_string<CharT, Traits, Allocator>
1043 to_string( Allocator
const & a )
const
1045 return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
1060template<
class CharT,
class Traits >
1062 basic_string_view <CharT, Traits> lhs,
1064{
return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
1066template<
class CharT,
class Traits >
1068 basic_string_view <CharT, Traits> lhs,
1070{
return !( lhs == rhs ); }
1072template<
class CharT,
class Traits >
1074 basic_string_view <CharT, Traits> lhs,
1076{
return lhs.compare( rhs ) < 0; }
1078template<
class CharT,
class Traits >
1080 basic_string_view <CharT, Traits> lhs,
1082{
return lhs.compare( rhs ) <= 0; }
1084template<
class CharT,
class Traits >
1086 basic_string_view <CharT, Traits> lhs,
1088{
return lhs.compare( rhs ) > 0; }
1090template<
class CharT,
class Traits >
1092 basic_string_view <CharT, Traits> lhs,
1094{
return lhs.compare( rhs ) >= 0; }
1101#if ! nssv_CPP11_OR_GREATER || nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 100, 141 )
1107template<
class CharT,
class Traits>
1109 basic_string_view<CharT, Traits> lhs,
1111{
return lhs.size() == detail::length( rhs ) && lhs.compare( rhs ) == 0; }
1113template<
class CharT,
class Traits>
1117{
return detail::length( lhs ) == rhs.size() && rhs.compare( lhs ) == 0; }
1119template<
class CharT,
class Traits>
1121 basic_string_view<CharT, Traits> lhs,
1123{
return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
1125template<
class CharT,
class Traits>
1127 std::basic_string<CharT, Traits> rhs,
1129{
return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
1133template<
class CharT,
class Traits>
1135 basic_string_view<CharT, Traits> lhs,
1137{
return !( lhs == rhs ); }
1139template<
class CharT,
class Traits>
1143{
return !( lhs == rhs ); }
1145template<
class CharT,
class Traits>
1147 basic_string_view<CharT, Traits> lhs,
1149{
return !( lhs == rhs ); }
1151template<
class CharT,
class Traits>
1153 std::basic_string<CharT, Traits> rhs,
1155{
return !( lhs == rhs ); }
1159template<
class CharT,
class Traits>
1161 basic_string_view<CharT, Traits> lhs,
1163{
return lhs.compare( rhs ) < 0; }
1165template<
class CharT,
class Traits>
1169{
return rhs.compare( lhs ) > 0; }
1171template<
class CharT,
class Traits>
1173 basic_string_view<CharT, Traits> lhs,
1175{
return lhs.compare( rhs ) < 0; }
1177template<
class CharT,
class Traits>
1179 std::basic_string<CharT, Traits> rhs,
1181{
return rhs.compare( lhs ) > 0; }
1185template<
class CharT,
class Traits>
1187 basic_string_view<CharT, Traits> lhs,
1189{
return lhs.compare( rhs ) <= 0; }
1191template<
class CharT,
class Traits>
1195{
return rhs.compare( lhs ) >= 0; }
1197template<
class CharT,
class Traits>
1199 basic_string_view<CharT, Traits> lhs,
1201{
return lhs.compare( rhs ) <= 0; }
1203template<
class CharT,
class Traits>
1205 std::basic_string<CharT, Traits> rhs,
1207{
return rhs.compare( lhs ) >= 0; }
1211template<
class CharT,
class Traits>
1213 basic_string_view<CharT, Traits> lhs,
1215{
return lhs.compare( rhs ) > 0; }
1217template<
class CharT,
class Traits>
1221{
return rhs.compare( lhs ) < 0; }
1223template<
class CharT,
class Traits>
1225 basic_string_view<CharT, Traits> lhs,
1227{
return lhs.compare( rhs ) > 0; }
1229template<
class CharT,
class Traits>
1231 std::basic_string<CharT, Traits> rhs,
1233{
return rhs.compare( lhs ) < 0; }
1237template<
class CharT,
class Traits>
1239 basic_string_view<CharT, Traits> lhs,
1241{
return lhs.compare( rhs ) >= 0; }
1243template<
class CharT,
class Traits>
1247{
return rhs.compare( lhs ) <= 0; }
1249template<
class CharT,
class Traits>
1251 basic_string_view<CharT, Traits> lhs,
1253{
return lhs.compare( rhs ) >= 0; }
1255template<
class CharT,
class Traits>
1257 std::basic_string<CharT, Traits> rhs,
1259{
return rhs.compare( lhs ) <= 0; }
1263#define nssv_BASIC_STRING_VIEW_I(T,U) typename std::decay< basic_string_view<T,U> >::type
1265#if nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 140, 150 )
1266# define nssv_MSVC_ORDER(x) , int=x
1268# define nssv_MSVC_ORDER(x)
1273template<
class CharT,
class Traits nssv_MSVC_ORDER(1) >
1275 basic_string_view <CharT, Traits> lhs,
1277{
return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
1279template<
class CharT,
class Traits nssv_MSVC_ORDER(2) >
1281 nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
1283{
return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
1287template<
class CharT,
class Traits nssv_MSVC_ORDER(1) >
1289 basic_string_view < CharT, Traits > lhs,
1290 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs )
nssv_noexcept
1291{
return !( lhs == rhs ); }
1293template<
class CharT,
class Traits nssv_MSVC_ORDER(2) >
1295 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
1297{
return !( lhs == rhs ); }
1301template<
class CharT,
class Traits nssv_MSVC_ORDER(1) >
1303 basic_string_view < CharT, Traits > lhs,
1304 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs )
nssv_noexcept
1305{
return lhs.compare( rhs ) < 0; }
1307template<
class CharT,
class Traits nssv_MSVC_ORDER(2) >
1309 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
1311{
return lhs.compare( rhs ) < 0; }
1315template<
class CharT,
class Traits nssv_MSVC_ORDER(1) >
1317 basic_string_view < CharT, Traits > lhs,
1318 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs )
nssv_noexcept
1319{
return lhs.compare( rhs ) <= 0; }
1321template<
class CharT,
class Traits nssv_MSVC_ORDER(2) >
1323 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
1325{
return lhs.compare( rhs ) <= 0; }
1329template<
class CharT,
class Traits nssv_MSVC_ORDER(1) >
1331 basic_string_view < CharT, Traits > lhs,
1332 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs )
nssv_noexcept
1333{
return lhs.compare( rhs ) > 0; }
1335template<
class CharT,
class Traits nssv_MSVC_ORDER(2) >
1337 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
1339{
return lhs.compare( rhs ) > 0; }
1343template<
class CharT,
class Traits nssv_MSVC_ORDER(1) >
1345 basic_string_view < CharT, Traits > lhs,
1346 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs )
nssv_noexcept
1347{
return lhs.compare( rhs ) >= 0; }
1349template<
class CharT,
class Traits nssv_MSVC_ORDER(2) >
1351 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
1353{
return lhs.compare( rhs ) >= 0; }
1355#undef nssv_MSVC_ORDER
1356#undef nssv_BASIC_STRING_VIEW_I
1364template<
class Stream >
1365void write_padding( Stream & os, std::streamsize n )
1367 for ( std::streamsize i = 0; i < n; ++i )
1368 os.rdbuf()->sputc( os.fill() );
1371template<
class Stream,
class View >
1372Stream & write_to_stream( Stream & os, View
const & sv )
1374 typename Stream::sentry sentry( os );
1379 const std::streamsize length =
static_cast<std::streamsize
>( sv.length() );
1382 const bool pad = ( length < os.width() );
1383 const bool left_pad = pad && ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::right;
1386 write_padding( os, os.width() - length );
1389 os.rdbuf()->sputn( sv.begin(), length );
1391 if ( pad && !left_pad )
1392 write_padding( os, os.width() - length );
1402template<
class CharT,
class Traits >
1403std::basic_ostream<CharT, Traits> &
1405 std::basic_ostream<CharT, Traits>& os,
1406 basic_string_view <CharT, Traits> sv )
1408 return detail::write_to_stream( os, sv );
1413typedef basic_string_view<char> string_view;
1414typedef basic_string_view<wchar_t> wstring_view;
1415#if nssv_HAVE_WCHAR16_T
1416typedef basic_string_view<char16_t> u16string_view;
1417typedef basic_string_view<char32_t> u32string_view;