string_view.hpp
Go to the documentation of this file.
00001 // Copyright 2017-2018 by Martin Moene
00002 //
00003 // string-view lite, a C++17-like string_view for C++98 and later.
00004 // For more information see https://github.com/martinmoene/string-view-lite
00005 //
00006 // Distributed under the Boost Software License, Version 1.0.
00007 // (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // string-view lite configuration:
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 // C++ language version detection (C++20 is speculative):
00059 // Note: VC14.0/1900 (VS2015) lacks too much from C++14.
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 // use C++17 std::string_view if available and requested:
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 // Use C++17 std::string_view:
00095 //
00096 
00097 #if nssv_USES_STD_STRING_VIEW
00098 
00099 #include <string_view>
00100 
00101 // Extensions for std::string:
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 // Literal operators sv and _sv:
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  // (1)
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  // (2)
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  // (3)
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  // (4)
00151 {
00152     return std::wstring_view{ str, len };
00153 }
00154 
00155 }} // namespace literals::string_view_literals
00156 
00157 #endif // nssv_CONFIG_USR_SV_OPERATOR
00158 
00159 } // namespace nonstd
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 // literal "sv" and "_sv", see above
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 } // namespace nonstd
00183 
00184 #else // nssv_HAVE_STD_STRING_VIEW
00185 
00186 //
00187 // Before C++17: use string_view lite:
00188 //
00189 
00190 // Compiler versions:
00191 //
00192 // MSVC++ 6.0  _MSC_VER == 1200 (Visual Studio 6.0)
00193 // MSVC++ 7.0  _MSC_VER == 1300 (Visual Studio .NET 2002)
00194 // MSVC++ 7.1  _MSC_VER == 1310 (Visual Studio .NET 2003)
00195 // MSVC++ 8.0  _MSC_VER == 1400 (Visual Studio 2005)
00196 // MSVC++ 9.0  _MSC_VER == 1500 (Visual Studio 2008)
00197 // MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
00198 // MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
00199 // MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
00200 // MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
00201 // MSVC++ 14.1 _MSC_VER >= 1910 (Visual Studio 2017)
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 // half-open range [lo..hi):
00226 #define nssv_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
00227 
00228 // Presence of language and library features:
00229 
00230 #ifdef _HAS_CPP0X
00231 # define nssv_HAS_CPP0X  _HAS_CPP0X
00232 #else
00233 # define nssv_HAS_CPP0X  0
00234 #endif
00235 
00236 // Unless defined otherwise below, consider VC14 as C++11 for variant-lite:
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 // Presence of C++11 language features:
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 // Presence of C++14 language features:
00271 
00272 #define nssv_HAVE_CONSTEXPR_14          nssv_CPP14_000
00273 
00274 // Presence of C++17 language features:
00275 
00276 #define nssv_HAVE_NODISCARD             nssv_CPP17_000
00277 
00278 // Presence of C++ library features:
00279 
00280 #define nssv_HAVE_STD_HASH              nssv_CPP11_120
00281 
00282 // C++ feature usage:
00283 
00284 #if nssv_HAVE_CONSTEXPR_11
00285 # define nssv_constexpr  constexpr
00286 #else
00287 # define nssv_constexpr  /*constexpr*/
00288 #endif
00289 
00290 #if  nssv_HAVE_CONSTEXPR_14
00291 # define nssv_constexpr14  constexpr
00292 #else
00293 # define nssv_constexpr14  /*constexpr*/
00294 #endif
00295 
00296 #if nssv_HAVE_EXPLICIT_CONVERSION
00297 # define nssv_explicit  explicit
00298 #else
00299 # define nssv_explicit  /*explicit*/
00300 #endif
00301 
00302 #if nssv_HAVE_INLINE_NAMESPACE
00303 # define nssv_inline_ns  inline
00304 #else
00305 # define nssv_inline_ns  /*inline*/
00306 #endif
00307 
00308 #if nssv_HAVE_NOEXCEPT
00309 # define nssv_noexcept  noexcept
00310 #else
00311 # define nssv_noexcept  /*noexcept*/
00312 #endif
00313 
00314 //#if nssv_HAVE_REF_QUALIFIER
00315 //# define nssv_ref_qual  &
00316 //# define nssv_refref_qual  &&
00317 //#else
00318 //# define nssv_ref_qual  /*&*/
00319 //# define nssv_refref_qual  /*&&*/
00320 //#endif
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  /*[[nodiscard]]*/
00332 #endif
00333 
00334 // Additional includes:
00335 
00336 #include <algorithm>
00337 #include <cassert>
00338 #include <iterator>
00339 #include <limits>
00340 #include <ostream>
00341 #include <stdexcept>
00342 #include <string>   // std::char_traits<>
00343 
00344 #if nssv_CPP11_OR_GREATER
00345 # include <type_traits>
00346 #endif
00347 
00348 // Clang, GNUC, MSVC warning suppression macros:
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 // Suppress the following MSVC (GSL) warnings:
00380 // - C4455, non-gsl   : 'operator ""sv': literal suffix identifiers that do not
00381 //                      start with an underscore are reserved
00382 // - C26472, gsl::t.1 : don't use a static_cast for arithmetic conversions;
00383 //                      use brace initialization, gsl::narrow_cast or gsl::narow
00384 // - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead
00385 
00386 nssv_DISABLE_MSVC_WARNINGS( 4455 26481 26472 )
00387 //nssv_DISABLE_CLANG_WARNINGS( "-Wuser-defined-literals" )
00388 //nssv_DISABLE_GNUC_WARNINGS( -Wliteral-suffix )
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 // basic_string_view:
00401 //
00402 
00403 template
00404 <
00405     class CharT,
00406     class Traits /* = std::char_traits<CharT> */
00407 >
00408 class basic_string_view
00409 {
00410 public:
00411     // Member types:
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     // 24.4.2.1 Construction and assignment:
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     // Assignment:
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     // 24.4.2.2 Iterator support:
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     // 24.4.2.3 Capacity:
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     // since C++20
00489     nssv_nodiscard nssv_constexpr bool empty() const nssv_noexcept
00490     {
00491         return 0 == size_;
00492     }
00493 
00494     // 24.4.2.4 Element access:
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     // 24.4.2.5 Modifiers:
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     // 24.4.2.6 String operations:
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     // compare(), 6x:
00561 
00562     nssv_constexpr14 int compare( basic_string_view other ) const nssv_noexcept // (1)
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 // (2)
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 // (3)
00576     {
00577         return substr( pos1, n1 ).compare( other.substr( pos2, n2 ) );
00578     }
00579 
00580     nssv_constexpr int compare( CharT const * s ) const // (4)
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 // (5)
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 // (6)
00591     {
00592         return substr( pos1, n1 ).compare( basic_string_view( s, n2 ) );
00593     }
00594 
00595     // 24.4.2.7 Searching:
00596 
00597     // starts_with(), 3x, since C++20:
00598 
00599     nssv_constexpr bool starts_with( basic_string_view v ) const nssv_noexcept  // (1)
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  // (2)
00605     {
00606         return starts_with( basic_string_view( &c, 1 ) );
00607     }
00608 
00609     nssv_constexpr bool starts_with( CharT const * s ) const  // (3)
00610     {
00611         return starts_with( basic_string_view( s ) );
00612     }
00613 
00614     // ends_with(), 3x, since C++20:
00615 
00616     nssv_constexpr bool ends_with( basic_string_view v ) const nssv_noexcept  // (1)
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  // (2)
00622     {
00623         return ends_with( basic_string_view( &c, 1 ) );
00624     }
00625 
00626     nssv_constexpr bool ends_with( CharT const * s ) const  // (3)
00627     {
00628         return ends_with( basic_string_view( s ) );
00629     }
00630 
00631     // find(), 4x:
00632 
00633     nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept  // (1)
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  // (2)
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  // (3)
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  // (4)
00652     {
00653         return find( basic_string_view( s ), pos );
00654     }
00655 
00656     // rfind(), 4x:
00657 
00658     nssv_constexpr14 size_type rfind( basic_string_view v, size_type pos = npos ) const nssv_noexcept  // (1)
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  // (2)
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  // (3)
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  // (4)
00683     {
00684         return rfind( basic_string_view( s ), pos );
00685     }
00686 
00687     // find_first_of(), 4x:
00688 
00689     nssv_constexpr size_type find_first_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept  // (1)
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  // (2)
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  // (3)
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  // (4)
00707     {
00708         return find_first_of( basic_string_view( s ), pos );
00709     }
00710 
00711     // find_last_of(), 4x:
00712 
00713     nssv_constexpr size_type find_last_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept  // (1)
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  // (2)
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  // (3)
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  // (4)
00733     {
00734         return find_last_of( basic_string_view( s ), pos );
00735     }
00736 
00737     // find_first_not_of(), 4x:
00738 
00739     nssv_constexpr size_type find_first_not_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept  // (1)
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  // (2)
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  // (3)
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  // (4)
00757     {
00758         return find_first_not_of( basic_string_view( s ), pos );
00759     }
00760 
00761     // find_last_not_of(), 4x:
00762 
00763     nssv_constexpr size_type find_last_not_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept  // (1)
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  // (2)
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  // (3)
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  // (4)
00783     {
00784         return find_last_not_of( basic_string_view( s ), pos );
00785     }
00786 
00787     // Constants:
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 // Non-member functions:
00883 //
00884 
00885 // 24.4.3 Non-member comparison functions:
00886 // lexicographically compare two string views (function template):
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 // Let S be basic_string_view<CharT, Traits>, and sv be an instance of S.
00925 // Implementations shall provide sufficient additional overloads marked
00926 // constexpr and noexcept so that an object t with an implicit conversion
00927 // to S can be compared according to Table 67.
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)  /*, int=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 // 24.4.4 Inserters and extractors:
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     // Whether, and how, to pad:
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     // Write span characters:
01057     os.rdbuf()->sputn( sv.begin(), length );
01058 
01059     if ( pad && !left_pad )
01060         write_padding( os, os.width() - length );
01061 
01062     // Reset output stream width:
01063     os.width( 0 );
01064 
01065     return os;
01066 }
01067 
01068 } // namespace detail
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 // Several typedefs for common character types are provided:
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 }} // namespace nonstd::sv_lite
01089 
01090 //
01091 // 24.4.6 Suffix for basic_string_view literals:
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  // (1)
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  // (2)
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  // (3)
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  // (4)
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  // (1)
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  // (2)
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  // (3)
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  // (4)
01142 {
01143     return nonstd::sv_lite::wstring_view{ str, len };
01144 }
01145 
01146 #endif // nssv_CONFIG_USR_SV_OPERATOR
01147 
01148 }}} // namespace nonstd::literals::string_view_literals
01149 
01150 #endif
01151 
01152 //
01153 // Extensions for std::string:
01154 //
01155 
01156 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
01157 
01158 namespace nonstd {
01159 namespace sv_lite {
01160 
01161 // Exclude MSVC 14 (19.00): it yields ambiguous to_string():
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 }} // namespace nonstd::sv_lite
01198 
01199 #endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
01200 
01201 //
01202 // make types and algorithms available in namespace nonstd:
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 // literal "sv"
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 } // namespace nonstd
01235 
01236 // 24.4.5 Hash support (C++11):
01237 
01238 // Note: The hash value of a string view object is equal to the hash value of
01239 // the corresponding string object.
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 } // namespace std
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


plotjuggler
Author(s): Davide Faconti
autogenerated on Wed Jul 3 2019 19:28:05