string_view.hpp
Go to the documentation of this file.
1 // Copyright 2017-2018 by Martin Moene
2 //
3 // string-view lite, a C++17-like string_view for C++98 and later.
4 // For more information see https://github.com/martinmoene/string-view-lite
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 
9 #pragma once
10 
11 #ifndef NONSTD_SV_LITE_H_INCLUDED
12 #define NONSTD_SV_LITE_H_INCLUDED
13 
14 #define string_view_lite_MAJOR 1
15 #define string_view_lite_MINOR 1
16 #define string_view_lite_PATCH 0
17 
18 #define string_view_lite_VERSION nssv_STRINGIFY(string_view_lite_MAJOR) "." nssv_STRINGIFY(string_view_lite_MINOR) "." nssv_STRINGIFY(string_view_lite_PATCH)
19 
20 #define nssv_STRINGIFY( x ) nssv_STRINGIFY_( x )
21 #define nssv_STRINGIFY_( x ) #x
22 
23 // string-view lite configuration:
24 
25 #define nssv_STRING_VIEW_DEFAULT 0
26 #define nssv_STRING_VIEW_NONSTD 1
27 #define nssv_STRING_VIEW_STD 2
28 
29 #if !defined( nssv_CONFIG_SELECT_STRING_VIEW )
30 # define nssv_CONFIG_SELECT_STRING_VIEW ( nssv_HAVE_STD_STRING_VIEW ? nssv_STRING_VIEW_STD : nssv_STRING_VIEW_NONSTD )
31 #endif
32 
33 #if defined( nssv_CONFIG_SELECT_STD_STRING_VIEW ) || defined( nssv_CONFIG_SELECT_NONSTD_STRING_VIEW )
34 # 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_...
35 #endif
36 
37 #ifndef nssv_CONFIG_STD_SV_OPERATOR
38 # define nssv_CONFIG_STD_SV_OPERATOR 0
39 #endif
40 
41 #ifndef nssv_CONFIG_USR_SV_OPERATOR
42 # define nssv_CONFIG_USR_SV_OPERATOR 1
43 #endif
44 
45 #ifdef nssv_CONFIG_CONVERSION_STD_STRING
46 # define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS nssv_CONFIG_CONVERSION_STD_STRING
47 # define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS nssv_CONFIG_CONVERSION_STD_STRING
48 #endif
49 
50 #ifndef nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
51 # define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS 1
52 #endif
53 
54 #ifndef nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
55 # define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS 1
56 #endif
57 
58 // C++ language version detection (C++20 is speculative):
59 // Note: VC14.0/1900 (VS2015) lacks too much from C++14.
60 
61 #ifndef nssv_CPLUSPLUS
62 # if defined(_MSVC_LANG ) && !defined(__clang__)
63 # define nssv_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
64 # else
65 # define nssv_CPLUSPLUS __cplusplus
66 # endif
67 #endif
68 
69 #define nssv_CPP98_OR_GREATER ( nssv_CPLUSPLUS >= 199711L )
70 #define nssv_CPP11_OR_GREATER ( nssv_CPLUSPLUS >= 201103L )
71 #define nssv_CPP11_OR_GREATER_ ( nssv_CPLUSPLUS >= 201103L )
72 #define nssv_CPP14_OR_GREATER ( nssv_CPLUSPLUS >= 201402L )
73 #define nssv_CPP17_OR_GREATER ( nssv_CPLUSPLUS >= 201703L )
74 #define nssv_CPP20_OR_GREATER ( nssv_CPLUSPLUS >= 202000L )
75 
76 // use C++17 std::string_view if available and requested:
77 
78 #if nssv_CPP17_OR_GREATER && defined(__has_include )
79 # if __has_include( <string_view> )
80 # define nssv_HAVE_STD_STRING_VIEW 1
81 # else
82 # define nssv_HAVE_STD_STRING_VIEW 0
83 # endif
84 #else
85 # define nssv_HAVE_STD_STRING_VIEW 0
86 #endif
87 
88 #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) )
89 
90 #define nssv_HAVE_STARTS_WITH ( nssv_CPP20_OR_GREATER || !nssv_USES_STD_STRING_VIEW )
91 #define nssv_HAVE_ENDS_WITH nssv_HAVE_STARTS_WITH
92 
93 //
94 // Use C++17 std::string_view:
95 //
96 
97 #if nssv_USES_STD_STRING_VIEW
98 
99 #include <string_view>
100 
101 // Extensions for std::string:
102 
103 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
104 
105 namespace nonstd {
106 
107 template< class CharT, class Traits, class Allocator = std::allocator<CharT> >
108 std::basic_string<CharT, Traits, Allocator>
109 to_string( std::basic_string_view<CharT, Traits> v, Allocator const & a = Allocator() )
110 {
111  return std::basic_string<CharT,Traits, Allocator>( v.begin(), v.end(), a );
112 }
113 
114 template< class CharT, class Traits, class Allocator >
115 std::basic_string_view<CharT, Traits>
116 to_string_view( std::basic_string<CharT, Traits, Allocator> const & s )
117 {
118  return std::basic_string_view<CharT, Traits>( s.data(), s.size() );
119 }
120 
121 // Literal operators sv and _sv:
122 
123 #if nssv_CONFIG_STD_SV_OPERATOR
124 
125 using namespace std::literals::string_view_literals;
126 
127 #endif
128 
129 #if nssv_CONFIG_USR_SV_OPERATOR
130 
131 inline namespace literals {
132 inline namespace string_view_literals {
133 
134 
135 constexpr std::string_view operator "" _sv( const char* str, size_t len ) noexcept // (1)
136 {
137  return std::string_view{ str, len };
138 }
139 
140 constexpr std::u16string_view operator "" _sv( const char16_t* str, size_t len ) noexcept // (2)
141 {
142  return std::u16string_view{ str, len };
143 }
144 
145 constexpr std::u32string_view operator "" _sv( const char32_t* str, size_t len ) noexcept // (3)
146 {
147  return std::u32string_view{ str, len };
148 }
149 
150 constexpr std::wstring_view operator "" _sv( const wchar_t* str, size_t len ) noexcept // (4)
151 {
152  return std::wstring_view{ str, len };
153 }
154 
155 }} // namespace literals::string_view_literals
156 
157 #endif // nssv_CONFIG_USR_SV_OPERATOR
158 
159 } // namespace nonstd
160 
161 #endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
162 
163 namespace nonstd {
164 
165 using std::string_view;
166 using std::wstring_view;
167 using std::u16string_view;
168 using std::u32string_view;
169 using std::basic_string_view;
170 
171 // literal "sv" and "_sv", see above
172 
173 using std::operator==;
174 using std::operator!=;
175 using std::operator<;
176 using std::operator<=;
177 using std::operator>;
178 using std::operator>=;
179 
180 using std::operator<<;
181 
182 } // namespace nonstd
183 
184 #else // nssv_HAVE_STD_STRING_VIEW
185 
186 //
187 // Before C++17: use string_view lite:
188 //
189 
190 // Compiler versions:
191 //
192 // MSVC++ 6.0 _MSC_VER == 1200 (Visual Studio 6.0)
193 // MSVC++ 7.0 _MSC_VER == 1300 (Visual Studio .NET 2002)
194 // MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio .NET 2003)
195 // MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
196 // MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
197 // MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
198 // MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
199 // MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
200 // MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
201 // MSVC++ 14.1 _MSC_VER >= 1910 (Visual Studio 2017)
202 
203 #if defined(_MSC_VER ) && !defined(__clang__)
204 # define nssv_COMPILER_MSVC_VER (_MSC_VER )
205 # define nssv_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
206 #else
207 # define nssv_COMPILER_MSVC_VER 0
208 # define nssv_COMPILER_MSVC_VERSION 0
209 #endif
210 
211 #define nssv_COMPILER_VERSION( major, minor, patch ) (10 * ( 10 * major + minor) + patch)
212 
213 #if defined(__clang__)
214 # define nssv_COMPILER_CLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
215 #else
216 # define nssv_COMPILER_CLANG_VERSION 0
217 #endif
218 
219 #if defined(__GNUC__) && !defined(__clang__)
220 # define nssv_COMPILER_GNUC_VERSION nssv_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
221 #else
222 # define nssv_COMPILER_GNUC_VERSION 0
223 #endif
224 
225 // half-open range [lo..hi):
226 #define nssv_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
227 
228 // Presence of language and library features:
229 
230 #ifdef _HAS_CPP0X
231 # define nssv_HAS_CPP0X _HAS_CPP0X
232 #else
233 # define nssv_HAS_CPP0X 0
234 #endif
235 
236 // Unless defined otherwise below, consider VC14 as C++11 for variant-lite:
237 
238 #if nssv_COMPILER_MSVC_VER >= 1900
239 # undef nssv_CPP11_OR_GREATER
240 # define nssv_CPP11_OR_GREATER 1
241 #endif
242 
243 #define nssv_CPP11_90 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1500)
244 #define nssv_CPP11_100 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1600)
245 #define nssv_CPP11_110 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1700)
246 #define nssv_CPP11_120 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1800)
247 #define nssv_CPP11_140 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1900)
248 #define nssv_CPP11_141 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1910)
249 
250 #define nssv_CPP14_000 (nssv_CPP14_OR_GREATER)
251 #define nssv_CPP17_000 (nssv_CPP17_OR_GREATER)
252 
253 // Presence of C++11 language features:
254 
255 #define nssv_HAVE_CONSTEXPR_11 nssv_CPP11_140
256 #define nssv_HAVE_EXPLICIT_CONVERSION nssv_CPP11_140
257 #define nssv_HAVE_INLINE_NAMESPACE nssv_CPP11_140
258 #define nssv_HAVE_NOEXCEPT nssv_CPP11_140
259 #define nssv_HAVE_NULLPTR nssv_CPP11_100
260 #define nssv_HAVE_REF_QUALIFIER nssv_CPP11_140
261 #define nssv_HAVE_UNICODE_LITERALS nssv_CPP11_140
262 #define nssv_HAVE_USER_DEFINED_LITERALS nssv_CPP11_140
263 #define nssv_HAVE_WCHAR16_T nssv_CPP11_100
264 #define nssv_HAVE_WCHAR32_T nssv_CPP11_100
265 
266 #if ! ( ( nssv_CPP11 && nssv_COMPILER_CLANG_VERSION ) || nssv_BETWEEN( nssv_COMPILER_CLANG_VERSION, 300, 400 ) )
267 # define nssv_HAVE_STD_DEFINED_LITERALS nssv_CPP11_140
268 #endif
269 
270 // Presence of C++14 language features:
271 
272 #define nssv_HAVE_CONSTEXPR_14 nssv_CPP14_000
273 
274 // Presence of C++17 language features:
275 
276 #define nssv_HAVE_NODISCARD nssv_CPP17_000
277 
278 // Presence of C++ library features:
279 
280 #define nssv_HAVE_STD_HASH nssv_CPP11_120
281 
282 // C++ feature usage:
283 
284 #if nssv_HAVE_CONSTEXPR_11
285 # define nssv_constexpr constexpr
286 #else
287 # define nssv_constexpr /*constexpr*/
288 #endif
289 
290 #if nssv_HAVE_CONSTEXPR_14
291 # define nssv_constexpr14 constexpr
292 #else
293 # define nssv_constexpr14 /*constexpr*/
294 #endif
295 
296 #if nssv_HAVE_EXPLICIT_CONVERSION
297 # define nssv_explicit explicit
298 #else
299 # define nssv_explicit /*explicit*/
300 #endif
301 
302 #if nssv_HAVE_INLINE_NAMESPACE
303 # define nssv_inline_ns inline
304 #else
305 # define nssv_inline_ns /*inline*/
306 #endif
307 
308 #if nssv_HAVE_NOEXCEPT
309 # define nssv_noexcept noexcept
310 #else
311 # define nssv_noexcept /*noexcept*/
312 #endif
313 
314 //#if nssv_HAVE_REF_QUALIFIER
315 //# define nssv_ref_qual &
316 //# define nssv_refref_qual &&
317 //#else
318 //# define nssv_ref_qual /*&*/
319 //# define nssv_refref_qual /*&&*/
320 //#endif
321 
322 #if nssv_HAVE_NULLPTR
323 # define nssv_nullptr nullptr
324 #else
325 # define nssv_nullptr NULL
326 #endif
327 
328 #if nssv_HAVE_NODISCARD
329 # define nssv_nodiscard [[nodiscard]]
330 #else
331 # define nssv_nodiscard /*[[nodiscard]]*/
332 #endif
333 
334 // Additional includes:
335 
336 #include <algorithm>
337 #include <cassert>
338 #include <iterator>
339 #include <limits>
340 #include <ostream>
341 #include <stdexcept>
342 #include <string> // std::char_traits<>
343 
344 #if nssv_CPP11_OR_GREATER
345 # include <type_traits>
346 #endif
347 
348 // Clang, GNUC, MSVC warning suppression macros:
349 
350 #if defined(__clang__)
351 # pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
352 # pragma clang diagnostic push
353 # pragma clang diagnostic ignored "-Wuser-defined-literals"
354 #elif defined(__GNUC__)
355 # pragma GCC diagnostic push
356 # pragma GCC diagnostic ignored "-Wliteral-suffix"
357 #endif // __clang__
358 
359 #if nssv_COMPILER_MSVC_VERSION >= 140
360 # define nssv_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]]
361 # define nssv_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress: code) )
362 # define nssv_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable: codes))
363 #else
364 # define nssv_SUPPRESS_MSGSL_WARNING(expr)
365 # define nssv_SUPPRESS_MSVC_WARNING(code, descr)
366 # define nssv_DISABLE_MSVC_WARNINGS(codes)
367 #endif
368 
369 #if defined(__clang__)
370 # define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
371 #elif defined(__GNUC__)
372 # define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
373 #elif nssv_COMPILER_MSVC_VERSION >= 140
374 # define nssv_RESTORE_WARNINGS() __pragma(warning(pop ))
375 #else
376 # define nssv_RESTORE_WARNINGS()
377 #endif
378 
379 // Suppress the following MSVC (GSL) warnings:
380 // - C4455, non-gsl : 'operator ""sv': literal suffix identifiers that do not
381 // start with an underscore are reserved
382 // - C26472, gsl::t.1 : don't use a static_cast for arithmetic conversions;
383 // use brace initialization, gsl::narrow_cast or gsl::narow
384 // - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead
385 
386 nssv_DISABLE_MSVC_WARNINGS( 4455 26481 26472 )
387 //nssv_DISABLE_CLANG_WARNINGS( "-Wuser-defined-literals" )
388 //nssv_DISABLE_GNUC_WARNINGS( -Wliteral-suffix )
389 
390 namespace nonstd { namespace sv_lite {
391 
392 template
393 <
394  class CharT,
395  class Traits = std::char_traits<CharT>
396 >
397 class basic_string_view;
398 
399 //
400 // basic_string_view:
401 //
402 
403 template
404 <
405  class CharT,
406  class Traits /* = std::char_traits<CharT> */
407 >
408 class basic_string_view
409 {
410 public:
411  // Member types:
412 
413  typedef Traits traits_type;
414  typedef CharT value_type;
415 
416  typedef CharT * pointer;
417  typedef CharT const * const_pointer;
418  typedef CharT & reference;
419  typedef CharT const & const_reference;
420 
421  typedef const_pointer iterator;
422  typedef const_pointer const_iterator;
423  typedef std::reverse_iterator< const_iterator > reverse_iterator;
424  typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
425 
426  typedef std::size_t size_type;
427  typedef std::ptrdiff_t difference_type;
428 
429  // 24.4.2.1 Construction and assignment:
430 
431  nssv_constexpr basic_string_view() nssv_noexcept
432  : data_( nssv_nullptr )
433  , size_( 0 )
434  {}
435 
436 #if nssv_CPP11_OR_GREATER
437  nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept = default;
438 #else
439  nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept
440  : data_( other.data_)
441  , size_( other.size_)
442  {}
443 #endif
444 
445  nssv_constexpr basic_string_view( CharT const * s, size_type count )
446  : data_( s )
447  , size_( count )
448  {}
449 
450  nssv_constexpr basic_string_view( CharT const * s)
451  : data_( s )
452  , size_( Traits::length(s) )
453  {}
454 
455  // Assignment:
456 
457 #if nssv_CPP11_OR_GREATER
458  nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept = default;
459 #else
460  nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept
461  {
462  data_ = other.data_;
463  size_ = other.size_;
464  return *this;
465  }
466 #endif
467 
468  // 24.4.2.2 Iterator support:
469 
470  nssv_constexpr const_iterator begin() const nssv_noexcept { return data_; }
471  nssv_constexpr const_iterator end() const nssv_noexcept { return data_ + size_; }
472 
473  nssv_constexpr const_iterator cbegin() const nssv_noexcept { return begin(); }
474  nssv_constexpr const_iterator cend() const nssv_noexcept { return end(); }
475 
476  nssv_constexpr const_reverse_iterator rbegin() const nssv_noexcept { return const_reverse_iterator( end() ); }
477  nssv_constexpr const_reverse_iterator rend() const nssv_noexcept { return const_reverse_iterator( begin() ); }
478 
479  nssv_constexpr const_reverse_iterator crbegin() const nssv_noexcept { return rbegin(); }
480  nssv_constexpr const_reverse_iterator crend() const nssv_noexcept { return rend(); }
481 
482  // 24.4.2.3 Capacity:
483 
484  nssv_constexpr size_type size() const nssv_noexcept { return size_; }
485  nssv_constexpr size_type length() const nssv_noexcept { return size_; }
486  nssv_constexpr size_type max_size() const nssv_noexcept { return (std::numeric_limits< size_type >::max)(); }
487 
488  // since C++20
489  nssv_nodiscard nssv_constexpr bool empty() const nssv_noexcept
490  {
491  return 0 == size_;
492  }
493 
494  // 24.4.2.4 Element access:
495 
496  nssv_constexpr const_reference operator[]( size_type pos ) const
497  {
498  return data_at( pos );
499  }
500 
501  nssv_constexpr14 const_reference at( size_type pos ) const
502  {
503  if ( pos < size() )
504  {
505  return data_at( pos );
506  }
507 
508  throw std::out_of_range("nonst::string_view::at()");
509  }
510 
511  nssv_constexpr const_reference front() const { return data_at( 0 ); }
512  nssv_constexpr const_reference back() const { return data_at( size() - 1 ); }
513 
514  nssv_constexpr const_pointer data() const nssv_noexcept { return data_; }
515 
516  // 24.4.2.5 Modifiers:
517 
518  nssv_constexpr14 void remove_prefix( size_type n )
519  {
520  assert( n <= size() );
521  data_ += n;
522  size_ -= n;
523  }
524 
525  nssv_constexpr14 void remove_suffix( size_type n )
526  {
527  assert( n <= size() );
528  size_ -= n;
529  }
530 
531  nssv_constexpr14 void swap( basic_string_view & other ) nssv_noexcept
532  {
533  using std::swap;
534  swap( data_, other.data_ );
535  swap( size_, other.size_ );
536  }
537 
538  // 24.4.2.6 String operations:
539 
540  size_type copy( CharT * dest, size_type n, size_type pos = 0 ) const
541  {
542  if ( pos > size() )
543  throw std::out_of_range("nonst::string_view::copy()");
544 
545  const size_type rlen = (std::min)( n, size() - pos );
546 
547  (void) Traits::copy( dest, data() + pos, rlen );
548 
549  return rlen;
550  }
551 
552  nssv_constexpr14 basic_string_view substr( size_type pos = 0, size_type n = npos ) const
553  {
554  if ( pos > size() )
555  throw std::out_of_range("nonst::string_view::substr()");
556 
557  return basic_string_view( data() + pos, (std::min)( n, size() - pos ) );
558  }
559 
560  // compare(), 6x:
561 
562  nssv_constexpr14 int compare( basic_string_view other ) const nssv_noexcept // (1)
563  {
564  if ( const int result = Traits::compare( data(), other.data(), (std::min)( size(), other.size() ) ) )
565  return result;
566 
567  return size() == other.size() ? 0 : size() < other.size() ? -1 : 1;
568  }
569 
570  nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other ) const // (2)
571  {
572  return substr( pos1, n1 ).compare( other );
573  }
574 
575  nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other, size_type pos2, size_type n2 ) const // (3)
576  {
577  return substr( pos1, n1 ).compare( other.substr( pos2, n2 ) );
578  }
579 
580  nssv_constexpr int compare( CharT const * s ) const // (4)
581  {
582  return compare( basic_string_view( s ) );
583  }
584 
585  nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s ) const // (5)
586  {
587  return substr( pos1, n1 ).compare( basic_string_view( s ) );
588  }
589 
590  nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s, size_type n2 ) const // (6)
591  {
592  return substr( pos1, n1 ).compare( basic_string_view( s, n2 ) );
593  }
594 
595  // 24.4.2.7 Searching:
596 
597  // starts_with(), 3x, since C++20:
598 
599  nssv_constexpr bool starts_with( basic_string_view v ) const nssv_noexcept // (1)
600  {
601  return size() >= v.size() && compare( 0, v.size(), v ) == 0;
602  }
603 
604  nssv_constexpr bool starts_with( CharT c ) const nssv_noexcept // (2)
605  {
606  return starts_with( basic_string_view( &c, 1 ) );
607  }
608 
609  nssv_constexpr bool starts_with( CharT const * s ) const // (3)
610  {
611  return starts_with( basic_string_view( s ) );
612  }
613 
614  // ends_with(), 3x, since C++20:
615 
616  nssv_constexpr bool ends_with( basic_string_view v ) const nssv_noexcept // (1)
617  {
618  return size() >= v.size() && compare( size() - v.size(), npos, v ) == 0;
619  }
620 
621  nssv_constexpr bool ends_with( CharT c ) const nssv_noexcept // (2)
622  {
623  return ends_with( basic_string_view( &c, 1 ) );
624  }
625 
626  nssv_constexpr bool ends_with( CharT const * s ) const // (3)
627  {
628  return ends_with( basic_string_view( s ) );
629  }
630 
631  // find(), 4x:
632 
633  nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
634  {
635  return assert( v.size() == 0 || v.data() != nssv_nullptr )
636  , pos >= size()
637  ? npos
638  : to_pos( std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
639  }
640 
641  nssv_constexpr14 size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
642  {
643  return find( basic_string_view( &c, 1 ), pos );
644  }
645 
646  nssv_constexpr14 size_type find( CharT const * s, size_type pos, size_type n ) const // (3)
647  {
648  return find( basic_string_view( s, n ), pos );
649  }
650 
651  nssv_constexpr14 size_type find( CharT const * s, size_type pos = 0 ) const // (4)
652  {
653  return find( basic_string_view( s ), pos );
654  }
655 
656  // rfind(), 4x:
657 
658  nssv_constexpr14 size_type rfind( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1)
659  {
660  if ( size() < v.size() )
661  return npos;
662 
663  if ( v.empty() )
664  return (std::min)( size(), pos );
665 
666  const_iterator last = cbegin() + (std::min)( size() - v.size(), pos ) + v.size();
667  const_iterator result = std::find_end( cbegin(), last, v.cbegin(), v.cend(), Traits::eq );
668 
669  return result != last ? size_type( result - cbegin() ) : npos;
670  }
671 
672  nssv_constexpr14 size_type rfind( CharT c, size_type pos = npos ) const nssv_noexcept // (2)
673  {
674  return rfind( basic_string_view( &c, 1 ), pos );
675  }
676 
677  nssv_constexpr14 size_type rfind( CharT const * s, size_type pos, size_type n ) const // (3)
678  {
679  return rfind( basic_string_view( s, n ), pos );
680  }
681 
682  nssv_constexpr14 size_type rfind( CharT const * s, size_type pos = npos ) const // (4)
683  {
684  return rfind( basic_string_view( s ), pos );
685  }
686 
687  // find_first_of(), 4x:
688 
689  nssv_constexpr size_type find_first_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
690  {
691  return pos >= size()
692  ? npos
693  : to_pos( std::find_first_of( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
694  }
695 
696  nssv_constexpr size_type find_first_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
697  {
698  return find_first_of( basic_string_view( &c, 1 ), pos );
699  }
700 
701  nssv_constexpr size_type find_first_of( CharT const * s, size_type pos, size_type n ) const // (3)
702  {
703  return find_first_of( basic_string_view( s, n ), pos );
704  }
705 
706  nssv_constexpr size_type find_first_of( CharT const * s, size_type pos = 0 ) const // (4)
707  {
708  return find_first_of( basic_string_view( s ), pos );
709  }
710 
711  // find_last_of(), 4x:
712 
713  nssv_constexpr size_type find_last_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1)
714  {
715  return pos >= size()
716  ? find_last_of( v, size() - 1 )
717  : to_pos( std::find_first_of( const_reverse_iterator( cbegin() + pos + 1 ), crend(), v.cbegin(), v.cend(), Traits::eq ) );
718  }
719 
720  nssv_constexpr size_type find_last_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2)
721  {
722  return find_last_of( basic_string_view( &c, 1 ), pos );
723  }
724 
725  nssv_constexpr size_type find_last_of( CharT const * s, size_type pos, size_type count ) const // (3)
726  {
727  return find_last_of( basic_string_view( s, count ), pos );
728  }
729 
730  nssv_constexpr size_type find_last_of( CharT const * s, size_type pos = npos ) const // (4)
731  {
732  return find_last_of( basic_string_view( s ), pos );
733  }
734 
735  // find_first_not_of(), 4x:
736 
737  nssv_constexpr size_type find_first_not_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
738  {
739  return pos >= size()
740  ? npos
741  : to_pos( std::find_if( cbegin() + pos, cend(), not_in_view( v ) ) );
742  }
743 
744  nssv_constexpr size_type find_first_not_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
745  {
746  return find_first_not_of( basic_string_view( &c, 1 ), pos );
747  }
748 
749  nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos, size_type count ) const // (3)
750  {
751  return find_first_not_of( basic_string_view( s, count ), pos );
752  }
753 
754  nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos = 0 ) const // (4)
755  {
756  return find_first_not_of( basic_string_view( s ), pos );
757  }
758 
759  // find_last_not_of(), 4x:
760 
761  nssv_constexpr size_type find_last_not_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1)
762  {
763  return pos >= size()
764  ? find_last_not_of( v, size() - 1 )
765  : to_pos( std::find_if( const_reverse_iterator( cbegin() + pos + 1 ), crend(), not_in_view( v ) ) );
766  }
767 
768  nssv_constexpr size_type find_last_not_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2)
769  {
770  return find_last_not_of( basic_string_view( &c, 1 ), pos );
771  }
772 
773  nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos, size_type count ) const // (3)
774  {
775  return find_last_not_of( basic_string_view( s, count ), pos );
776  }
777 
778  nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos = npos ) const // (4)
779  {
780  return find_last_not_of( basic_string_view( s ), pos );
781  }
782 
783  // Constants:
784 
785 #if nssv_CPP17_OR_GREATER
786  static nssv_constexpr size_type npos = size_type(-1);
787 #elif nssv_CPP11_OR_GREATER
788  enum : size_type { npos = size_type(-1) };
789 #else
790  enum { npos = size_type(-1) };
791 #endif
792 
793 private:
794  struct not_in_view
795  {
796  const basic_string_view v;
797 
798  nssv_constexpr not_in_view( basic_string_view v ) : v( v ) {}
799 
800  nssv_constexpr bool operator()( CharT c ) const
801  {
802  return npos == v.find_first_of( c );
803  }
804  };
805 
806  nssv_constexpr size_type to_pos( const_iterator it ) const
807  {
808  return it == cend() ? npos : size_type( it - cbegin() );
809  }
810 
811  nssv_constexpr size_type to_pos( const_reverse_iterator it ) const
812  {
813  return it == crend() ? npos : size_type( crend() - it - 1 );
814  }
815 
816  nssv_constexpr const_reference data_at( size_type pos ) const
817  {
818 #if nssv_BETWEEN( nssv_COMPILER_GNUC_VERSION, 1, 500 )
819  return data_[pos];
820 #else
821  return assert( pos < size() ), data_[pos];
822 #endif
823  }
824 
825 private:
826  const_pointer data_;
827  size_type size_;
828 
829 public:
830 #if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
831 
832  template< class Allocator >
833  basic_string_view( std::basic_string<CharT, Traits, Allocator> const & s ) nssv_noexcept
834  : data_( s.data() )
835  , size_( s.size() )
836  {}
837 
838 #if nssv_HAVE_EXPLICIT_CONVERSION
839 
840  template< class Allocator >
841  explicit operator std::basic_string<CharT, Traits, Allocator>() const
842  {
843  return to_string( Allocator() );
844  }
845 
846 #endif // nssv_HAVE_EXPLICIT_CONVERSION
847 
848 #if nssv_CPP11_OR_GREATER
849 
850  template< class Allocator = std::allocator<CharT> >
851  std::basic_string<CharT, Traits, Allocator>
852  to_string( Allocator const & a = Allocator() ) const
853  {
854  return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
855  }
856 
857 #else
858 
859  std::basic_string<CharT, Traits>
860  to_string() const
861  {
862  return std::basic_string<CharT, Traits>( begin(), end() );
863  }
864 
865  template< class Allocator >
866  std::basic_string<CharT, Traits, Allocator>
867  to_string( Allocator const & a ) const
868  {
869  return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
870  }
871 
872 #endif // nssv_CPP11_OR_GREATER
873 
874 #endif // nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
875 };
876 
877 //
878 // Non-member functions:
879 //
880 
881 // 24.4.3 Non-member comparison functions:
882 // lexicographically compare two string views (function template):
883 
884 template< class CharT, class Traits >
886  basic_string_view <CharT, Traits> lhs,
887  basic_string_view <CharT, Traits> rhs ) nssv_noexcept
888 { return lhs.compare( rhs ) == 0 ; }
889 
890 template< class CharT, class Traits >
892  basic_string_view <CharT, Traits> lhs,
893  basic_string_view <CharT, Traits> rhs ) nssv_noexcept
894 { return lhs.compare( rhs ) != 0 ; }
895 
896 template< class CharT, class Traits >
898  basic_string_view <CharT, Traits> lhs,
899  basic_string_view <CharT, Traits> rhs ) nssv_noexcept
900 { return lhs.compare( rhs ) < 0 ; }
901 
902 template< class CharT, class Traits >
904  basic_string_view <CharT, Traits> lhs,
905  basic_string_view <CharT, Traits> rhs ) nssv_noexcept
906 { return lhs.compare( rhs ) <= 0 ; }
907 
908 template< class CharT, class Traits >
910  basic_string_view <CharT, Traits> lhs,
911  basic_string_view <CharT, Traits> rhs ) nssv_noexcept
912 { return lhs.compare( rhs ) > 0 ; }
913 
914 template< class CharT, class Traits >
916  basic_string_view <CharT, Traits> lhs,
917  basic_string_view <CharT, Traits> rhs ) nssv_noexcept
918 { return lhs.compare( rhs ) >= 0 ; }
919 
920 // Let S be basic_string_view<CharT, Traits>, and sv be an instance of S.
921 // Implementations shall provide sufficient additional overloads marked
922 // constexpr and noexcept so that an object t with an implicit conversion
923 // to S can be compared according to Table 67.
924 
925 #if nssv_CPP11_OR_GREATER && ! nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 100, 141 )
926 
927 #define nssv_BASIC_STRING_VIEW_I(T,U) typename std::decay< basic_string_view<T,U> >::type
928 
929 #if nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 140, 150 )
930 # define nssv_MSVC_ORDER(x) , int=x
931 #else
932 # define nssv_MSVC_ORDER(x) /*, int=x*/
933 #endif
934 
935 // ==
936 
937 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
939  basic_string_view <CharT, Traits> lhs,
940  nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs ) nssv_noexcept
941 { return lhs.compare( rhs ) == 0; }
942 
943 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
945  nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
946  basic_string_view <CharT, Traits> rhs ) nssv_noexcept
947 { return lhs.compare( rhs ) == 0; }
948 
949 // !=
950 
951 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
953  basic_string_view < CharT, Traits > lhs,
954  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
955 { return lhs.compare( rhs ) != 0 ; }
956 
957 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
959  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
960  basic_string_view < CharT, Traits > rhs ) nssv_noexcept
961 { return lhs.compare( rhs ) != 0 ; }
962 
963 // <
964 
965 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
967  basic_string_view < CharT, Traits > lhs,
968  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
969 { return lhs.compare( rhs ) < 0 ; }
970 
971 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
973  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
974  basic_string_view < CharT, Traits > rhs ) nssv_noexcept
975 { return lhs.compare( rhs ) < 0 ; }
976 
977 // <=
978 
979 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
981  basic_string_view < CharT, Traits > lhs,
982  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
983 { return lhs.compare( rhs ) <= 0 ; }
984 
985 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
987  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
988  basic_string_view < CharT, Traits > rhs ) nssv_noexcept
989 { return lhs.compare( rhs ) <= 0 ; }
990 
991 // >
992 
993 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
995  basic_string_view < CharT, Traits > lhs,
996  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
997 { return lhs.compare( rhs ) > 0 ; }
998 
999 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
1001  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
1002  basic_string_view < CharT, Traits > rhs ) nssv_noexcept
1003 { return lhs.compare( rhs ) > 0 ; }
1004 
1005 // >=
1006 
1007 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
1009  basic_string_view < CharT, Traits > lhs,
1010  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
1011 { return lhs.compare( rhs ) >= 0 ; }
1012 
1013 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
1015  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
1016  basic_string_view < CharT, Traits > rhs ) nssv_noexcept
1017 { return lhs.compare( rhs ) >= 0 ; }
1018 
1019 #undef nssv_MSVC_ORDER
1020 #undef nssv_BASIC_STRING_VIEW_I
1021 
1022 #endif // nssv_CPP11_OR_GREATER
1023 
1024 // 24.4.4 Inserters and extractors:
1025 
1026 namespace detail {
1027 
1028 template< class Stream >
1029 void write_padding( Stream & os, std::streamsize n )
1030 {
1031  for ( std::streamsize i = 0; i < n; ++i )
1032  os.rdbuf()->sputc( os.fill() );
1033 }
1034 
1035 template< class Stream, class View >
1036 Stream & write_to_stream( Stream & os, View const & sv )
1037 {
1038  typename Stream::sentry sentry( os );
1039 
1040  if ( !os )
1041  return os;
1042 
1043  const std::streamsize length = static_cast<std::streamsize>( sv.length() );
1044 
1045  // Whether, and how, to pad:
1046  const bool pad = ( length < os.width() );
1047  const bool left_pad = pad && ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::right;
1048 
1049  if ( left_pad )
1050  write_padding( os, os.width() - length );
1051 
1052  // Write span characters:
1053  os.rdbuf()->sputn( sv.begin(), length );
1054 
1055  if ( pad && !left_pad )
1056  write_padding( os, os.width() - length );
1057 
1058  // Reset output stream width:
1059  os.width( 0 );
1060 
1061  return os;
1062 }
1063 
1064 } // namespace detail
1065 
1066 template< class CharT, class Traits >
1067 std::basic_ostream<CharT, Traits> &
1068 operator<<(
1069  std::basic_ostream<CharT, Traits>& os,
1070  basic_string_view <CharT, Traits> sv )
1071 {
1072  return detail::write_to_stream( os, sv );
1073 }
1074 
1075 // Several typedefs for common character types are provided:
1076 
1077 typedef basic_string_view<char> string_view;
1078 typedef basic_string_view<wchar_t> wstring_view;
1079 #if nssv_HAVE_WCHAR16_T
1080 typedef basic_string_view<char16_t> u16string_view;
1081 typedef basic_string_view<char32_t> u32string_view;
1082 #endif
1083 
1084 }} // namespace nonstd::sv_lite
1085 
1086 //
1087 // 24.4.6 Suffix for basic_string_view literals:
1088 //
1089 
1090 #if nssv_HAVE_USER_DEFINED_LITERALS
1091 
1092 namespace nonstd {
1093 nssv_inline_ns namespace literals {
1094 nssv_inline_ns namespace string_view_literals {
1095 
1096 #if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
1097 
1098 nssv_constexpr nonstd::sv_lite::string_view operator "" sv( const char* str, size_t len ) nssv_noexcept // (1)
1099 {
1100  return nonstd::sv_lite::string_view{ str, len };
1101 }
1102 
1103 nssv_constexpr nonstd::sv_lite::u16string_view operator "" sv( const char16_t* str, size_t len ) nssv_noexcept // (2)
1104 {
1105  return nonstd::sv_lite::u16string_view{ str, len };
1106 }
1107 
1108 nssv_constexpr nonstd::sv_lite::u32string_view operator "" sv( const char32_t* str, size_t len ) nssv_noexcept // (3)
1109 {
1110  return nonstd::sv_lite::u32string_view{ str, len };
1111 }
1112 
1113 nssv_constexpr nonstd::sv_lite::wstring_view operator "" sv( const wchar_t* str, size_t len ) nssv_noexcept // (4)
1114 {
1115  return nonstd::sv_lite::wstring_view{ str, len };
1116 }
1117 
1118 #endif // nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
1119 
1120 #if nssv_CONFIG_USR_SV_OPERATOR
1121 
1122 nssv_constexpr nonstd::sv_lite::string_view operator "" _sv( const char* str, size_t len ) nssv_noexcept // (1)
1123 {
1124  return nonstd::sv_lite::string_view{ str, len };
1125 }
1126 
1127 nssv_constexpr nonstd::sv_lite::u16string_view operator "" _sv( const char16_t* str, size_t len ) nssv_noexcept // (2)
1128 {
1129  return nonstd::sv_lite::u16string_view{ str, len };
1130 }
1131 
1132 nssv_constexpr nonstd::sv_lite::u32string_view operator "" _sv( const char32_t* str, size_t len ) nssv_noexcept // (3)
1133 {
1134  return nonstd::sv_lite::u32string_view{ str, len };
1135 }
1136 
1137 nssv_constexpr nonstd::sv_lite::wstring_view operator "" _sv( const wchar_t* str, size_t len ) nssv_noexcept // (4)
1138 {
1139  return nonstd::sv_lite::wstring_view{ str, len };
1140 }
1141 
1142 #endif // nssv_CONFIG_USR_SV_OPERATOR
1143 
1144 }}} // namespace nonstd::literals::string_view_literals
1145 
1146 #endif
1147 
1148 //
1149 // Extensions for std::string:
1150 //
1151 
1152 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1153 
1154 namespace nonstd {
1155 namespace sv_lite {
1156 
1157 // Exclude MSVC 14 (19.00): it yields ambiguous to_string():
1158 
1159 #if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140
1160 
1161 template< class CharT, class Traits, class Allocator = std::allocator<CharT> >
1162 std::basic_string<CharT, Traits, Allocator>
1163 to_string( basic_string_view<CharT, Traits> v, Allocator const & a = Allocator() )
1164 {
1165  return std::basic_string<CharT,Traits, Allocator>( v.begin(), v.end(), a );
1166 }
1167 
1168 #else
1169 
1170 template< class CharT, class Traits >
1171 std::basic_string<CharT, Traits>
1172 to_string( basic_string_view<CharT, Traits> v )
1173 {
1174  return std::basic_string<CharT, Traits>( v.begin(), v.end() );
1175 }
1176 
1177 template< class CharT, class Traits, class Allocator >
1178 std::basic_string<CharT, Traits, Allocator>
1179 to_string( basic_string_view<CharT, Traits> v, Allocator const & a )
1180 {
1181  return std::basic_string<CharT, Traits, Allocator>( v.begin(), v.end(), a );
1182 }
1183 
1184 #endif // nssv_CPP11_OR_GREATER
1185 
1186 template< class CharT, class Traits, class Allocator >
1187 basic_string_view<CharT, Traits>
1188 to_string_view( std::basic_string<CharT, Traits, Allocator> const & s )
1189 {
1190  return basic_string_view<CharT, Traits>( s.data(), s.size() );
1191 }
1192 
1193 }} // namespace nonstd::sv_lite
1194 
1195 #endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1196 
1197 //
1198 // make types and algorithms available in namespace nonstd:
1199 //
1200 
1201 namespace nonstd {
1202 
1203 using sv_lite::basic_string_view;
1204 using sv_lite::string_view;
1205 using sv_lite::wstring_view;
1206 
1207 #if nssv_HAVE_WCHAR16_T
1208 using sv_lite::u16string_view;
1209 #endif
1210 #if nssv_HAVE_WCHAR32_T
1211 using sv_lite::u32string_view;
1212 #endif
1213 
1214 // literal "sv"
1215 
1216 using sv_lite::operator==;
1217 using sv_lite::operator!=;
1218 using sv_lite::operator<;
1219 using sv_lite::operator<=;
1220 using sv_lite::operator>;
1221 using sv_lite::operator>=;
1222 
1223 using sv_lite::operator<<;
1224 
1225 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1226 using sv_lite::to_string;
1228 #endif
1229 
1230 } // namespace nonstd
1231 
1232 // 24.4.5 Hash support (C++11):
1233 
1234 // Note: The hash value of a string view object is equal to the hash value of
1235 // the corresponding string object.
1236 
1237 #if nssv_HAVE_STD_HASH
1238 
1239 #include <functional>
1240 
1241 namespace std {
1242 
1243 template<>
1244 struct hash< nonstd::string_view >
1245 {
1246 public:
1247  std::size_t operator()( nonstd::string_view v ) const nssv_noexcept
1248  {
1249  return std::hash<std::string>()( std::string( v.data(), v.size() ) );
1250  }
1251 };
1252 
1253 template<>
1254 struct hash< nonstd::wstring_view >
1255 {
1256 public:
1257  std::size_t operator()( nonstd::wstring_view v ) const nssv_noexcept
1258  {
1259  return std::hash<std::wstring>()( std::wstring( v.data(), v.size() ) );
1260  }
1261 };
1262 
1263 template<>
1264 struct hash< nonstd::u16string_view >
1265 {
1266 public:
1267  std::size_t operator()( nonstd::u16string_view v ) const nssv_noexcept
1268  {
1269  return std::hash<std::u16string>()( std::u16string( v.data(), v.size() ) );
1270  }
1271 };
1272 
1273 template<>
1274 struct hash< nonstd::u32string_view >
1275 {
1276 public:
1277  std::size_t operator()( nonstd::u32string_view v ) const nssv_noexcept
1278  {
1279  return std::hash<std::u32string>()( std::u32string( v.data(), v.size() ) );
1280  }
1281 };
1282 
1283 } // namespace std
1284 
1285 #endif // nssv_HAVE_STD_HASH
1286 
1288 
1289 #endif // nssv_HAVE_STD_STRING_VIEW
1290 #endif // NONSTD_SV_LITE_H_INCLUDED
1291 
optional_constexpr bool operator!=(optional< T > const &x, optional< U > const &y)
Definition: optional.hpp:960
const T * data(const std::vector< T, Alloc > &v)
Definition: flatbuffers.h:709
#define nssv_nullptr
Definition: any.hpp:455
void swap(linb::any &lhs, linb::any &rhs) noexcept
Definition: any.hpp:457
#define nssv_inline_ns
basic_string_view< CharT, Traits > to_string_view(std::basic_string< CharT, Traits, Allocator > const &s)
#define nssv_noexcept
optional_constexpr bool operator==(optional< T > const &x, optional< U > const &y)
Definition: optional.hpp:954
std::ostream & operator<<(std::ostream &os, const BT::NodeStatus &status)
optional_constexpr bool operator<=(optional< T > const &x, optional< U > const &y)
Definition: optional.hpp:978
#define nssv_constexpr
#define nssv_RESTORE_WARNINGS()
optional_constexpr bool operator<(optional< T > const &x, optional< U > const &y)
Definition: optional.hpp:966
optional_constexpr bool operator>=(optional< T > const &x, optional< U > const &y)
Definition: optional.hpp:984
#define nssv_constexpr14
static volatile int count
Definition: minitrace.cpp:55
#define nssv_DISABLE_MSVC_WARNINGS(codes)
std::basic_string< CharT, Traits, Allocator > to_string(basic_string_view< CharT, Traits > v, Allocator const &a)
std::basic_string< CharT, Traits > to_string(basic_string_view< CharT, Traits > v)
#define nssv_nodiscard
optional_constexpr bool operator>(optional< T > const &x, optional< U > const &y)
Definition: optional.hpp:972


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sun Feb 3 2019 03:14:32