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 empty()
716  ? npos
717  : pos >= size()
718  ? find_last_of( v, size() - 1 )
719  : to_pos( std::find_first_of( const_reverse_iterator( cbegin() + pos + 1 ), crend(), v.cbegin(), v.cend(), Traits::eq ) );
720  }
721 
722  nssv_constexpr size_type find_last_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2)
723  {
724  return find_last_of( basic_string_view( &c, 1 ), pos );
725  }
726 
727  nssv_constexpr size_type find_last_of( CharT const * s, size_type pos, size_type count ) const // (3)
728  {
729  return find_last_of( basic_string_view( s, count ), pos );
730  }
731 
732  nssv_constexpr size_type find_last_of( CharT const * s, size_type pos = npos ) const // (4)
733  {
734  return find_last_of( basic_string_view( s ), pos );
735  }
736 
737  // find_first_not_of(), 4x:
738 
739  nssv_constexpr size_type find_first_not_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
740  {
741  return pos >= size()
742  ? npos
743  : to_pos( std::find_if( cbegin() + pos, cend(), not_in_view( v ) ) );
744  }
745 
746  nssv_constexpr size_type find_first_not_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
747  {
748  return find_first_not_of( basic_string_view( &c, 1 ), pos );
749  }
750 
751  nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos, size_type count ) const // (3)
752  {
753  return find_first_not_of( basic_string_view( s, count ), pos );
754  }
755 
756  nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos = 0 ) const // (4)
757  {
758  return find_first_not_of( basic_string_view( s ), pos );
759  }
760 
761  // find_last_not_of(), 4x:
762 
763  nssv_constexpr size_type find_last_not_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1)
764  {
765  return empty()
766  ? npos
767  : pos >= size()
768  ? find_last_not_of( v, size() - 1 )
769  : to_pos( std::find_if( const_reverse_iterator( cbegin() + pos + 1 ), crend(), not_in_view( v ) ) );
770  }
771 
772  nssv_constexpr size_type find_last_not_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2)
773  {
774  return find_last_not_of( basic_string_view( &c, 1 ), pos );
775  }
776 
777  nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos, size_type count ) const // (3)
778  {
779  return find_last_not_of( basic_string_view( s, count ), pos );
780  }
781 
782  nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos = npos ) const // (4)
783  {
784  return find_last_not_of( basic_string_view( s ), pos );
785  }
786 
787  // Constants:
788 
789 #if nssv_CPP17_OR_GREATER
790  static nssv_constexpr size_type npos = size_type(-1);
791 #elif nssv_CPP11_OR_GREATER
792  enum : size_type { npos = size_type(-1) };
793 #else
794  enum { npos = size_type(-1) };
795 #endif
796 
797 private:
798  struct not_in_view
799  {
800  const basic_string_view v;
801 
802  nssv_constexpr not_in_view( basic_string_view v ) : v( v ) {}
803 
804  nssv_constexpr bool operator()( CharT c ) const
805  {
806  return npos == v.find_first_of( c );
807  }
808  };
809 
810  nssv_constexpr size_type to_pos( const_iterator it ) const
811  {
812  return it == cend() ? npos : size_type( it - cbegin() );
813  }
814 
815  nssv_constexpr size_type to_pos( const_reverse_iterator it ) const
816  {
817  return it == crend() ? npos : size_type( crend() - it - 1 );
818  }
819 
820  nssv_constexpr const_reference data_at( size_type pos ) const
821  {
822 #if nssv_BETWEEN( nssv_COMPILER_GNUC_VERSION, 1, 500 )
823  return data_[pos];
824 #else
825  return assert( pos < size() ), data_[pos];
826 #endif
827  }
828 
829 private:
830  const_pointer data_;
831  size_type size_;
832 
833 public:
834 #if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
835 
836  template< class Allocator >
837  basic_string_view( std::basic_string<CharT, Traits, Allocator> const & s ) nssv_noexcept
838  : data_( s.data() )
839  , size_( s.size() )
840  {}
841 
842 #if nssv_HAVE_EXPLICIT_CONVERSION
843 
844  template< class Allocator >
845  explicit operator std::basic_string<CharT, Traits, Allocator>() const
846  {
847  return to_string( Allocator() );
848  }
849 
850 #endif // nssv_HAVE_EXPLICIT_CONVERSION
851 
852 #if nssv_CPP11_OR_GREATER
853 
854  template< class Allocator = std::allocator<CharT> >
855  std::basic_string<CharT, Traits, Allocator>
856  to_string( Allocator const & a = Allocator() ) const
857  {
858  return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
859  }
860 
861 #else
862 
863  std::basic_string<CharT, Traits>
864  to_string() const
865  {
866  return std::basic_string<CharT, Traits>( begin(), end() );
867  }
868 
869  template< class Allocator >
870  std::basic_string<CharT, Traits, Allocator>
871  to_string( Allocator const & a ) const
872  {
873  return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
874  }
875 
876 #endif // nssv_CPP11_OR_GREATER
877 
878 #endif // nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
879 };
880 
881 //
882 // Non-member functions:
883 //
884 
885 // 24.4.3 Non-member comparison functions:
886 // lexicographically compare two string views (function template):
887 
888 template< class CharT, class Traits >
889 nssv_constexpr bool operator== (
890  basic_string_view <CharT, Traits> lhs,
891  basic_string_view <CharT, Traits> rhs ) nssv_noexcept
892 { return lhs.compare( rhs ) == 0 ; }
893 
894 template< class CharT, class Traits >
895 nssv_constexpr bool operator!= (
896  basic_string_view <CharT, Traits> lhs,
897  basic_string_view <CharT, Traits> rhs ) nssv_noexcept
898 { return lhs.compare( rhs ) != 0 ; }
899 
900 template< class CharT, class Traits >
901 nssv_constexpr bool operator< (
902  basic_string_view <CharT, Traits> lhs,
903  basic_string_view <CharT, Traits> rhs ) nssv_noexcept
904 { return lhs.compare( rhs ) < 0 ; }
905 
906 template< class CharT, class Traits >
907 nssv_constexpr bool operator<= (
908  basic_string_view <CharT, Traits> lhs,
909  basic_string_view <CharT, Traits> rhs ) nssv_noexcept
910 { return lhs.compare( rhs ) <= 0 ; }
911 
912 template< class CharT, class Traits >
913 nssv_constexpr bool operator> (
914  basic_string_view <CharT, Traits> lhs,
915  basic_string_view <CharT, Traits> rhs ) nssv_noexcept
916 { return lhs.compare( rhs ) > 0 ; }
917 
918 template< class CharT, class Traits >
919 nssv_constexpr bool operator>= (
920  basic_string_view <CharT, Traits> lhs,
921  basic_string_view <CharT, Traits> rhs ) nssv_noexcept
922 { return lhs.compare( rhs ) >= 0 ; }
923 
924 // Let S be basic_string_view<CharT, Traits>, and sv be an instance of S.
925 // Implementations shall provide sufficient additional overloads marked
926 // constexpr and noexcept so that an object t with an implicit conversion
927 // to S can be compared according to Table 67.
928 
929 #if nssv_CPP11_OR_GREATER && ! nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 100, 141 )
930 
931 #define nssv_BASIC_STRING_VIEW_I(T,U) typename std::decay< basic_string_view<T,U> >::type
932 
933 #if nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 140, 150 )
934 # define nssv_MSVC_ORDER(x) , int=x
935 #else
936 # define nssv_MSVC_ORDER(x) /*, int=x*/
937 #endif
938 
939 // ==
940 
941 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
942 nssv_constexpr bool operator==(
943  basic_string_view <CharT, Traits> lhs,
944  nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs ) nssv_noexcept
945 { return lhs.compare( rhs ) == 0; }
946 
947 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
948 nssv_constexpr bool operator==(
949  nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
950  basic_string_view <CharT, Traits> rhs ) nssv_noexcept
951 { return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
952 
953 // !=
954 
955 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
956 nssv_constexpr bool operator!= (
957  basic_string_view < CharT, Traits > lhs,
958  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
959 { return lhs.size() != rhs.size() || lhs.compare( rhs ) != 0 ; }
960 
961 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
962 nssv_constexpr bool operator!= (
963  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
964  basic_string_view < CharT, Traits > rhs ) nssv_noexcept
965 { return lhs.compare( rhs ) != 0 ; }
966 
967 // <
968 
969 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
970 nssv_constexpr bool operator< (
971  basic_string_view < CharT, Traits > lhs,
972  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
973 { return lhs.compare( rhs ) < 0 ; }
974 
975 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
976 nssv_constexpr bool operator< (
977  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
978  basic_string_view < CharT, Traits > rhs ) nssv_noexcept
979 { return lhs.compare( rhs ) < 0 ; }
980 
981 // <=
982 
983 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
984 nssv_constexpr bool operator<= (
985  basic_string_view < CharT, Traits > lhs,
986  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
987 { return lhs.compare( rhs ) <= 0 ; }
988 
989 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
990 nssv_constexpr bool operator<= (
991  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
992  basic_string_view < CharT, Traits > rhs ) nssv_noexcept
993 { return lhs.compare( rhs ) <= 0 ; }
994 
995 // >
996 
997 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
998 nssv_constexpr bool operator> (
999  basic_string_view < CharT, Traits > lhs,
1000  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
1001 { return lhs.compare( rhs ) > 0 ; }
1002 
1003 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
1004 nssv_constexpr bool operator> (
1005  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
1006  basic_string_view < CharT, Traits > rhs ) nssv_noexcept
1007 { return lhs.compare( rhs ) > 0 ; }
1008 
1009 // >=
1010 
1011 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
1012 nssv_constexpr bool operator>= (
1013  basic_string_view < CharT, Traits > lhs,
1014  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
1015 { return lhs.compare( rhs ) >= 0 ; }
1016 
1017 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
1018 nssv_constexpr bool operator>= (
1019  nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
1020  basic_string_view < CharT, Traits > rhs ) nssv_noexcept
1021 { return lhs.compare( rhs ) >= 0 ; }
1022 
1023 #undef nssv_MSVC_ORDER
1024 #undef nssv_BASIC_STRING_VIEW_I
1025 
1026 #endif // nssv_CPP11_OR_GREATER
1027 
1028 // 24.4.4 Inserters and extractors:
1029 
1030 namespace detail {
1031 
1032 template< class Stream >
1033 void write_padding( Stream & os, std::streamsize n )
1034 {
1035  for ( std::streamsize i = 0; i < n; ++i )
1036  os.rdbuf()->sputc( os.fill() );
1037 }
1038 
1039 template< class Stream, class View >
1040 Stream & write_to_stream( Stream & os, View const & sv )
1041 {
1042  typename Stream::sentry sentry( os );
1043 
1044  if ( !os )
1045  return os;
1046 
1047  const std::streamsize length = static_cast<std::streamsize>( sv.length() );
1048 
1049  // Whether, and how, to pad:
1050  const bool pad = ( length < os.width() );
1051  const bool left_pad = pad && ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::right;
1052 
1053  if ( left_pad )
1054  write_padding( os, os.width() - length );
1055 
1056  // Write span characters:
1057  os.rdbuf()->sputn( sv.begin(), length );
1058 
1059  if ( pad && !left_pad )
1060  write_padding( os, os.width() - length );
1061 
1062  // Reset output stream width:
1063  os.width( 0 );
1064 
1065  return os;
1066 }
1067 
1068 } // namespace detail
1069 
1070 template< class CharT, class Traits >
1071 std::basic_ostream<CharT, Traits> &
1072 operator<<(
1073  std::basic_ostream<CharT, Traits>& os,
1074  basic_string_view <CharT, Traits> sv )
1075 {
1076  return detail::write_to_stream( os, sv );
1077 }
1078 
1079 // Several typedefs for common character types are provided:
1080 
1081 typedef basic_string_view<char> string_view;
1082 typedef basic_string_view<wchar_t> wstring_view;
1083 #if nssv_HAVE_WCHAR16_T
1084 typedef basic_string_view<char16_t> u16string_view;
1085 typedef basic_string_view<char32_t> u32string_view;
1086 #endif
1087 
1088 }} // namespace nonstd::sv_lite
1089 
1090 //
1091 // 24.4.6 Suffix for basic_string_view literals:
1092 //
1093 
1094 #if nssv_HAVE_USER_DEFINED_LITERALS
1095 
1096 namespace nonstd {
1097 nssv_inline_ns namespace literals {
1098 nssv_inline_ns namespace string_view_literals {
1099 
1100 #if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
1101 
1102 nssv_constexpr nonstd::sv_lite::string_view operator "" sv( const char* str, size_t len ) nssv_noexcept // (1)
1103 {
1104  return nonstd::sv_lite::string_view{ str, len };
1105 }
1106 
1107 nssv_constexpr nonstd::sv_lite::u16string_view operator "" sv( const char16_t* str, size_t len ) nssv_noexcept // (2)
1108 {
1109  return nonstd::sv_lite::u16string_view{ str, len };
1110 }
1111 
1112 nssv_constexpr nonstd::sv_lite::u32string_view operator "" sv( const char32_t* str, size_t len ) nssv_noexcept // (3)
1113 {
1114  return nonstd::sv_lite::u32string_view{ str, len };
1115 }
1116 
1117 nssv_constexpr nonstd::sv_lite::wstring_view operator "" sv( const wchar_t* str, size_t len ) nssv_noexcept // (4)
1118 {
1119  return nonstd::sv_lite::wstring_view{ str, len };
1120 }
1121 
1122 #endif // nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
1123 
1124 #if nssv_CONFIG_USR_SV_OPERATOR
1125 
1126 nssv_constexpr nonstd::sv_lite::string_view operator "" _sv( const char* str, size_t len ) nssv_noexcept // (1)
1127 {
1128  return nonstd::sv_lite::string_view{ str, len };
1129 }
1130 
1131 nssv_constexpr nonstd::sv_lite::u16string_view operator "" _sv( const char16_t* str, size_t len ) nssv_noexcept // (2)
1132 {
1133  return nonstd::sv_lite::u16string_view{ str, len };
1134 }
1135 
1136 nssv_constexpr nonstd::sv_lite::u32string_view operator "" _sv( const char32_t* str, size_t len ) nssv_noexcept // (3)
1137 {
1138  return nonstd::sv_lite::u32string_view{ str, len };
1139 }
1140 
1141 nssv_constexpr nonstd::sv_lite::wstring_view operator "" _sv( const wchar_t* str, size_t len ) nssv_noexcept // (4)
1142 {
1143  return nonstd::sv_lite::wstring_view{ str, len };
1144 }
1145 
1146 #endif // nssv_CONFIG_USR_SV_OPERATOR
1147 
1148 }}} // namespace nonstd::literals::string_view_literals
1149 
1150 #endif
1151 
1152 //
1153 // Extensions for std::string:
1154 //
1155 
1156 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1157 
1158 namespace nonstd {
1159 namespace sv_lite {
1160 
1161 // Exclude MSVC 14 (19.00): it yields ambiguous to_string():
1162 
1163 #if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140
1164 
1165 template< class CharT, class Traits, class Allocator = std::allocator<CharT> >
1166 std::basic_string<CharT, Traits, Allocator>
1167 to_string( basic_string_view<CharT, Traits> v, Allocator const & a = Allocator() )
1168 {
1169  return std::basic_string<CharT,Traits, Allocator>( v.begin(), v.end(), a );
1170 }
1171 
1172 #else
1173 
1174 template< class CharT, class Traits >
1175 std::basic_string<CharT, Traits>
1176 to_string( basic_string_view<CharT, Traits> v )
1177 {
1178  return std::basic_string<CharT, Traits>( v.begin(), v.end() );
1179 }
1180 
1181 template< class CharT, class Traits, class Allocator >
1182 std::basic_string<CharT, Traits, Allocator>
1183 to_string( basic_string_view<CharT, Traits> v, Allocator const & a )
1184 {
1185  return std::basic_string<CharT, Traits, Allocator>( v.begin(), v.end(), a );
1186 }
1187 
1188 #endif // nssv_CPP11_OR_GREATER
1189 
1190 template< class CharT, class Traits, class Allocator >
1191 basic_string_view<CharT, Traits>
1192 to_string_view( std::basic_string<CharT, Traits, Allocator> const & s )
1193 {
1194  return basic_string_view<CharT, Traits>( s.data(), s.size() );
1195 }
1196 
1197 }} // namespace nonstd::sv_lite
1198 
1199 #endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1200 
1201 //
1202 // make types and algorithms available in namespace nonstd:
1203 //
1204 
1205 namespace nonstd {
1206 
1207 using sv_lite::basic_string_view;
1208 using sv_lite::string_view;
1209 using sv_lite::wstring_view;
1210 
1211 #if nssv_HAVE_WCHAR16_T
1212 using sv_lite::u16string_view;
1213 #endif
1214 #if nssv_HAVE_WCHAR32_T
1215 using sv_lite::u32string_view;
1216 #endif
1217 
1218 // literal "sv"
1219 
1220 using sv_lite::operator==;
1221 using sv_lite::operator!=;
1222 using sv_lite::operator<;
1223 using sv_lite::operator<=;
1224 using sv_lite::operator>;
1225 using sv_lite::operator>=;
1226 
1227 using sv_lite::operator<<;
1228 
1229 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1230 using sv_lite::to_string;
1232 #endif
1233 
1234 } // namespace nonstd
1235 
1236 // 24.4.5 Hash support (C++11):
1237 
1238 // Note: The hash value of a string view object is equal to the hash value of
1239 // the corresponding string object.
1240 
1241 #if nssv_HAVE_STD_HASH
1242 
1243 #include <functional>
1244 
1245 namespace std {
1246 
1247 template<>
1248 struct hash< nonstd::string_view >
1249 {
1250 public:
1251  std::size_t operator()( nonstd::string_view v ) const nssv_noexcept
1252  {
1253  return std::hash<std::string>()( std::string( v.data(), v.size() ) );
1254  }
1255 };
1256 
1257 template<>
1258 struct hash< nonstd::wstring_view >
1259 {
1260 public:
1261  std::size_t operator()( nonstd::wstring_view v ) const nssv_noexcept
1262  {
1263  return std::hash<std::wstring>()( std::wstring( v.data(), v.size() ) );
1264  }
1265 };
1266 
1267 template<>
1268 struct hash< nonstd::u16string_view >
1269 {
1270 public:
1271  std::size_t operator()( nonstd::u16string_view v ) const nssv_noexcept
1272  {
1273  return std::hash<std::u16string>()( std::u16string( v.data(), v.size() ) );
1274  }
1275 };
1276 
1277 template<>
1278 struct hash< nonstd::u32string_view >
1279 {
1280 public:
1281  std::size_t operator()( nonstd::u32string_view v ) const nssv_noexcept
1282  {
1283  return std::hash<std::u32string>()( std::u32string( v.data(), v.size() ) );
1284  }
1285 };
1286 
1287 } // namespace std
1288 
1289 #endif // nssv_HAVE_STD_HASH
1290 
1292 
1293 #endif // nssv_HAVE_STD_STRING_VIEW
1294 #endif // NONSTD_SV_LITE_H_INCLUDED
#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
std::ostream & operator<<(std::ostream &os, const BT::NodeStatus &status)
#define nssv_constexpr
#define nssv_RESTORE_WARNINGS()
const T * data(const std::vector< T, Alloc > &v)
const char * str
Definition: util.h:257
#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


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sat Jun 8 2019 18:04:05