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 pos >= size()
00716             ? find_last_of( v, size() - 1 )
00717             : to_pos( std::find_first_of( const_reverse_iterator( cbegin() + pos + 1 ), crend(), v.cbegin(), v.cend(), Traits::eq ) );
00718     }
00719 
00720     nssv_constexpr size_type find_last_of( CharT c, size_type pos = npos ) const nssv_noexcept  // (2)
00721     {
00722         return find_last_of( basic_string_view( &c, 1 ), pos );
00723     }
00724 
00725     nssv_constexpr size_type find_last_of( CharT const * s, size_type pos, size_type count ) const  // (3)
00726     {
00727         return find_last_of( basic_string_view( s, count ), pos );
00728     }
00729 
00730     nssv_constexpr size_type find_last_of( CharT const * s, size_type pos = npos ) const  // (4)
00731     {
00732         return find_last_of( basic_string_view( s ), pos );
00733     }
00734 
00735     // find_first_not_of(), 4x:
00736 
00737     nssv_constexpr size_type find_first_not_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept  // (1)
00738     {
00739         return pos >= size()
00740             ? npos
00741             : to_pos( std::find_if( cbegin() + pos, cend(), not_in_view( v ) ) );
00742     }
00743 
00744     nssv_constexpr size_type find_first_not_of( CharT c, size_type pos = 0 ) const nssv_noexcept  // (2)
00745     {
00746         return find_first_not_of( basic_string_view( &c, 1 ), pos );
00747     }
00748 
00749     nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos, size_type count ) const  // (3)
00750     {
00751         return find_first_not_of( basic_string_view( s, count ), pos );
00752     }
00753 
00754     nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos = 0 ) const  // (4)
00755     {
00756         return find_first_not_of( basic_string_view( s ), pos );
00757     }
00758 
00759     // find_last_not_of(), 4x:
00760 
00761     nssv_constexpr size_type find_last_not_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept  // (1)
00762     {
00763         return pos >= size()
00764             ? find_last_not_of( v, size() - 1 )
00765             : to_pos( std::find_if( const_reverse_iterator( cbegin() + pos + 1 ), crend(), not_in_view( v ) ) );
00766     }
00767 
00768     nssv_constexpr size_type find_last_not_of( CharT c, size_type pos = npos ) const nssv_noexcept  // (2)
00769     {
00770         return find_last_not_of( basic_string_view( &c, 1 ), pos );
00771     }
00772 
00773     nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos, size_type count ) const  // (3)
00774     {
00775         return find_last_not_of( basic_string_view( s, count ), pos );
00776     }
00777 
00778     nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos = npos ) const  // (4)
00779     {
00780         return find_last_not_of( basic_string_view( s ), pos );
00781     }
00782 
00783     // Constants:
00784 
00785 #if nssv_CPP17_OR_GREATER
00786     static nssv_constexpr size_type npos = size_type(-1);
00787 #elif nssv_CPP11_OR_GREATER
00788     enum : size_type { npos = size_type(-1) };
00789 #else
00790     enum { npos = size_type(-1) };
00791 #endif
00792 
00793 private:
00794     struct not_in_view
00795     {
00796         const basic_string_view v;
00797 
00798         nssv_constexpr not_in_view( basic_string_view v ) : v( v ) {}
00799 
00800         nssv_constexpr bool operator()( CharT c ) const
00801         {
00802             return npos == v.find_first_of( c );
00803         }
00804     };
00805 
00806     nssv_constexpr size_type to_pos( const_iterator it ) const
00807     {
00808         return it == cend() ? npos : size_type( it - cbegin() );
00809     }
00810 
00811     nssv_constexpr size_type to_pos( const_reverse_iterator it ) const
00812     {
00813         return it == crend() ? npos : size_type( crend() - it - 1 );
00814     }
00815 
00816     nssv_constexpr const_reference data_at( size_type pos ) const
00817     {
00818 #if nssv_BETWEEN( nssv_COMPILER_GNUC_VERSION, 1, 500 )
00819         return data_[pos];
00820 #else
00821         return assert( pos < size() ), data_[pos];
00822 #endif
00823     }
00824 
00825 private:
00826     const_pointer data_;
00827     size_type     size_;
00828 
00829 public:
00830 #if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
00831 
00832     template< class Allocator >
00833     basic_string_view( std::basic_string<CharT, Traits, Allocator> const & s ) nssv_noexcept
00834         : data_( s.data() )
00835         , size_( s.size() )
00836     {}
00837 
00838 #if nssv_HAVE_EXPLICIT_CONVERSION
00839 
00840     template< class Allocator >
00841     explicit operator std::basic_string<CharT, Traits, Allocator>() const
00842     {
00843         return to_string( Allocator() );
00844     }
00845 
00846 #endif // nssv_HAVE_EXPLICIT_CONVERSION
00847 
00848 #if nssv_CPP11_OR_GREATER
00849 
00850     template< class Allocator = std::allocator<CharT> >
00851     std::basic_string<CharT, Traits, Allocator>
00852     to_string( Allocator const & a = Allocator() ) const
00853     {
00854         return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
00855     }
00856 
00857 #else
00858 
00859     std::basic_string<CharT, Traits>
00860     to_string() const
00861     {
00862         return std::basic_string<CharT, Traits>( begin(), end() );
00863     }
00864 
00865     template< class Allocator >
00866     std::basic_string<CharT, Traits, Allocator>
00867     to_string( Allocator const & a ) const
00868     {
00869         return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
00870     }
00871 
00872 #endif // nssv_CPP11_OR_GREATER
00873 
00874 #endif // nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
00875 };
00876 
00877 //
00878 // Non-member functions:
00879 //
00880 
00881 // 24.4.3 Non-member comparison functions:
00882 // lexicographically compare two string views (function template):
00883 
00884 template< class CharT, class Traits >
00885 nssv_constexpr bool operator== (
00886     basic_string_view <CharT, Traits> lhs,
00887     basic_string_view <CharT, Traits> rhs ) nssv_noexcept
00888 { return lhs.compare( rhs ) == 0 ; }
00889 
00890 template< class CharT, class Traits >
00891 nssv_constexpr bool operator!= (
00892     basic_string_view <CharT, Traits> lhs,
00893     basic_string_view <CharT, Traits> rhs ) nssv_noexcept
00894 { return lhs.compare( rhs ) != 0 ; }
00895 
00896 template< class CharT, class Traits >
00897 nssv_constexpr bool operator< (
00898     basic_string_view <CharT, Traits> lhs,
00899     basic_string_view <CharT, Traits> rhs ) nssv_noexcept
00900 { return lhs.compare( rhs ) < 0 ; }
00901 
00902 template< class CharT, class Traits >
00903 nssv_constexpr bool operator<= (
00904     basic_string_view <CharT, Traits> lhs,
00905     basic_string_view <CharT, Traits> rhs ) nssv_noexcept
00906 { return lhs.compare( rhs ) <= 0 ; }
00907 
00908 template< class CharT, class Traits >
00909 nssv_constexpr bool operator> (
00910     basic_string_view <CharT, Traits> lhs,
00911     basic_string_view <CharT, Traits> rhs ) nssv_noexcept
00912 { return lhs.compare( rhs ) > 0 ; }
00913 
00914 template< class CharT, class Traits >
00915 nssv_constexpr bool operator>= (
00916     basic_string_view <CharT, Traits> lhs,
00917     basic_string_view <CharT, Traits> rhs ) nssv_noexcept
00918 { return lhs.compare( rhs ) >= 0 ; }
00919 
00920 // Let S be basic_string_view<CharT, Traits>, and sv be an instance of S.
00921 // Implementations shall provide sufficient additional overloads marked
00922 // constexpr and noexcept so that an object t with an implicit conversion
00923 // to S can be compared according to Table 67.
00924 
00925 #if nssv_CPP11_OR_GREATER && ! nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 100, 141 )
00926 
00927 #define nssv_BASIC_STRING_VIEW_I(T,U)  typename std::decay< basic_string_view<T,U> >::type
00928 
00929 #if nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 140, 150 )
00930 # define nssv_MSVC_ORDER(x)  , int=x
00931 #else
00932 # define nssv_MSVC_ORDER(x)  /*, int=x*/
00933 #endif
00934 
00935 // ==
00936 
00937 template< class CharT, class Traits  nssv_MSVC_ORDER(1) >
00938 nssv_constexpr bool operator==(
00939          basic_string_view  <CharT, Traits> lhs,
00940     nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs ) nssv_noexcept
00941 { return lhs.compare( rhs ) == 0; }
00942 
00943 template< class CharT, class Traits  nssv_MSVC_ORDER(2) >
00944 nssv_constexpr bool operator==(
00945     nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
00946          basic_string_view  <CharT, Traits> rhs ) nssv_noexcept
00947 { return lhs.compare( rhs ) == 0; }
00948 
00949 // !=
00950 
00951 template< class CharT, class Traits  nssv_MSVC_ORDER(1) >
00952 nssv_constexpr bool operator!= (
00953          basic_string_view  < CharT, Traits > lhs,
00954     nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
00955 { return lhs.compare( rhs ) != 0 ; }
00956 
00957 template< class CharT, class Traits  nssv_MSVC_ORDER(2) >
00958 nssv_constexpr bool operator!= (
00959     nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
00960          basic_string_view  < CharT, Traits > rhs ) nssv_noexcept
00961 { return lhs.compare( rhs ) != 0 ; }
00962 
00963 // <
00964 
00965 template< class CharT, class Traits  nssv_MSVC_ORDER(1) >
00966 nssv_constexpr bool operator< (
00967          basic_string_view  < CharT, Traits > lhs,
00968     nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
00969 { return lhs.compare( rhs ) < 0 ; }
00970 
00971 template< class CharT, class Traits  nssv_MSVC_ORDER(2) >
00972 nssv_constexpr bool operator< (
00973     nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
00974          basic_string_view  < CharT, Traits > rhs ) nssv_noexcept
00975 { return lhs.compare( rhs ) < 0 ; }
00976 
00977 // <=
00978 
00979 template< class CharT, class Traits  nssv_MSVC_ORDER(1) >
00980 nssv_constexpr bool operator<= (
00981          basic_string_view  < CharT, Traits > lhs,
00982     nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
00983 { return lhs.compare( rhs ) <= 0 ; }
00984 
00985 template< class CharT, class Traits  nssv_MSVC_ORDER(2) >
00986 nssv_constexpr bool operator<= (
00987     nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
00988          basic_string_view  < CharT, Traits > rhs ) nssv_noexcept
00989 { return lhs.compare( rhs ) <= 0 ; }
00990 
00991 // >
00992 
00993 template< class CharT, class Traits  nssv_MSVC_ORDER(1) >
00994 nssv_constexpr bool operator> (
00995          basic_string_view  < CharT, Traits > lhs,
00996     nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
00997 { return lhs.compare( rhs ) > 0 ; }
00998 
00999 template< class CharT, class Traits  nssv_MSVC_ORDER(2) >
01000 nssv_constexpr bool operator> (
01001     nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
01002          basic_string_view  < CharT, Traits > rhs ) nssv_noexcept
01003 { return lhs.compare( rhs ) > 0 ; }
01004 
01005 // >=
01006 
01007 template< class CharT, class Traits  nssv_MSVC_ORDER(1) >
01008 nssv_constexpr bool operator>= (
01009          basic_string_view  < CharT, Traits > lhs,
01010     nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
01011 { return lhs.compare( rhs ) >= 0 ; }
01012 
01013 template< class CharT, class Traits  nssv_MSVC_ORDER(2) >
01014 nssv_constexpr bool operator>= (
01015     nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
01016          basic_string_view  < CharT, Traits > rhs ) nssv_noexcept
01017 { return lhs.compare( rhs ) >= 0 ; }
01018 
01019 #undef nssv_MSVC_ORDER
01020 #undef nssv_BASIC_STRING_VIEW_I
01021 
01022 #endif // nssv_CPP11_OR_GREATER
01023 
01024 // 24.4.4 Inserters and extractors:
01025 
01026 namespace detail {
01027 
01028 template< class Stream >
01029 void write_padding( Stream & os, std::streamsize n )
01030 {
01031     for ( std::streamsize i = 0; i < n; ++i )
01032         os.rdbuf()->sputc( os.fill() );
01033 }
01034 
01035 template< class Stream, class View >
01036 Stream & write_to_stream( Stream & os, View const & sv )
01037 {
01038     typename Stream::sentry sentry( os );
01039 
01040     if ( !os )
01041         return os;
01042 
01043     const std::streamsize length = static_cast<std::streamsize>( sv.length() );
01044 
01045     // Whether, and how, to pad:
01046     const bool      pad = ( length < os.width() );
01047     const bool left_pad = pad && ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::right;
01048 
01049     if ( left_pad )
01050         write_padding( os, os.width() - length );
01051 
01052     // Write span characters:
01053     os.rdbuf()->sputn( sv.begin(), length );
01054 
01055     if ( pad && !left_pad )
01056         write_padding( os, os.width() - length );
01057 
01058     // Reset output stream width:
01059     os.width( 0 );
01060 
01061     return os;
01062 }
01063 
01064 } // namespace detail
01065 
01066 template< class CharT, class Traits >
01067 std::basic_ostream<CharT, Traits> &
01068 operator<<(
01069     std::basic_ostream<CharT, Traits>& os,
01070     basic_string_view <CharT, Traits> sv )
01071 {
01072     return detail::write_to_stream( os, sv );
01073 }
01074 
01075 // Several typedefs for common character types are provided:
01076 
01077 typedef basic_string_view<char>      string_view;
01078 typedef basic_string_view<wchar_t>   wstring_view;
01079 #if nssv_HAVE_WCHAR16_T
01080 typedef basic_string_view<char16_t>  u16string_view;
01081 typedef basic_string_view<char32_t>  u32string_view;
01082 #endif
01083 
01084 }} // namespace nonstd::sv_lite
01085 
01086 //
01087 // 24.4.6 Suffix for basic_string_view literals:
01088 //
01089 
01090 #if nssv_HAVE_USER_DEFINED_LITERALS
01091 
01092 namespace nonstd {
01093 nssv_inline_ns namespace literals {
01094 nssv_inline_ns namespace string_view_literals {
01095 
01096 #if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
01097 
01098 nssv_constexpr nonstd::sv_lite::string_view operator "" sv( const char* str, size_t len ) nssv_noexcept  // (1)
01099 {
01100     return nonstd::sv_lite::string_view{ str, len };
01101 }
01102 
01103 nssv_constexpr nonstd::sv_lite::u16string_view operator "" sv( const char16_t* str, size_t len ) nssv_noexcept  // (2)
01104 {
01105     return nonstd::sv_lite::u16string_view{ str, len };
01106 }
01107 
01108 nssv_constexpr nonstd::sv_lite::u32string_view operator "" sv( const char32_t* str, size_t len ) nssv_noexcept  // (3)
01109 {
01110     return nonstd::sv_lite::u32string_view{ str, len };
01111 }
01112 
01113 nssv_constexpr nonstd::sv_lite::wstring_view operator "" sv( const wchar_t* str, size_t len ) nssv_noexcept  // (4)
01114 {
01115     return nonstd::sv_lite::wstring_view{ str, len };
01116 }
01117 
01118 #endif // nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
01119 
01120 #if nssv_CONFIG_USR_SV_OPERATOR
01121 
01122 nssv_constexpr nonstd::sv_lite::string_view operator "" _sv( const char* str, size_t len ) nssv_noexcept  // (1)
01123 {
01124     return nonstd::sv_lite::string_view{ str, len };
01125 }
01126 
01127 nssv_constexpr nonstd::sv_lite::u16string_view operator "" _sv( const char16_t* str, size_t len ) nssv_noexcept  // (2)
01128 {
01129     return nonstd::sv_lite::u16string_view{ str, len };
01130 }
01131 
01132 nssv_constexpr nonstd::sv_lite::u32string_view operator "" _sv( const char32_t* str, size_t len ) nssv_noexcept  // (3)
01133 {
01134     return nonstd::sv_lite::u32string_view{ str, len };
01135 }
01136 
01137 nssv_constexpr nonstd::sv_lite::wstring_view operator "" _sv( const wchar_t* str, size_t len ) nssv_noexcept  // (4)
01138 {
01139     return nonstd::sv_lite::wstring_view{ str, len };
01140 }
01141 
01142 #endif // nssv_CONFIG_USR_SV_OPERATOR
01143 
01144 }}} // namespace nonstd::literals::string_view_literals
01145 
01146 #endif
01147 
01148 //
01149 // Extensions for std::string:
01150 //
01151 
01152 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
01153 
01154 namespace nonstd {
01155 namespace sv_lite {
01156 
01157 // Exclude MSVC 14 (19.00): it yields ambiguous to_string():
01158 
01159 #if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140
01160 
01161 template< class CharT, class Traits, class Allocator = std::allocator<CharT> >
01162 std::basic_string<CharT, Traits, Allocator>
01163 to_string( basic_string_view<CharT, Traits> v, Allocator const & a = Allocator() )
01164 {
01165     return std::basic_string<CharT,Traits, Allocator>( v.begin(), v.end(), a );
01166 }
01167 
01168 #else
01169 
01170 template< class CharT, class Traits >
01171 std::basic_string<CharT, Traits>
01172 to_string( basic_string_view<CharT, Traits> v )
01173 {
01174     return std::basic_string<CharT, Traits>( v.begin(), v.end() );
01175 }
01176 
01177 template< class CharT, class Traits, class Allocator >
01178 std::basic_string<CharT, Traits, Allocator>
01179 to_string( basic_string_view<CharT, Traits> v, Allocator const & a )
01180 {
01181     return std::basic_string<CharT, Traits, Allocator>( v.begin(), v.end(), a );
01182 }
01183 
01184 #endif // nssv_CPP11_OR_GREATER
01185 
01186 template< class CharT, class Traits, class Allocator >
01187 basic_string_view<CharT, Traits>
01188 to_string_view( std::basic_string<CharT, Traits, Allocator> const & s )
01189 {
01190     return basic_string_view<CharT, Traits>( s.data(), s.size() );
01191 }
01192 
01193 }} // namespace nonstd::sv_lite
01194 
01195 #endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
01196 
01197 //
01198 // make types and algorithms available in namespace nonstd:
01199 //
01200 
01201 namespace nonstd {
01202 
01203 using sv_lite::basic_string_view;
01204 using sv_lite::string_view;
01205 using sv_lite::wstring_view;
01206 
01207 #if nssv_HAVE_WCHAR16_T
01208 using sv_lite::u16string_view;
01209 #endif
01210 #if nssv_HAVE_WCHAR32_T
01211 using sv_lite::u32string_view;
01212 #endif
01213 
01214 // literal "sv"
01215 
01216 using sv_lite::operator==;
01217 using sv_lite::operator!=;
01218 using sv_lite::operator<;
01219 using sv_lite::operator<=;
01220 using sv_lite::operator>;
01221 using sv_lite::operator>=;
01222 
01223 using sv_lite::operator<<;
01224 
01225 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
01226 using sv_lite::to_string;
01227 using sv_lite::to_string_view;
01228 #endif
01229 
01230 } // namespace nonstd
01231 
01232 // 24.4.5 Hash support (C++11):
01233 
01234 // Note: The hash value of a string view object is equal to the hash value of
01235 // the corresponding string object.
01236 
01237 #if nssv_HAVE_STD_HASH
01238 
01239 #include <functional>
01240 
01241 namespace std {
01242 
01243 template<>
01244 struct hash< nonstd::string_view >
01245 {
01246 public:
01247     std::size_t operator()( nonstd::string_view v ) const nssv_noexcept
01248     {
01249         return std::hash<std::string>()( std::string( v.data(), v.size() ) );
01250     }
01251 };
01252 
01253 template<>
01254 struct hash< nonstd::wstring_view >
01255 {
01256 public:
01257     std::size_t operator()( nonstd::wstring_view v ) const nssv_noexcept
01258     {
01259         return std::hash<std::wstring>()( std::wstring( v.data(), v.size() ) );
01260     }
01261 };
01262 
01263 template<>
01264 struct hash< nonstd::u16string_view >
01265 {
01266 public:
01267     std::size_t operator()( nonstd::u16string_view v ) const nssv_noexcept
01268     {
01269         return std::hash<std::u16string>()( std::u16string( v.data(), v.size() ) );
01270     }
01271 };
01272 
01273 template<>
01274 struct hash< nonstd::u32string_view >
01275 {
01276 public:
01277     std::size_t operator()( nonstd::u32string_view v ) const nssv_noexcept
01278     {
01279         return std::hash<std::u32string>()( std::u32string( v.data(), v.size() ) );
01280     }
01281 };
01282 
01283 } // namespace std
01284 
01285 #endif // nssv_HAVE_STD_HASH
01286 
01287 nssv_RESTORE_WARNINGS()
01288 
01289 #endif // nssv_HAVE_STD_STRING_VIEW
01290 #endif // NONSTD_SV_LITE_H_INCLUDED
01291 


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sat Feb 2 2019 03:50:10