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