00001
00002
00003
00004
00005
00006
00007
00008
00009 #pragma once
00010
00011 #ifndef NONSTD_SV_LITE_H_INCLUDED
00012 #define NONSTD_SV_LITE_H_INCLUDED
00013
00014 #define string_view_lite_MAJOR 1
00015 #define string_view_lite_MINOR 1
00016 #define string_view_lite_PATCH 0
00017
00018 #define string_view_lite_VERSION nssv_STRINGIFY(string_view_lite_MAJOR) "." nssv_STRINGIFY(string_view_lite_MINOR) "." nssv_STRINGIFY(string_view_lite_PATCH)
00019
00020 #define nssv_STRINGIFY( x ) nssv_STRINGIFY_( x )
00021 #define nssv_STRINGIFY_( x ) #x
00022
00023
00024
00025 #define nssv_STRING_VIEW_DEFAULT 0
00026 #define nssv_STRING_VIEW_NONSTD 1
00027 #define nssv_STRING_VIEW_STD 2
00028
00029 #if !defined( nssv_CONFIG_SELECT_STRING_VIEW )
00030 # define nssv_CONFIG_SELECT_STRING_VIEW ( nssv_HAVE_STD_STRING_VIEW ? nssv_STRING_VIEW_STD : nssv_STRING_VIEW_NONSTD )
00031 #endif
00032
00033 #if defined( nssv_CONFIG_SELECT_STD_STRING_VIEW ) || defined( nssv_CONFIG_SELECT_NONSTD_STRING_VIEW )
00034 # error nssv_CONFIG_SELECT_STD_STRING_VIEW and nssv_CONFIG_SELECT_NONSTD_STRING_VIEW are deprecated and removed, please use nssv_CONFIG_SELECT_STRING_VIEW=nssv_STRING_VIEW_...
00035 #endif
00036
00037 #ifndef nssv_CONFIG_STD_SV_OPERATOR
00038 # define nssv_CONFIG_STD_SV_OPERATOR 0
00039 #endif
00040
00041 #ifndef nssv_CONFIG_USR_SV_OPERATOR
00042 # define nssv_CONFIG_USR_SV_OPERATOR 1
00043 #endif
00044
00045 #ifdef nssv_CONFIG_CONVERSION_STD_STRING
00046 # define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS nssv_CONFIG_CONVERSION_STD_STRING
00047 # define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS nssv_CONFIG_CONVERSION_STD_STRING
00048 #endif
00049
00050 #ifndef nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
00051 # define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS 1
00052 #endif
00053
00054 #ifndef nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
00055 # define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS 1
00056 #endif
00057
00058
00059
00060
00061 #ifndef nssv_CPLUSPLUS
00062 # if defined(_MSVC_LANG ) && !defined(__clang__)
00063 # define nssv_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
00064 # else
00065 # define nssv_CPLUSPLUS __cplusplus
00066 # endif
00067 #endif
00068
00069 #define nssv_CPP98_OR_GREATER ( nssv_CPLUSPLUS >= 199711L )
00070 #define nssv_CPP11_OR_GREATER ( nssv_CPLUSPLUS >= 201103L )
00071 #define nssv_CPP11_OR_GREATER_ ( nssv_CPLUSPLUS >= 201103L )
00072 #define nssv_CPP14_OR_GREATER ( nssv_CPLUSPLUS >= 201402L )
00073 #define nssv_CPP17_OR_GREATER ( nssv_CPLUSPLUS >= 201703L )
00074 #define nssv_CPP20_OR_GREATER ( nssv_CPLUSPLUS >= 202000L )
00075
00076
00077
00078 #if nssv_CPP17_OR_GREATER && defined(__has_include )
00079 # if __has_include( <string_view> )
00080 # define nssv_HAVE_STD_STRING_VIEW 1
00081 # else
00082 # define nssv_HAVE_STD_STRING_VIEW 0
00083 # endif
00084 #else
00085 # define nssv_HAVE_STD_STRING_VIEW 0
00086 #endif
00087
00088 #define nssv_USES_STD_STRING_VIEW ( (nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_STD) || ((nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_DEFAULT) && nssv_HAVE_STD_STRING_VIEW) )
00089
00090 #define nssv_HAVE_STARTS_WITH ( nssv_CPP20_OR_GREATER || !nssv_USES_STD_STRING_VIEW )
00091 #define nssv_HAVE_ENDS_WITH nssv_HAVE_STARTS_WITH
00092
00093
00094
00095
00096
00097 #if nssv_USES_STD_STRING_VIEW
00098
00099 #include <string_view>
00100
00101
00102
00103 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
00104
00105 namespace nonstd {
00106
00107 template< class CharT, class Traits, class Allocator = std::allocator<CharT> >
00108 std::basic_string<CharT, Traits, Allocator>
00109 to_string( std::basic_string_view<CharT, Traits> v, Allocator const & a = Allocator() )
00110 {
00111 return std::basic_string<CharT,Traits, Allocator>( v.begin(), v.end(), a );
00112 }
00113
00114 template< class CharT, class Traits, class Allocator >
00115 std::basic_string_view<CharT, Traits>
00116 to_string_view( std::basic_string<CharT, Traits, Allocator> const & s )
00117 {
00118 return std::basic_string_view<CharT, Traits>( s.data(), s.size() );
00119 }
00120
00121
00122
00123 #if nssv_CONFIG_STD_SV_OPERATOR
00124
00125 using namespace std::literals::string_view_literals;
00126
00127 #endif
00128
00129 #if nssv_CONFIG_USR_SV_OPERATOR
00130
00131 inline namespace literals {
00132 inline namespace string_view_literals {
00133
00134
00135 constexpr std::string_view operator "" _sv( const char* str, size_t len ) noexcept
00136 {
00137 return std::string_view{ str, len };
00138 }
00139
00140 constexpr std::u16string_view operator "" _sv( const char16_t* str, size_t len ) noexcept
00141 {
00142 return std::u16string_view{ str, len };
00143 }
00144
00145 constexpr std::u32string_view operator "" _sv( const char32_t* str, size_t len ) noexcept
00146 {
00147 return std::u32string_view{ str, len };
00148 }
00149
00150 constexpr std::wstring_view operator "" _sv( const wchar_t* str, size_t len ) noexcept
00151 {
00152 return std::wstring_view{ str, len };
00153 }
00154
00155 }}
00156
00157 #endif // nssv_CONFIG_USR_SV_OPERATOR
00158
00159 }
00160
00161 #endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
00162
00163 namespace nonstd {
00164
00165 using std::string_view;
00166 using std::wstring_view;
00167 using std::u16string_view;
00168 using std::u32string_view;
00169 using std::basic_string_view;
00170
00171
00172
00173 using std::operator==;
00174 using std::operator!=;
00175 using std::operator<;
00176 using std::operator<=;
00177 using std::operator>;
00178 using std::operator>=;
00179
00180 using std::operator<<;
00181
00182 }
00183
00184 #else // nssv_HAVE_STD_STRING_VIEW
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 #if defined(_MSC_VER ) && !defined(__clang__)
00204 # define nssv_COMPILER_MSVC_VER (_MSC_VER )
00205 # define nssv_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
00206 #else
00207 # define nssv_COMPILER_MSVC_VER 0
00208 # define nssv_COMPILER_MSVC_VERSION 0
00209 #endif
00210
00211 #define nssv_COMPILER_VERSION( major, minor, patch ) (10 * ( 10 * major + minor) + patch)
00212
00213 #if defined(__clang__)
00214 # define nssv_COMPILER_CLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
00215 #else
00216 # define nssv_COMPILER_CLANG_VERSION 0
00217 #endif
00218
00219 #if defined(__GNUC__) && !defined(__clang__)
00220 # define nssv_COMPILER_GNUC_VERSION nssv_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
00221 #else
00222 # define nssv_COMPILER_GNUC_VERSION 0
00223 #endif
00224
00225
00226 #define nssv_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
00227
00228
00229
00230 #ifdef _HAS_CPP0X
00231 # define nssv_HAS_CPP0X _HAS_CPP0X
00232 #else
00233 # define nssv_HAS_CPP0X 0
00234 #endif
00235
00236
00237
00238 #if nssv_COMPILER_MSVC_VER >= 1900
00239 # undef nssv_CPP11_OR_GREATER
00240 # define nssv_CPP11_OR_GREATER 1
00241 #endif
00242
00243 #define nssv_CPP11_90 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1500)
00244 #define nssv_CPP11_100 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1600)
00245 #define nssv_CPP11_110 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1700)
00246 #define nssv_CPP11_120 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1800)
00247 #define nssv_CPP11_140 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1900)
00248 #define nssv_CPP11_141 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1910)
00249
00250 #define nssv_CPP14_000 (nssv_CPP14_OR_GREATER)
00251 #define nssv_CPP17_000 (nssv_CPP17_OR_GREATER)
00252
00253
00254
00255 #define nssv_HAVE_CONSTEXPR_11 nssv_CPP11_140
00256 #define nssv_HAVE_EXPLICIT_CONVERSION nssv_CPP11_140
00257 #define nssv_HAVE_INLINE_NAMESPACE nssv_CPP11_140
00258 #define nssv_HAVE_NOEXCEPT nssv_CPP11_140
00259 #define nssv_HAVE_NULLPTR nssv_CPP11_100
00260 #define nssv_HAVE_REF_QUALIFIER nssv_CPP11_140
00261 #define nssv_HAVE_UNICODE_LITERALS nssv_CPP11_140
00262 #define nssv_HAVE_USER_DEFINED_LITERALS nssv_CPP11_140
00263 #define nssv_HAVE_WCHAR16_T nssv_CPP11_100
00264 #define nssv_HAVE_WCHAR32_T nssv_CPP11_100
00265
00266 #if ! ( ( nssv_CPP11 && nssv_COMPILER_CLANG_VERSION ) || nssv_BETWEEN( nssv_COMPILER_CLANG_VERSION, 300, 400 ) )
00267 # define nssv_HAVE_STD_DEFINED_LITERALS nssv_CPP11_140
00268 #endif
00269
00270
00271
00272 #define nssv_HAVE_CONSTEXPR_14 nssv_CPP14_000
00273
00274
00275
00276 #define nssv_HAVE_NODISCARD nssv_CPP17_000
00277
00278
00279
00280 #define nssv_HAVE_STD_HASH nssv_CPP11_120
00281
00282
00283
00284 #if nssv_HAVE_CONSTEXPR_11
00285 # define nssv_constexpr constexpr
00286 #else
00287 # define nssv_constexpr
00288 #endif
00289
00290 #if nssv_HAVE_CONSTEXPR_14
00291 # define nssv_constexpr14 constexpr
00292 #else
00293 # define nssv_constexpr14
00294 #endif
00295
00296 #if nssv_HAVE_EXPLICIT_CONVERSION
00297 # define nssv_explicit explicit
00298 #else
00299 # define nssv_explicit
00300 #endif
00301
00302 #if nssv_HAVE_INLINE_NAMESPACE
00303 # define nssv_inline_ns inline
00304 #else
00305 # define nssv_inline_ns
00306 #endif
00307
00308 #if nssv_HAVE_NOEXCEPT
00309 # define nssv_noexcept noexcept
00310 #else
00311 # define nssv_noexcept
00312 #endif
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 #if nssv_HAVE_NULLPTR
00323 # define nssv_nullptr nullptr
00324 #else
00325 # define nssv_nullptr NULL
00326 #endif
00327
00328 #if nssv_HAVE_NODISCARD
00329 # define nssv_nodiscard [[nodiscard]]
00330 #else
00331 # define nssv_nodiscard
00332 #endif
00333
00334
00335
00336 #include <algorithm>
00337 #include <cassert>
00338 #include <iterator>
00339 #include <limits>
00340 #include <ostream>
00341 #include <stdexcept>
00342 #include <string>
00343
00344 #if nssv_CPP11_OR_GREATER
00345 # include <type_traits>
00346 #endif
00347
00348
00349
00350 #if defined(__clang__)
00351 # pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
00352 # pragma clang diagnostic push
00353 # pragma clang diagnostic ignored "-Wuser-defined-literals"
00354 #elif defined(__GNUC__)
00355 # pragma GCC diagnostic push
00356 # pragma GCC diagnostic ignored "-Wliteral-suffix"
00357 #endif // __clang__
00358
00359 #if nssv_COMPILER_MSVC_VERSION >= 140
00360 # define nssv_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]]
00361 # define nssv_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress: code) )
00362 # define nssv_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable: codes))
00363 #else
00364 # define nssv_SUPPRESS_MSGSL_WARNING(expr)
00365 # define nssv_SUPPRESS_MSVC_WARNING(code, descr)
00366 # define nssv_DISABLE_MSVC_WARNINGS(codes)
00367 #endif
00368
00369 #if defined(__clang__)
00370 # define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
00371 #elif defined(__GNUC__)
00372 # define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
00373 #elif nssv_COMPILER_MSVC_VERSION >= 140
00374 # define nssv_RESTORE_WARNINGS() __pragma(warning(pop ))
00375 #else
00376 # define nssv_RESTORE_WARNINGS()
00377 #endif
00378
00379
00380
00381
00382
00383
00384
00385
00386 nssv_DISABLE_MSVC_WARNINGS( 4455 26481 26472 )
00387
00388
00389
00390 namespace nonstd { namespace sv_lite {
00391
00392 template
00393 <
00394 class CharT,
00395 class Traits = std::char_traits<CharT>
00396 >
00397 class basic_string_view;
00398
00399
00400
00401
00402
00403 template
00404 <
00405 class CharT,
00406 class Traits
00407 >
00408 class basic_string_view
00409 {
00410 public:
00411
00412
00413 typedef Traits traits_type;
00414 typedef CharT value_type;
00415
00416 typedef CharT * pointer;
00417 typedef CharT const * const_pointer;
00418 typedef CharT & reference;
00419 typedef CharT const & const_reference;
00420
00421 typedef const_pointer iterator;
00422 typedef const_pointer const_iterator;
00423 typedef std::reverse_iterator< const_iterator > reverse_iterator;
00424 typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
00425
00426 typedef std::size_t size_type;
00427 typedef std::ptrdiff_t difference_type;
00428
00429
00430
00431 nssv_constexpr basic_string_view() nssv_noexcept
00432 : data_( nssv_nullptr )
00433 , size_( 0 )
00434 {}
00435
00436 #if nssv_CPP11_OR_GREATER
00437 nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept = default;
00438 #else
00439 nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept
00440 : data_( other.data_)
00441 , size_( other.size_)
00442 {}
00443 #endif
00444
00445 nssv_constexpr basic_string_view( CharT const * s, size_type count )
00446 : data_( s )
00447 , size_( count )
00448 {}
00449
00450 nssv_constexpr basic_string_view( CharT const * s)
00451 : data_( s )
00452 , size_( Traits::length(s) )
00453 {}
00454
00455
00456
00457 #if nssv_CPP11_OR_GREATER
00458 nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept = default;
00459 #else
00460 nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept
00461 {
00462 data_ = other.data_;
00463 size_ = other.size_;
00464 return *this;
00465 }
00466 #endif
00467
00468
00469
00470 nssv_constexpr const_iterator begin() const nssv_noexcept { return data_; }
00471 nssv_constexpr const_iterator end() const nssv_noexcept { return data_ + size_; }
00472
00473 nssv_constexpr const_iterator cbegin() const nssv_noexcept { return begin(); }
00474 nssv_constexpr const_iterator cend() const nssv_noexcept { return end(); }
00475
00476 nssv_constexpr const_reverse_iterator rbegin() const nssv_noexcept { return const_reverse_iterator( end() ); }
00477 nssv_constexpr const_reverse_iterator rend() const nssv_noexcept { return const_reverse_iterator( begin() ); }
00478
00479 nssv_constexpr const_reverse_iterator crbegin() const nssv_noexcept { return rbegin(); }
00480 nssv_constexpr const_reverse_iterator crend() const nssv_noexcept { return rend(); }
00481
00482
00483
00484 nssv_constexpr size_type size() const nssv_noexcept { return size_; }
00485 nssv_constexpr size_type length() const nssv_noexcept { return size_; }
00486 nssv_constexpr size_type max_size() const nssv_noexcept { return (std::numeric_limits< size_type >::max)(); }
00487
00488
00489 nssv_nodiscard nssv_constexpr bool empty() const nssv_noexcept
00490 {
00491 return 0 == size_;
00492 }
00493
00494
00495
00496 nssv_constexpr const_reference operator[]( size_type pos ) const
00497 {
00498 return data_at( pos );
00499 }
00500
00501 nssv_constexpr14 const_reference at( size_type pos ) const
00502 {
00503 if ( pos < size() )
00504 {
00505 return data_at( pos );
00506 }
00507
00508 throw std::out_of_range("nonst::string_view::at()");
00509 }
00510
00511 nssv_constexpr const_reference front() const { return data_at( 0 ); }
00512 nssv_constexpr const_reference back() const { return data_at( size() - 1 ); }
00513
00514 nssv_constexpr const_pointer data() const nssv_noexcept { return data_; }
00515
00516
00517
00518 nssv_constexpr14 void remove_prefix( size_type n )
00519 {
00520 assert( n <= size() );
00521 data_ += n;
00522 size_ -= n;
00523 }
00524
00525 nssv_constexpr14 void remove_suffix( size_type n )
00526 {
00527 assert( n <= size() );
00528 size_ -= n;
00529 }
00530
00531 nssv_constexpr14 void swap( basic_string_view & other ) nssv_noexcept
00532 {
00533 using std::swap;
00534 swap( data_, other.data_ );
00535 swap( size_, other.size_ );
00536 }
00537
00538
00539
00540 size_type copy( CharT * dest, size_type n, size_type pos = 0 ) const
00541 {
00542 if ( pos > size() )
00543 throw std::out_of_range("nonst::string_view::copy()");
00544
00545 const size_type rlen = (std::min)( n, size() - pos );
00546
00547 (void) Traits::copy( dest, data() + pos, rlen );
00548
00549 return rlen;
00550 }
00551
00552 nssv_constexpr14 basic_string_view substr( size_type pos = 0, size_type n = npos ) const
00553 {
00554 if ( pos > size() )
00555 throw std::out_of_range("nonst::string_view::substr()");
00556
00557 return basic_string_view( data() + pos, (std::min)( n, size() - pos ) );
00558 }
00559
00560
00561
00562 nssv_constexpr14 int compare( basic_string_view other ) const nssv_noexcept
00563 {
00564 if ( const int result = Traits::compare( data(), other.data(), (std::min)( size(), other.size() ) ) )
00565 return result;
00566
00567 return size() == other.size() ? 0 : size() < other.size() ? -1 : 1;
00568 }
00569
00570 nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other ) const
00571 {
00572 return substr( pos1, n1 ).compare( other );
00573 }
00574
00575 nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other, size_type pos2, size_type n2 ) const
00576 {
00577 return substr( pos1, n1 ).compare( other.substr( pos2, n2 ) );
00578 }
00579
00580 nssv_constexpr int compare( CharT const * s ) const
00581 {
00582 return compare( basic_string_view( s ) );
00583 }
00584
00585 nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s ) const
00586 {
00587 return substr( pos1, n1 ).compare( basic_string_view( s ) );
00588 }
00589
00590 nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s, size_type n2 ) const
00591 {
00592 return substr( pos1, n1 ).compare( basic_string_view( s, n2 ) );
00593 }
00594
00595
00596
00597
00598
00599 nssv_constexpr bool starts_with( basic_string_view v ) const nssv_noexcept
00600 {
00601 return size() >= v.size() && compare( 0, v.size(), v ) == 0;
00602 }
00603
00604 nssv_constexpr bool starts_with( CharT c ) const nssv_noexcept
00605 {
00606 return starts_with( basic_string_view( &c, 1 ) );
00607 }
00608
00609 nssv_constexpr bool starts_with( CharT const * s ) const
00610 {
00611 return starts_with( basic_string_view( s ) );
00612 }
00613
00614
00615
00616 nssv_constexpr bool ends_with( basic_string_view v ) const nssv_noexcept
00617 {
00618 return size() >= v.size() && compare( size() - v.size(), npos, v ) == 0;
00619 }
00620
00621 nssv_constexpr bool ends_with( CharT c ) const nssv_noexcept
00622 {
00623 return ends_with( basic_string_view( &c, 1 ) );
00624 }
00625
00626 nssv_constexpr bool ends_with( CharT const * s ) const
00627 {
00628 return ends_with( basic_string_view( s ) );
00629 }
00630
00631
00632
00633 nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept
00634 {
00635 return assert( v.size() == 0 || v.data() != nssv_nullptr )
00636 , pos >= size()
00637 ? npos
00638 : to_pos( std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
00639 }
00640
00641 nssv_constexpr14 size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept
00642 {
00643 return find( basic_string_view( &c, 1 ), pos );
00644 }
00645
00646 nssv_constexpr14 size_type find( CharT const * s, size_type pos, size_type n ) const
00647 {
00648 return find( basic_string_view( s, n ), pos );
00649 }
00650
00651 nssv_constexpr14 size_type find( CharT const * s, size_type pos = 0 ) const
00652 {
00653 return find( basic_string_view( s ), pos );
00654 }
00655
00656
00657
00658 nssv_constexpr14 size_type rfind( basic_string_view v, size_type pos = npos ) const nssv_noexcept
00659 {
00660 if ( size() < v.size() )
00661 return npos;
00662
00663 if ( v.empty() )
00664 return (std::min)( size(), pos );
00665
00666 const_iterator last = cbegin() + (std::min)( size() - v.size(), pos ) + v.size();
00667 const_iterator result = std::find_end( cbegin(), last, v.cbegin(), v.cend(), Traits::eq );
00668
00669 return result != last ? size_type( result - cbegin() ) : npos;
00670 }
00671
00672 nssv_constexpr14 size_type rfind( CharT c, size_type pos = npos ) const nssv_noexcept
00673 {
00674 return rfind( basic_string_view( &c, 1 ), pos );
00675 }
00676
00677 nssv_constexpr14 size_type rfind( CharT const * s, size_type pos, size_type n ) const
00678 {
00679 return rfind( basic_string_view( s, n ), pos );
00680 }
00681
00682 nssv_constexpr14 size_type rfind( CharT const * s, size_type pos = npos ) const
00683 {
00684 return rfind( basic_string_view( s ), pos );
00685 }
00686
00687
00688
00689 nssv_constexpr size_type find_first_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept
00690 {
00691 return pos >= size()
00692 ? npos
00693 : to_pos( std::find_first_of( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
00694 }
00695
00696 nssv_constexpr size_type find_first_of( CharT c, size_type pos = 0 ) const nssv_noexcept
00697 {
00698 return find_first_of( basic_string_view( &c, 1 ), pos );
00699 }
00700
00701 nssv_constexpr size_type find_first_of( CharT const * s, size_type pos, size_type n ) const
00702 {
00703 return find_first_of( basic_string_view( s, n ), pos );
00704 }
00705
00706 nssv_constexpr size_type find_first_of( CharT const * s, size_type pos = 0 ) const
00707 {
00708 return find_first_of( basic_string_view( s ), pos );
00709 }
00710
00711
00712
00713 nssv_constexpr size_type find_last_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept
00714 {
00715 return empty()
00716 ? npos
00717 : pos >= size()
00718 ? find_last_of( v, size() - 1 )
00719 : to_pos( std::find_first_of( const_reverse_iterator( cbegin() + pos + 1 ), crend(), v.cbegin(), v.cend(), Traits::eq ) );
00720 }
00721
00722 nssv_constexpr size_type find_last_of( CharT c, size_type pos = npos ) const nssv_noexcept
00723 {
00724 return find_last_of( basic_string_view( &c, 1 ), pos );
00725 }
00726
00727 nssv_constexpr size_type find_last_of( CharT const * s, size_type pos, size_type count ) const
00728 {
00729 return find_last_of( basic_string_view( s, count ), pos );
00730 }
00731
00732 nssv_constexpr size_type find_last_of( CharT const * s, size_type pos = npos ) const
00733 {
00734 return find_last_of( basic_string_view( s ), pos );
00735 }
00736
00737
00738
00739 nssv_constexpr size_type find_first_not_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept
00740 {
00741 return pos >= size()
00742 ? npos
00743 : to_pos( std::find_if( cbegin() + pos, cend(), not_in_view( v ) ) );
00744 }
00745
00746 nssv_constexpr size_type find_first_not_of( CharT c, size_type pos = 0 ) const nssv_noexcept
00747 {
00748 return find_first_not_of( basic_string_view( &c, 1 ), pos );
00749 }
00750
00751 nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos, size_type count ) const
00752 {
00753 return find_first_not_of( basic_string_view( s, count ), pos );
00754 }
00755
00756 nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos = 0 ) const
00757 {
00758 return find_first_not_of( basic_string_view( s ), pos );
00759 }
00760
00761
00762
00763 nssv_constexpr size_type find_last_not_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept
00764 {
00765 return empty()
00766 ? npos
00767 : pos >= size()
00768 ? find_last_not_of( v, size() - 1 )
00769 : to_pos( std::find_if( const_reverse_iterator( cbegin() + pos + 1 ), crend(), not_in_view( v ) ) );
00770 }
00771
00772 nssv_constexpr size_type find_last_not_of( CharT c, size_type pos = npos ) const nssv_noexcept
00773 {
00774 return find_last_not_of( basic_string_view( &c, 1 ), pos );
00775 }
00776
00777 nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos, size_type count ) const
00778 {
00779 return find_last_not_of( basic_string_view( s, count ), pos );
00780 }
00781
00782 nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos = npos ) const
00783 {
00784 return find_last_not_of( basic_string_view( s ), pos );
00785 }
00786
00787
00788
00789 #if nssv_CPP17_OR_GREATER
00790 static nssv_constexpr size_type npos = size_type(-1);
00791 #elif nssv_CPP11_OR_GREATER
00792 enum : size_type { npos = size_type(-1) };
00793 #else
00794 enum { npos = size_type(-1) };
00795 #endif
00796
00797 private:
00798 struct not_in_view
00799 {
00800 const basic_string_view v;
00801
00802 nssv_constexpr not_in_view( basic_string_view v ) : v( v ) {}
00803
00804 nssv_constexpr bool operator()( CharT c ) const
00805 {
00806 return npos == v.find_first_of( c );
00807 }
00808 };
00809
00810 nssv_constexpr size_type to_pos( const_iterator it ) const
00811 {
00812 return it == cend() ? npos : size_type( it - cbegin() );
00813 }
00814
00815 nssv_constexpr size_type to_pos( const_reverse_iterator it ) const
00816 {
00817 return it == crend() ? npos : size_type( crend() - it - 1 );
00818 }
00819
00820 nssv_constexpr const_reference data_at( size_type pos ) const
00821 {
00822 #if nssv_BETWEEN( nssv_COMPILER_GNUC_VERSION, 1, 500 )
00823 return data_[pos];
00824 #else
00825 return assert( pos < size() ), data_[pos];
00826 #endif
00827 }
00828
00829 private:
00830 const_pointer data_;
00831 size_type size_;
00832
00833 public:
00834 #if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
00835
00836 template< class Allocator >
00837 basic_string_view( std::basic_string<CharT, Traits, Allocator> const & s ) nssv_noexcept
00838 : data_( s.data() )
00839 , size_( s.size() )
00840 {}
00841
00842 #if nssv_HAVE_EXPLICIT_CONVERSION
00843
00844 template< class Allocator >
00845 explicit operator std::basic_string<CharT, Traits, Allocator>() const
00846 {
00847 return to_string( Allocator() );
00848 }
00849
00850 #endif // nssv_HAVE_EXPLICIT_CONVERSION
00851
00852 #if nssv_CPP11_OR_GREATER
00853
00854 template< class Allocator = std::allocator<CharT> >
00855 std::basic_string<CharT, Traits, Allocator>
00856 to_string( Allocator const & a = Allocator() ) const
00857 {
00858 return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
00859 }
00860
00861 #else
00862
00863 std::basic_string<CharT, Traits>
00864 to_string() const
00865 {
00866 return std::basic_string<CharT, Traits>( begin(), end() );
00867 }
00868
00869 template< class Allocator >
00870 std::basic_string<CharT, Traits, Allocator>
00871 to_string( Allocator const & a ) const
00872 {
00873 return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
00874 }
00875
00876 #endif // nssv_CPP11_OR_GREATER
00877
00878 #endif // nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
00879 };
00880
00881
00882
00883
00884
00885
00886
00887
00888 template< class CharT, class Traits >
00889 nssv_constexpr bool operator== (
00890 basic_string_view <CharT, Traits> lhs,
00891 basic_string_view <CharT, Traits> rhs ) nssv_noexcept
00892 { return lhs.compare( rhs ) == 0 ; }
00893
00894 template< class CharT, class Traits >
00895 nssv_constexpr bool operator!= (
00896 basic_string_view <CharT, Traits> lhs,
00897 basic_string_view <CharT, Traits> rhs ) nssv_noexcept
00898 { return lhs.compare( rhs ) != 0 ; }
00899
00900 template< class CharT, class Traits >
00901 nssv_constexpr bool operator< (
00902 basic_string_view <CharT, Traits> lhs,
00903 basic_string_view <CharT, Traits> rhs ) nssv_noexcept
00904 { return lhs.compare( rhs ) < 0 ; }
00905
00906 template< class CharT, class Traits >
00907 nssv_constexpr bool operator<= (
00908 basic_string_view <CharT, Traits> lhs,
00909 basic_string_view <CharT, Traits> rhs ) nssv_noexcept
00910 { return lhs.compare( rhs ) <= 0 ; }
00911
00912 template< class CharT, class Traits >
00913 nssv_constexpr bool operator> (
00914 basic_string_view <CharT, Traits> lhs,
00915 basic_string_view <CharT, Traits> rhs ) nssv_noexcept
00916 { return lhs.compare( rhs ) > 0 ; }
00917
00918 template< class CharT, class Traits >
00919 nssv_constexpr bool operator>= (
00920 basic_string_view <CharT, Traits> lhs,
00921 basic_string_view <CharT, Traits> rhs ) nssv_noexcept
00922 { return lhs.compare( rhs ) >= 0 ; }
00923
00924
00925
00926
00927
00928
00929 #if nssv_CPP11_OR_GREATER && ! nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 100, 141 )
00930
00931 #define nssv_BASIC_STRING_VIEW_I(T,U) typename std::decay< basic_string_view<T,U> >::type
00932
00933 #if nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 140, 150 )
00934 # define nssv_MSVC_ORDER(x) , int=x
00935 #else
00936 # define nssv_MSVC_ORDER(x)
00937 #endif
00938
00939
00940
00941 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
00942 nssv_constexpr bool operator==(
00943 basic_string_view <CharT, Traits> lhs,
00944 nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs ) nssv_noexcept
00945 { return lhs.compare( rhs ) == 0; }
00946
00947 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
00948 nssv_constexpr bool operator==(
00949 nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
00950 basic_string_view <CharT, Traits> rhs ) nssv_noexcept
00951 { return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
00952
00953
00954
00955 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
00956 nssv_constexpr bool operator!= (
00957 basic_string_view < CharT, Traits > lhs,
00958 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
00959 { return lhs.size() != rhs.size() || lhs.compare( rhs ) != 0 ; }
00960
00961 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
00962 nssv_constexpr bool operator!= (
00963 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
00964 basic_string_view < CharT, Traits > rhs ) nssv_noexcept
00965 { return lhs.compare( rhs ) != 0 ; }
00966
00967
00968
00969 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
00970 nssv_constexpr bool operator< (
00971 basic_string_view < CharT, Traits > lhs,
00972 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
00973 { return lhs.compare( rhs ) < 0 ; }
00974
00975 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
00976 nssv_constexpr bool operator< (
00977 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
00978 basic_string_view < CharT, Traits > rhs ) nssv_noexcept
00979 { return lhs.compare( rhs ) < 0 ; }
00980
00981
00982
00983 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
00984 nssv_constexpr bool operator<= (
00985 basic_string_view < CharT, Traits > lhs,
00986 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
00987 { return lhs.compare( rhs ) <= 0 ; }
00988
00989 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
00990 nssv_constexpr bool operator<= (
00991 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
00992 basic_string_view < CharT, Traits > rhs ) nssv_noexcept
00993 { return lhs.compare( rhs ) <= 0 ; }
00994
00995
00996
00997 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
00998 nssv_constexpr bool operator> (
00999 basic_string_view < CharT, Traits > lhs,
01000 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
01001 { return lhs.compare( rhs ) > 0 ; }
01002
01003 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
01004 nssv_constexpr bool operator> (
01005 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
01006 basic_string_view < CharT, Traits > rhs ) nssv_noexcept
01007 { return lhs.compare( rhs ) > 0 ; }
01008
01009
01010
01011 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
01012 nssv_constexpr bool operator>= (
01013 basic_string_view < CharT, Traits > lhs,
01014 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
01015 { return lhs.compare( rhs ) >= 0 ; }
01016
01017 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
01018 nssv_constexpr bool operator>= (
01019 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
01020 basic_string_view < CharT, Traits > rhs ) nssv_noexcept
01021 { return lhs.compare( rhs ) >= 0 ; }
01022
01023 #undef nssv_MSVC_ORDER
01024 #undef nssv_BASIC_STRING_VIEW_I
01025
01026 #endif // nssv_CPP11_OR_GREATER
01027
01028
01029
01030 namespace detail {
01031
01032 template< class Stream >
01033 void write_padding( Stream & os, std::streamsize n )
01034 {
01035 for ( std::streamsize i = 0; i < n; ++i )
01036 os.rdbuf()->sputc( os.fill() );
01037 }
01038
01039 template< class Stream, class View >
01040 Stream & write_to_stream( Stream & os, View const & sv )
01041 {
01042 typename Stream::sentry sentry( os );
01043
01044 if ( !os )
01045 return os;
01046
01047 const std::streamsize length = static_cast<std::streamsize>( sv.length() );
01048
01049
01050 const bool pad = ( length < os.width() );
01051 const bool left_pad = pad && ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::right;
01052
01053 if ( left_pad )
01054 write_padding( os, os.width() - length );
01055
01056
01057 os.rdbuf()->sputn( sv.begin(), length );
01058
01059 if ( pad && !left_pad )
01060 write_padding( os, os.width() - length );
01061
01062
01063 os.width( 0 );
01064
01065 return os;
01066 }
01067
01068 }
01069
01070 template< class CharT, class Traits >
01071 std::basic_ostream<CharT, Traits> &
01072 operator<<(
01073 std::basic_ostream<CharT, Traits>& os,
01074 basic_string_view <CharT, Traits> sv )
01075 {
01076 return detail::write_to_stream( os, sv );
01077 }
01078
01079
01080
01081 typedef basic_string_view<char> string_view;
01082 typedef basic_string_view<wchar_t> wstring_view;
01083 #if nssv_HAVE_WCHAR16_T
01084 typedef basic_string_view<char16_t> u16string_view;
01085 typedef basic_string_view<char32_t> u32string_view;
01086 #endif
01087
01088 }}
01089
01090
01091
01092
01093
01094 #if nssv_HAVE_USER_DEFINED_LITERALS
01095
01096 namespace nonstd {
01097 nssv_inline_ns namespace literals {
01098 nssv_inline_ns namespace string_view_literals {
01099
01100 #if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
01101
01102 nssv_constexpr nonstd::sv_lite::string_view operator "" sv( const char* str, size_t len ) nssv_noexcept
01103 {
01104 return nonstd::sv_lite::string_view{ str, len };
01105 }
01106
01107 nssv_constexpr nonstd::sv_lite::u16string_view operator "" sv( const char16_t* str, size_t len ) nssv_noexcept
01108 {
01109 return nonstd::sv_lite::u16string_view{ str, len };
01110 }
01111
01112 nssv_constexpr nonstd::sv_lite::u32string_view operator "" sv( const char32_t* str, size_t len ) nssv_noexcept
01113 {
01114 return nonstd::sv_lite::u32string_view{ str, len };
01115 }
01116
01117 nssv_constexpr nonstd::sv_lite::wstring_view operator "" sv( const wchar_t* str, size_t len ) nssv_noexcept
01118 {
01119 return nonstd::sv_lite::wstring_view{ str, len };
01120 }
01121
01122 #endif // nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
01123
01124 #if nssv_CONFIG_USR_SV_OPERATOR
01125
01126 nssv_constexpr nonstd::sv_lite::string_view operator "" _sv( const char* str, size_t len ) nssv_noexcept
01127 {
01128 return nonstd::sv_lite::string_view{ str, len };
01129 }
01130
01131 nssv_constexpr nonstd::sv_lite::u16string_view operator "" _sv( const char16_t* str, size_t len ) nssv_noexcept
01132 {
01133 return nonstd::sv_lite::u16string_view{ str, len };
01134 }
01135
01136 nssv_constexpr nonstd::sv_lite::u32string_view operator "" _sv( const char32_t* str, size_t len ) nssv_noexcept
01137 {
01138 return nonstd::sv_lite::u32string_view{ str, len };
01139 }
01140
01141 nssv_constexpr nonstd::sv_lite::wstring_view operator "" _sv( const wchar_t* str, size_t len ) nssv_noexcept
01142 {
01143 return nonstd::sv_lite::wstring_view{ str, len };
01144 }
01145
01146 #endif // nssv_CONFIG_USR_SV_OPERATOR
01147
01148 }}}
01149
01150 #endif
01151
01152
01153
01154
01155
01156 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
01157
01158 namespace nonstd {
01159 namespace sv_lite {
01160
01161
01162
01163 #if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140
01164
01165 template< class CharT, class Traits, class Allocator = std::allocator<CharT> >
01166 std::basic_string<CharT, Traits, Allocator>
01167 to_string( basic_string_view<CharT, Traits> v, Allocator const & a = Allocator() )
01168 {
01169 return std::basic_string<CharT,Traits, Allocator>( v.begin(), v.end(), a );
01170 }
01171
01172 #else
01173
01174 template< class CharT, class Traits >
01175 std::basic_string<CharT, Traits>
01176 to_string( basic_string_view<CharT, Traits> v )
01177 {
01178 return std::basic_string<CharT, Traits>( v.begin(), v.end() );
01179 }
01180
01181 template< class CharT, class Traits, class Allocator >
01182 std::basic_string<CharT, Traits, Allocator>
01183 to_string( basic_string_view<CharT, Traits> v, Allocator const & a )
01184 {
01185 return std::basic_string<CharT, Traits, Allocator>( v.begin(), v.end(), a );
01186 }
01187
01188 #endif // nssv_CPP11_OR_GREATER
01189
01190 template< class CharT, class Traits, class Allocator >
01191 basic_string_view<CharT, Traits>
01192 to_string_view( std::basic_string<CharT, Traits, Allocator> const & s )
01193 {
01194 return basic_string_view<CharT, Traits>( s.data(), s.size() );
01195 }
01196
01197 }}
01198
01199 #endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
01200
01201
01202
01203
01204
01205 namespace nonstd {
01206
01207 using sv_lite::basic_string_view;
01208 using sv_lite::string_view;
01209 using sv_lite::wstring_view;
01210
01211 #if nssv_HAVE_WCHAR16_T
01212 using sv_lite::u16string_view;
01213 #endif
01214 #if nssv_HAVE_WCHAR32_T
01215 using sv_lite::u32string_view;
01216 #endif
01217
01218
01219
01220 using sv_lite::operator==;
01221 using sv_lite::operator!=;
01222 using sv_lite::operator<;
01223 using sv_lite::operator<=;
01224 using sv_lite::operator>;
01225 using sv_lite::operator>=;
01226
01227 using sv_lite::operator<<;
01228
01229 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
01230 using sv_lite::to_string;
01231 using sv_lite::to_string_view;
01232 #endif
01233
01234 }
01235
01236
01237
01238
01239
01240
01241 #if nssv_HAVE_STD_HASH
01242
01243 #include <functional>
01244
01245 namespace std {
01246
01247 template<>
01248 struct hash< nonstd::string_view >
01249 {
01250 public:
01251 std::size_t operator()( nonstd::string_view v ) const nssv_noexcept
01252 {
01253 return std::hash<std::string>()( std::string( v.data(), v.size() ) );
01254 }
01255 };
01256
01257 template<>
01258 struct hash< nonstd::wstring_view >
01259 {
01260 public:
01261 std::size_t operator()( nonstd::wstring_view v ) const nssv_noexcept
01262 {
01263 return std::hash<std::wstring>()( std::wstring( v.data(), v.size() ) );
01264 }
01265 };
01266
01267 template<>
01268 struct hash< nonstd::u16string_view >
01269 {
01270 public:
01271 std::size_t operator()( nonstd::u16string_view v ) const nssv_noexcept
01272 {
01273 return std::hash<std::u16string>()( std::u16string( v.data(), v.size() ) );
01274 }
01275 };
01276
01277 template<>
01278 struct hash< nonstd::u32string_view >
01279 {
01280 public:
01281 std::size_t operator()( nonstd::u32string_view v ) const nssv_noexcept
01282 {
01283 return std::hash<std::u32string>()( std::u32string( v.data(), v.size() ) );
01284 }
01285 };
01286
01287 }
01288
01289 #endif // nssv_HAVE_STD_HASH
01290
01291 nssv_RESTORE_WARNINGS()
01292
01293 #endif // nssv_HAVE_STD_STRING_VIEW
01294 #endif // NONSTD_SV_LITE_H_INCLUDED