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


behaviotree_cpp_v3
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Tue May 4 2021 02:56:25