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