Remove unused function generate_excls and make clean_excls static
[gromacs.git] / src / gromacs / compat / string_view.h
blob07396d3483d37eb75854250f38cc1844cae1c85f
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2019, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
35 // Copyright 2017-2019 by Martin Moene
37 // string-view lite, a C++17-like string_view for C++98 and later.
38 // For more information see https://github.com/martinmoene/string-view-lite
40 // Distributed under the Boost Software License, Version 1.0.
41 // (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
43 /*! \file
44 * \brief Provides C++14-compatible implementation of std::string_view.
46 * This implementation is nearly identical to the reference
47 * implementation at commit bf5824916b6895ccab0dbc2431520ee3b6d4f27f of
48 * https://github.com/martinmoene/string_view-lite.git. The code has not
49 * been linted with uncrustify so that any future updates to this
50 * active repo can be incorporated easily, and //NOLINT comments and
51 * braces around if-expressions added to suppress clang-tidy
52 * warnings. Comments referring to GMX note those places where a
53 * change has been made. The form of those changes have been made to
54 * simplify the contents, while making it easy to import any bug fixes
55 * that may appear in the source repository.
57 * There is no Doxygen for this code, but it is intended to conform to
58 * that of std::string_view, so look in the usual C++17 documentation for
59 * std::string_view for that.
61 * \todo Remove when requiring C++17, which has a standardized version
62 * of std::string_view.
64 * \author Paul Bauer <paul.bauer.q@gmail.com>
65 * \ingroup module_compat
66 * \inpublicapi
68 // GMX Make include guard conform to GROMACS standards.
69 #ifndef GMX_COMPAT_STRINGVIEW_H
70 #define GMX_COMPAT_STRINGVIEW_H
72 // GMX modification to suppress Doxygen checking
73 #ifndef DOXYGEN
75 #define string_view_lite_MAJOR 1
76 #define string_view_lite_MINOR 1
77 #define string_view_lite_PATCH 0
79 #define string_view_lite_VERSION nssv_STRINGIFY(string_view_lite_MAJOR) "." nssv_STRINGIFY(string_view_lite_MINOR) "." nssv_STRINGIFY(string_view_lite_PATCH)
81 #define nssv_STRINGIFY( x ) nssv_STRINGIFY_( x )
82 #define nssv_STRINGIFY_( x ) #x
84 // string-view lite configuration:
86 #define nssv_STRING_VIEW_DEFAULT 0
87 #define nssv_STRING_VIEW_NONSTD 1
88 #define nssv_STRING_VIEW_STD 2
90 #if !defined( nssv_CONFIG_SELECT_STRING_VIEW )
91 # define nssv_CONFIG_SELECT_STRING_VIEW ( nssv_HAVE_STD_STRING_VIEW ? nssv_STRING_VIEW_STD : nssv_STRING_VIEW_NONSTD )
92 #endif
94 #if defined( nssv_CONFIG_SELECT_STD_STRING_VIEW ) || defined( nssv_CONFIG_SELECT_NONSTD_STRING_VIEW )
95 # 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_...
96 #endif
98 #ifndef nssv_CONFIG_STD_SV_OPERATOR
99 # define nssv_CONFIG_STD_SV_OPERATOR 0
100 #endif
102 #ifndef nssv_CONFIG_USR_SV_OPERATOR
103 # define nssv_CONFIG_USR_SV_OPERATOR 1
104 #endif
106 #ifdef nssv_CONFIG_CONVERSION_STD_STRING
107 # define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS nssv_CONFIG_CONVERSION_STD_STRING
108 # define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS nssv_CONFIG_CONVERSION_STD_STRING
109 #endif
111 #ifndef nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
112 # define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS 1
113 #endif
115 #ifndef nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
116 # define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS 1
117 #endif
119 // Control presence of exception handling (try and auto discover):
121 #ifndef nssv_CONFIG_NO_EXCEPTIONS
122 # if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
123 # define nssv_CONFIG_NO_EXCEPTIONS 0
124 # else
125 # define nssv_CONFIG_NO_EXCEPTIONS 1
126 # endif
127 #endif
129 // C++ language version detection (C++20 is speculative):
130 // Note: VC14.0/1900 (VS2015) lacks too much from C++14.
132 #ifndef nssv_CPLUSPLUS
133 # if defined(_MSVC_LANG ) && !defined(__clang__)
134 # define nssv_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
135 # else
136 # define nssv_CPLUSPLUS __cplusplus
137 # endif
138 #endif
140 #define nssv_CPP98_OR_GREATER ( nssv_CPLUSPLUS >= 199711L )
141 #define nssv_CPP11_OR_GREATER ( nssv_CPLUSPLUS >= 201103L )
142 #define nssv_CPP11_OR_GREATER_ ( nssv_CPLUSPLUS >= 201103L )
143 #define nssv_CPP14_OR_GREATER ( nssv_CPLUSPLUS >= 201402L )
144 #define nssv_CPP17_OR_GREATER ( nssv_CPLUSPLUS >= 201703L )
145 #define nssv_CPP20_OR_GREATER ( nssv_CPLUSPLUS >= 202000L )
147 // use C++17 std::string_view if available and requested:
149 #if nssv_CPP17_OR_GREATER && defined(__has_include )
150 # if __has_include( <string_view> )
151 # define nssv_HAVE_STD_STRING_VIEW 1
152 # else
153 # define nssv_HAVE_STD_STRING_VIEW 0
154 # endif
155 #else
156 # define nssv_HAVE_STD_STRING_VIEW 0
157 #endif
159 #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) )
161 #define nssv_HAVE_STARTS_WITH ( nssv_CPP20_OR_GREATER || !nssv_USES_STD_STRING_VIEW )
162 #define nssv_HAVE_ENDS_WITH nssv_HAVE_STARTS_WITH
165 // Use C++17 std::string_view:
168 #if nssv_USES_STD_STRING_VIEW
170 #include <string_view>
172 // Extensions for std::string:
174 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
176 namespace nonstd {
178 template< class CharT, class Traits, class Allocator = std::allocator<CharT> >
179 std::basic_string<CharT, Traits, Allocator>
180 to_string( std::basic_string_view<CharT, Traits> v, Allocator const & a = Allocator() )
182 return std::basic_string<CharT,Traits, Allocator>( v.begin(), v.end(), a );
185 template< class CharT, class Traits, class Allocator >
186 std::basic_string_view<CharT, Traits>
187 to_string_view( std::basic_string<CharT, Traits, Allocator> const & s )
189 return std::basic_string_view<CharT, Traits>( s.data(), s.size() );
192 // Literal operators sv and _sv:
194 #if nssv_CONFIG_STD_SV_OPERATOR
196 using namespace std::literals::string_view_literals;
198 #endif
200 #if nssv_CONFIG_USR_SV_OPERATOR
202 inline namespace literals {
203 inline namespace string_view_literals {
206 constexpr std::string_view operator "" _sv( const char* str, size_t len ) noexcept // (1)
208 return std::string_view{ str, len };
211 constexpr std::u16string_view operator "" _sv( const char16_t* str, size_t len ) noexcept // (2)
213 return std::u16string_view{ str, len };
216 constexpr std::u32string_view operator "" _sv( const char32_t* str, size_t len ) noexcept // (3)
218 return std::u32string_view{ str, len };
221 constexpr std::wstring_view operator "" _sv( const wchar_t* str, size_t len ) noexcept // (4)
223 return std::wstring_view{ str, len };
226 }} // namespace literals::string_view_literals
228 #endif // nssv_CONFIG_USR_SV_OPERATOR
230 } // namespace nonstd
232 #endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
234 namespace nonstd {
236 using std::string_view;
237 using std::wstring_view;
238 using std::u16string_view;
239 using std::u32string_view;
240 using std::basic_string_view;
242 // literal "sv" and "_sv", see above
244 using std::operator==;
245 using std::operator!=;
246 using std::operator<;
247 using std::operator<=;
248 using std::operator>;
249 using std::operator>=;
251 using std::operator<<;
253 } // namespace nonstd
255 #else // nssv_HAVE_STD_STRING_VIEW
258 // Before C++17: use string_view lite:
261 // Compiler versions:
263 // MSVC++ 6.0 _MSC_VER == 1200 (Visual Studio 6.0)
264 // MSVC++ 7.0 _MSC_VER == 1300 (Visual Studio .NET 2002)
265 // MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio .NET 2003)
266 // MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
267 // MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
268 // MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
269 // MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
270 // MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
271 // MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
272 // MSVC++ 14.1 _MSC_VER >= 1910 (Visual Studio 2017)
274 #if defined(_MSC_VER ) && !defined(__clang__)
275 # define nssv_COMPILER_MSVC_VER (_MSC_VER )
276 # define nssv_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
277 #else
278 # define nssv_COMPILER_MSVC_VER 0
279 # define nssv_COMPILER_MSVC_VERSION 0
280 #endif
282 #define nssv_COMPILER_VERSION( major, minor, patch ) (10 * ( 10 * (major) + (minor)) + (patch))
284 #if defined(__clang__)
285 # define nssv_COMPILER_CLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
286 #else
287 # define nssv_COMPILER_CLANG_VERSION 0
288 #endif
290 #if defined(__GNUC__) && !defined(__clang__)
291 # define nssv_COMPILER_GNUC_VERSION nssv_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
292 #else
293 # define nssv_COMPILER_GNUC_VERSION 0
294 #endif
296 // half-open range [lo..hi):
297 #define nssv_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
299 // Presence of language and library features:
301 #ifdef _HAS_CPP0X
302 # define nssv_HAS_CPP0X _HAS_CPP0X
303 #else
304 # define nssv_HAS_CPP0X 0
305 #endif
307 // Unless defined otherwise below, consider VC14 as C++11 for variant-lite:
309 #if nssv_COMPILER_MSVC_VER >= 1900
310 # undef nssv_CPP11_OR_GREATER
311 # define nssv_CPP11_OR_GREATER 1
312 #endif
314 #define nssv_CPP11_90 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1500)
315 #define nssv_CPP11_100 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1600)
316 #define nssv_CPP11_110 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1700)
317 #define nssv_CPP11_120 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1800)
318 #define nssv_CPP11_140 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1900)
319 #define nssv_CPP11_141 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1910)
321 #define nssv_CPP14_000 (nssv_CPP14_OR_GREATER)
322 #define nssv_CPP17_000 (nssv_CPP17_OR_GREATER)
324 // Presence of C++11 language features:
326 #define nssv_HAVE_CONSTEXPR_11 nssv_CPP11_140
327 #define nssv_HAVE_EXPLICIT_CONVERSION nssv_CPP11_140
328 #define nssv_HAVE_INLINE_NAMESPACE nssv_CPP11_140
329 #define nssv_HAVE_NOEXCEPT nssv_CPP11_140
330 #define nssv_HAVE_NULLPTR nssv_CPP11_100
331 #define nssv_HAVE_REF_QUALIFIER nssv_CPP11_140
332 #define nssv_HAVE_UNICODE_LITERALS nssv_CPP11_140
333 #define nssv_HAVE_USER_DEFINED_LITERALS nssv_CPP11_140
334 #define nssv_HAVE_WCHAR16_T nssv_CPP11_100
335 #define nssv_HAVE_WCHAR32_T nssv_CPP11_100
337 // GMX fixed definitions
338 #if ! ( ( nssv_CPP11_OR_GREATER && nssv_COMPILER_CLANG_VERSION ) || nssv_BETWEEN( nssv_COMPILER_CLANG_VERSION, 300, 400 ) )
339 # define nssv_HAVE_STD_DEFINED_LITERALS nssv_CPP11_140
340 #endif
342 // Presence of C++14 language features:
344 #define nssv_HAVE_CONSTEXPR_14 nssv_CPP14_000
346 // Presence of C++17 language features:
348 #define nssv_HAVE_NODISCARD nssv_CPP17_000
350 // Presence of C++ library features:
352 #define nssv_HAVE_STD_HASH nssv_CPP11_120
354 // C++ feature usage:
356 #if nssv_HAVE_CONSTEXPR_11
357 # define nssv_constexpr constexpr
358 #else
359 # define nssv_constexpr /*constexpr*/
360 #endif
362 #if nssv_HAVE_CONSTEXPR_14
363 # define nssv_constexpr14 constexpr
364 #else
365 # define nssv_constexpr14 /*constexpr*/
366 #endif
368 #if nssv_HAVE_EXPLICIT_CONVERSION
369 # define nssv_explicit explicit
370 #else
371 # define nssv_explicit /*explicit*/
372 #endif
374 #if nssv_HAVE_INLINE_NAMESPACE
375 # define nssv_inline_ns inline
376 #else
377 # define nssv_inline_ns /*inline*/
378 #endif
380 #if nssv_HAVE_NOEXCEPT
381 # define nssv_noexcept noexcept
382 #else
383 # define nssv_noexcept /*noexcept*/
384 #endif
386 //#if nssv_HAVE_REF_QUALIFIER
387 //# define nssv_ref_qual &
388 //# define nssv_refref_qual &&
389 //#else
390 //# define nssv_ref_qual /*&*/
391 //# define nssv_refref_qual /*&&*/
392 //#endif
394 #if nssv_HAVE_NULLPTR
395 # define nssv_nullptr nullptr
396 #else
397 # define nssv_nullptr NULL
398 #endif
400 #if nssv_HAVE_NODISCARD
401 # define nssv_nodiscard [[nodiscard]]
402 #else
403 # define nssv_nodiscard /*[[nodiscard]]*/
404 #endif
406 // Additional includes:
408 #include <algorithm>
409 #include <cassert>
410 #include <iterator>
411 #include <limits>
412 #include <ostream>
413 #include <string> // std::char_traits<>
415 #if ! nssv_CONFIG_NO_EXCEPTIONS
416 # include <stdexcept>
417 #endif
419 #if nssv_CPP11_OR_GREATER
420 # include <type_traits>
421 #endif
423 // Clang, GNUC, MSVC warning suppression macros:
425 #if defined(__clang__)
426 # pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
427 # pragma clang diagnostic push
428 # pragma clang diagnostic ignored "-Wuser-defined-literals"
429 #elif defined(__GNUC__)
430 # pragma GCC diagnostic push
431 # pragma GCC diagnostic ignored "-Wliteral-suffix"
432 #endif // __clang__
434 #if nssv_COMPILER_MSVC_VERSION >= 140
435 # define nssv_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]]
436 # define nssv_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress: code) )
437 # define nssv_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable: codes))
438 #else
439 # define nssv_SUPPRESS_MSGSL_WARNING(expr)
440 # define nssv_SUPPRESS_MSVC_WARNING(code, descr)
441 # define nssv_DISABLE_MSVC_WARNINGS(codes)
442 #endif
444 #if defined(__clang__)
445 # define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
446 #elif defined(__GNUC__)
447 # define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
448 #elif nssv_COMPILER_MSVC_VERSION >= 140
449 # define nssv_RESTORE_WARNINGS() __pragma(warning(pop ))
450 #else
451 # define nssv_RESTORE_WARNINGS()
452 #endif
454 // Suppress the following MSVC (GSL) warnings:
455 // - C4455, non-gsl : 'operator ""sv': literal suffix identifiers that do not
456 // start with an underscore are reserved
457 // - C26472, gsl::t.1 : don't use a static_cast for arithmetic conversions;
458 // use brace initialization, gsl::narrow_cast or gsl::narow
459 // - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead
461 nssv_DISABLE_MSVC_WARNINGS( 4455 26481 26472 )
462 //nssv_DISABLE_CLANG_WARNINGS( "-Wuser-defined-literals" )
463 //nssv_DISABLE_GNUC_WARNINGS( -Wliteral-suffix )
465 namespace nonstd { namespace sv_lite {
467 template
469 class CharT,
470 class Traits = std::char_traits<CharT>
472 class basic_string_view;
475 // basic_string_view:
478 template
480 class CharT,
481 class Traits /* = std::char_traits<CharT> */
483 class basic_string_view
485 public:
486 // Member types:
488 typedef Traits traits_type;
489 typedef CharT value_type;
491 typedef CharT * pointer;
492 typedef CharT const * const_pointer;
493 typedef CharT & reference;
494 typedef CharT const & const_reference;
496 typedef const_pointer iterator;
497 typedef const_pointer const_iterator;
498 typedef std::reverse_iterator< const_iterator > reverse_iterator;
499 typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
501 typedef std::size_t size_type;
502 typedef std::ptrdiff_t difference_type;
504 // 24.4.2.1 Construction and assignment:
506 nssv_constexpr basic_string_view() nssv_noexcept
507 : data_( nssv_nullptr )
508 , size_( 0 )
511 #if nssv_CPP11_OR_GREATER
512 nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept = default;
513 #else
514 nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept
515 : data_( other.data_)
516 , size_( other.size_)
518 #endif
520 nssv_constexpr basic_string_view( CharT const * s, size_type count )
521 : data_( s )
522 , size_( count )
525 nssv_constexpr basic_string_view( CharT const * s)
526 : data_( s )
527 , size_( Traits::length(s) )
530 // Assignment:
532 #if nssv_CPP11_OR_GREATER
533 nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept = default;
534 #else
535 nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept
537 data_ = other.data_;
538 size_ = other.size_;
539 return *this;
541 #endif
543 // 24.4.2.2 Iterator support:
545 nssv_constexpr const_iterator begin() const nssv_noexcept { return data_; }
546 nssv_constexpr const_iterator end() const nssv_noexcept { return data_ + size_; }
548 nssv_constexpr const_iterator cbegin() const nssv_noexcept { return begin(); }
549 nssv_constexpr const_iterator cend() const nssv_noexcept { return end(); }
551 nssv_constexpr const_reverse_iterator rbegin() const nssv_noexcept { return const_reverse_iterator( end() ); }
552 nssv_constexpr const_reverse_iterator rend() const nssv_noexcept { return const_reverse_iterator( begin() ); }
554 nssv_constexpr const_reverse_iterator crbegin() const nssv_noexcept { return rbegin(); }
555 nssv_constexpr const_reverse_iterator crend() const nssv_noexcept { return rend(); }
557 // 24.4.2.3 Capacity:
559 nssv_constexpr size_type size() const nssv_noexcept { return size_; }
560 nssv_constexpr size_type length() const nssv_noexcept { return size_; }
561 nssv_constexpr size_type max_size() const nssv_noexcept { return (std::numeric_limits< size_type >::max)(); }
563 // since C++20
564 nssv_nodiscard nssv_constexpr bool empty() const nssv_noexcept
566 return 0 == size_;
569 // 24.4.2.4 Element access:
571 nssv_constexpr const_reference operator[]( size_type pos ) const
573 return data_at( pos );
576 nssv_constexpr14 const_reference at( size_type pos ) const
578 #if nssv_CONFIG_NO_EXCEPTIONS
579 assert( pos < size() );
580 #else
581 if ( pos >= size() )
583 throw std::out_of_range("nonst::string_view::at()");
585 #endif
586 return data_at( pos );
589 nssv_constexpr const_reference front() const { return data_at( 0 ); }
590 nssv_constexpr const_reference back() const { return data_at( size() - 1 ); }
592 nssv_constexpr const_pointer data() const nssv_noexcept { return data_; }
594 // 24.4.2.5 Modifiers:
596 nssv_constexpr14 void remove_prefix( size_type n )
598 assert( n <= size() );
599 data_ += n;
600 size_ -= n;
603 nssv_constexpr14 void remove_suffix( size_type n )
605 assert( n <= size() );
606 size_ -= n;
609 nssv_constexpr14 void swap( basic_string_view & other ) nssv_noexcept
611 using std::swap;
612 swap( data_, other.data_ );
613 swap( size_, other.size_ );
616 // 24.4.2.6 String operations:
618 size_type copy( CharT * dest, size_type n, size_type pos = 0 ) const
620 #if nssv_CONFIG_NO_EXCEPTIONS
621 assert( pos <= size() );
622 #else
623 if ( pos > size() )
625 throw std::out_of_range("nonst::string_view::copy()");
627 #endif
628 const size_type rlen = (std::min)( n, size() - pos );
630 (void) Traits::copy( dest, data() + pos, rlen );
632 return rlen;
635 nssv_constexpr14 basic_string_view substr( size_type pos = 0, size_type n = npos ) const
637 #if nssv_CONFIG_NO_EXCEPTIONS
638 assert( pos <= size() );
639 #else
640 if ( pos > size() )
642 throw std::out_of_range("nonst::string_view::substr()");
644 #endif
645 return basic_string_view( data() + pos, (std::min)( n, size() - pos ) );
648 // compare(), 6x:
650 nssv_constexpr14 int compare( basic_string_view other ) const nssv_noexcept // (1)
652 if ( const int result = Traits::compare( data(), other.data(), (std::min)( size(), other.size() ) ) )
654 return result;
657 return size() == other.size() ? 0 : size() < other.size() ? -1 : 1;
660 nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other ) const // (2)
662 return substr( pos1, n1 ).compare( other );
665 nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other, size_type pos2, size_type n2 ) const // (3)
667 return substr( pos1, n1 ).compare( other.substr( pos2, n2 ) );
670 nssv_constexpr int compare( CharT const * s ) const // (4)
672 return compare( basic_string_view( s ) );
675 nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s ) const // (5)
677 return substr( pos1, n1 ).compare( basic_string_view( s ) );
680 nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s, size_type n2 ) const // (6)
682 return substr( pos1, n1 ).compare( basic_string_view( s, n2 ) );
685 // 24.4.2.7 Searching:
687 // starts_with(), 3x, since C++20:
689 nssv_constexpr bool starts_with( basic_string_view v ) const nssv_noexcept // (1)
691 return size() >= v.size() && compare( 0, v.size(), v ) == 0;
694 nssv_constexpr bool starts_with( CharT c ) const nssv_noexcept // (2)
696 return starts_with( basic_string_view( &c, 1 ) );
699 nssv_constexpr bool starts_with( CharT const * s ) const // (3)
701 return starts_with( basic_string_view( s ) );
704 // ends_with(), 3x, since C++20:
706 nssv_constexpr bool ends_with( basic_string_view v ) const nssv_noexcept // (1)
708 return size() >= v.size() && compare( size() - v.size(), npos, v ) == 0;
711 nssv_constexpr bool ends_with( CharT c ) const nssv_noexcept // (2)
713 return ends_with( basic_string_view( &c, 1 ) );
716 nssv_constexpr bool ends_with( CharT const * s ) const // (3)
718 return ends_with( basic_string_view( s ) );
721 // find(), 4x:
723 nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
725 return assert( v.size() == 0 || v.data() != nssv_nullptr )
726 , pos >= size()
727 ? npos
728 : to_pos( std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
731 nssv_constexpr14 size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
733 return find( basic_string_view( &c, 1 ), pos );
736 nssv_constexpr14 size_type find( CharT const * s, size_type pos, size_type n ) const // (3)
738 return find( basic_string_view( s, n ), pos );
741 nssv_constexpr14 size_type find( CharT const * s, size_type pos = 0 ) const // (4)
743 return find( basic_string_view( s ), pos );
746 // rfind(), 4x:
748 nssv_constexpr14 size_type rfind( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1)
750 if ( size() < v.size() )
752 return npos;
755 if ( v.empty() )
757 return (std::min)( size(), pos );
760 const_iterator last = cbegin() + (std::min)( size() - v.size(), pos ) + v.size();
761 const_iterator result = std::find_end( cbegin(), last, v.cbegin(), v.cend(), Traits::eq );
763 return result != last ? size_type( result - cbegin() ) : npos;
766 nssv_constexpr14 size_type rfind( CharT c, size_type pos = npos ) const nssv_noexcept // (2)
768 return rfind( basic_string_view( &c, 1 ), pos );
771 nssv_constexpr14 size_type rfind( CharT const * s, size_type pos, size_type n ) const // (3)
773 return rfind( basic_string_view( s, n ), pos );
776 nssv_constexpr14 size_type rfind( CharT const * s, size_type pos = npos ) const // (4)
778 return rfind( basic_string_view( s ), pos );
781 // find_first_of(), 4x:
783 nssv_constexpr size_type find_first_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
785 return pos >= size()
786 ? npos
787 : to_pos( std::find_first_of( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
790 nssv_constexpr size_type find_first_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
792 return find_first_of( basic_string_view( &c, 1 ), pos );
795 nssv_constexpr size_type find_first_of( CharT const * s, size_type pos, size_type n ) const // (3)
797 return find_first_of( basic_string_view( s, n ), pos );
800 nssv_constexpr size_type find_first_of( CharT const * s, size_type pos = 0 ) const // (4)
802 return find_first_of( basic_string_view( s ), pos );
805 // find_last_of(), 4x:
807 nssv_constexpr size_type find_last_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1)
809 return empty()
810 ? npos
811 : pos >= size()
812 ? find_last_of( v, size() - 1 )
813 : to_pos( std::find_first_of( const_reverse_iterator( cbegin() + pos + 1 ), crend(), v.cbegin(), v.cend(), Traits::eq ) );
816 nssv_constexpr size_type find_last_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2)
818 return find_last_of( basic_string_view( &c, 1 ), pos );
821 nssv_constexpr size_type find_last_of( CharT const * s, size_type pos, size_type count ) const // (3)
823 return find_last_of( basic_string_view( s, count ), pos );
826 nssv_constexpr size_type find_last_of( CharT const * s, size_type pos = npos ) const // (4)
828 return find_last_of( basic_string_view( s ), pos );
831 // find_first_not_of(), 4x:
833 nssv_constexpr size_type find_first_not_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
835 return pos >= size()
836 ? npos
837 : to_pos( std::find_if( cbegin() + pos, cend(), not_in_view( v ) ) );
840 nssv_constexpr size_type find_first_not_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
842 return find_first_not_of( basic_string_view( &c, 1 ), pos );
845 nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos, size_type count ) const // (3)
847 return find_first_not_of( basic_string_view( s, count ), pos );
850 nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos = 0 ) const // (4)
852 return find_first_not_of( basic_string_view( s ), pos );
855 // find_last_not_of(), 4x:
857 nssv_constexpr size_type find_last_not_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1)
859 return empty()
860 ? npos
861 : pos >= size()
862 ? find_last_not_of( v, size() - 1 )
863 : to_pos( std::find_if( const_reverse_iterator( cbegin() + pos + 1 ), crend(), not_in_view( v ) ) );
866 nssv_constexpr size_type find_last_not_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2)
868 return find_last_not_of( basic_string_view( &c, 1 ), pos );
871 nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos, size_type count ) const // (3)
873 return find_last_not_of( basic_string_view( s, count ), pos );
876 nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos = npos ) const // (4)
878 return find_last_not_of( basic_string_view( s ), pos );
881 // Constants:
883 #if nssv_CPP17_OR_GREATER
884 static nssv_constexpr size_type npos = size_type(-1);
885 #elif nssv_CPP11_OR_GREATER
886 enum : size_type { npos = size_type(-1) };
887 #else
888 enum { npos = size_type(-1) };
889 #endif
891 private:
892 struct not_in_view
894 const basic_string_view v;
896 nssv_constexpr not_in_view( basic_string_view v ) : v( v ) {}
898 nssv_constexpr bool operator()( CharT c ) const
900 return npos == v.find_first_of( c );
904 nssv_constexpr size_type to_pos( const_iterator it ) const
906 return it == cend() ? npos : size_type( it - cbegin() );
909 nssv_constexpr size_type to_pos( const_reverse_iterator it ) const
911 return it == crend() ? npos : size_type( crend() - it - 1 );
914 nssv_constexpr const_reference data_at( size_type pos ) const
916 #if nssv_BETWEEN( nssv_COMPILER_GNUC_VERSION, 1, 500 )
917 return data_[pos];
918 #else
919 return assert( pos < size() ), data_[pos];
920 #endif
923 private:
924 const_pointer data_;
925 size_type size_;
927 public:
928 #if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
930 template< class Allocator >
931 basic_string_view( std::basic_string<CharT, Traits, Allocator> const & s ) nssv_noexcept
932 : data_( s.data() )
933 , size_( s.size() )
936 #if nssv_HAVE_EXPLICIT_CONVERSION
938 template< class Allocator >
939 explicit operator std::basic_string<CharT, Traits, Allocator>() const
941 return to_string( Allocator() );
944 #endif // nssv_HAVE_EXPLICIT_CONVERSION
946 #if nssv_CPP11_OR_GREATER
948 template< class Allocator = std::allocator<CharT> >
949 std::basic_string<CharT, Traits, Allocator>
950 to_string( Allocator const & a = Allocator() ) const
952 return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
955 #else
957 std::basic_string<CharT, Traits>
958 to_string() const
960 return std::basic_string<CharT, Traits>( begin(), end() );
963 template< class Allocator >
964 std::basic_string<CharT, Traits, Allocator>
965 to_string( Allocator const & a ) const
967 return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
970 #endif // nssv_CPP11_OR_GREATER
972 #endif // nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
976 // Non-member functions:
979 // 24.4.3 Non-member comparison functions:
980 // lexicographically compare two string views (function template):
982 template< class CharT, class Traits >
983 nssv_constexpr bool operator== (
984 basic_string_view <CharT, Traits> lhs,
985 basic_string_view <CharT, Traits> rhs ) nssv_noexcept
986 { return lhs.compare( rhs ) == 0 ; }
988 template< class CharT, class Traits >
989 nssv_constexpr bool operator!= (
990 basic_string_view <CharT, Traits> lhs,
991 basic_string_view <CharT, Traits> rhs ) nssv_noexcept
992 { return lhs.compare( rhs ) != 0 ; }
994 template< class CharT, class Traits >
995 nssv_constexpr bool operator< (
996 basic_string_view <CharT, Traits> lhs,
997 basic_string_view <CharT, Traits> rhs ) nssv_noexcept
998 { return lhs.compare( rhs ) < 0 ; }
1000 template< class CharT, class Traits >
1001 nssv_constexpr bool operator<= (
1002 basic_string_view <CharT, Traits> lhs,
1003 basic_string_view <CharT, Traits> rhs ) nssv_noexcept
1004 { return lhs.compare( rhs ) <= 0 ; }
1006 template< class CharT, class Traits >
1007 nssv_constexpr bool operator> (
1008 basic_string_view <CharT, Traits> lhs,
1009 basic_string_view <CharT, Traits> rhs ) nssv_noexcept
1010 { return lhs.compare( rhs ) > 0 ; }
1012 template< class CharT, class Traits >
1013 nssv_constexpr bool operator>= (
1014 basic_string_view <CharT, Traits> lhs,
1015 basic_string_view <CharT, Traits> rhs ) nssv_noexcept
1016 { return lhs.compare( rhs ) >= 0 ; }
1018 // Let S be basic_string_view<CharT, Traits>, and sv be an instance of S.
1019 // Implementations shall provide sufficient additional overloads marked
1020 // constexpr and noexcept so that an object t with an implicit conversion
1021 // to S can be compared according to Table 67.
1023 #if nssv_CPP11_OR_GREATER && ! nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 100, 141 )
1025 #define nssv_BASIC_STRING_VIEW_I(T,U) typename std::decay< basic_string_view<T,U> >::type
1027 #if nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 140, 150 )
1028 # define nssv_MSVC_ORDER(x) , int=x
1029 #else
1030 # define nssv_MSVC_ORDER(x) /*, int=x*/
1031 #endif
1033 // ==
1035 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
1036 nssv_constexpr bool operator==(
1037 basic_string_view <CharT, Traits> lhs,
1038 nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs ) nssv_noexcept
1039 { return lhs.compare( rhs ) == 0; }
1041 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
1042 nssv_constexpr bool operator==(
1043 nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
1044 basic_string_view <CharT, Traits> rhs ) nssv_noexcept
1045 { return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
1047 // !=
1049 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
1050 nssv_constexpr bool operator!= (
1051 basic_string_view < CharT, Traits > lhs,
1052 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
1053 { return lhs.size() != rhs.size() || lhs.compare( rhs ) != 0 ; }
1055 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
1056 nssv_constexpr bool operator!= (
1057 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
1058 basic_string_view < CharT, Traits > rhs ) nssv_noexcept
1059 { return lhs.compare( rhs ) != 0 ; }
1061 // <
1063 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
1064 nssv_constexpr bool operator< (
1065 basic_string_view < CharT, Traits > lhs,
1066 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
1067 { return lhs.compare( rhs ) < 0 ; }
1069 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
1070 nssv_constexpr bool operator< (
1071 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
1072 basic_string_view < CharT, Traits > rhs ) nssv_noexcept
1073 { return lhs.compare( rhs ) < 0 ; }
1075 // <=
1077 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
1078 nssv_constexpr bool operator<= (
1079 basic_string_view < CharT, Traits > lhs,
1080 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
1081 { return lhs.compare( rhs ) <= 0 ; }
1083 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
1084 nssv_constexpr bool operator<= (
1085 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
1086 basic_string_view < CharT, Traits > rhs ) nssv_noexcept
1087 { return lhs.compare( rhs ) <= 0 ; }
1089 // >
1091 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
1092 nssv_constexpr bool operator> (
1093 basic_string_view < CharT, Traits > lhs,
1094 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
1095 { return lhs.compare( rhs ) > 0 ; }
1097 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
1098 nssv_constexpr bool operator> (
1099 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
1100 basic_string_view < CharT, Traits > rhs ) nssv_noexcept
1101 { return lhs.compare( rhs ) > 0 ; }
1103 // >=
1105 template< class CharT, class Traits nssv_MSVC_ORDER(1) >
1106 nssv_constexpr bool operator>= (
1107 basic_string_view < CharT, Traits > lhs,
1108 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
1109 { return lhs.compare( rhs ) >= 0 ; }
1111 template< class CharT, class Traits nssv_MSVC_ORDER(2) >
1112 nssv_constexpr bool operator>= (
1113 nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
1114 basic_string_view < CharT, Traits > rhs ) nssv_noexcept
1115 { return lhs.compare( rhs ) >= 0 ; }
1117 #undef nssv_MSVC_ORDER
1118 #undef nssv_BASIC_STRING_VIEW_I
1120 #endif // nssv_CPP11_OR_GREATER
1122 // 24.4.4 Inserters and extractors:
1124 namespace detail {
1126 template< class Stream >
1127 void write_padding( Stream & os, std::streamsize n )
1129 for ( std::streamsize i = 0; i < n; ++i )
1131 os.rdbuf()->sputc( os.fill() );
1135 template< class Stream, class View >
1136 Stream & write_to_stream( Stream & os, View const & sv )
1138 typename Stream::sentry sentry( os );
1140 if ( !os )
1142 return os;
1145 const std::streamsize length = static_cast<std::streamsize>( sv.length() );
1147 // Whether, and how, to pad:
1148 const bool pad = ( length < os.width() );
1149 const bool left_pad = pad && ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::right;
1151 if ( left_pad )
1153 write_padding( os, os.width() - length );
1156 // Write span characters:
1157 os.rdbuf()->sputn( sv.begin(), length );
1159 if ( pad && !left_pad )
1161 write_padding( os, os.width() - length );
1164 // Reset output stream width:
1165 os.width( 0 );
1167 return os;
1170 } // namespace detail
1172 template< class CharT, class Traits >
1173 std::basic_ostream<CharT, Traits> &
1174 operator<<(
1175 std::basic_ostream<CharT, Traits>& os,
1176 basic_string_view <CharT, Traits> sv )
1178 return detail::write_to_stream( os, sv );
1181 // Several typedefs for common character types are provided:
1183 typedef basic_string_view<char> string_view;
1184 typedef basic_string_view<wchar_t> wstring_view;
1185 #if nssv_HAVE_WCHAR16_T
1186 typedef basic_string_view<char16_t> u16string_view;
1187 typedef basic_string_view<char32_t> u32string_view;
1188 #endif
1190 } // namespace sv_lite
1191 } // namespace nonstd
1194 // 24.4.6 Suffix for basic_string_view literals:
1197 #if nssv_HAVE_USER_DEFINED_LITERALS
1199 namespace nonstd {
1200 nssv_inline_ns namespace literals {
1201 nssv_inline_ns namespace string_view_literals {
1203 #if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
1205 nssv_constexpr nonstd::sv_lite::string_view operator "" sv( const char* str, size_t len ) nssv_noexcept // (1)
1207 return nonstd::sv_lite::string_view{ str, len };
1210 nssv_constexpr nonstd::sv_lite::u16string_view operator "" sv( const char16_t* str, size_t len ) nssv_noexcept // (2)
1212 return nonstd::sv_lite::u16string_view{ str, len };
1215 nssv_constexpr nonstd::sv_lite::u32string_view operator "" sv( const char32_t* str, size_t len ) nssv_noexcept // (3)
1217 return nonstd::sv_lite::u32string_view{ str, len };
1220 nssv_constexpr nonstd::sv_lite::wstring_view operator "" sv( const wchar_t* str, size_t len ) nssv_noexcept // (4)
1222 return nonstd::sv_lite::wstring_view{ str, len };
1225 #endif // nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
1227 #if nssv_CONFIG_USR_SV_OPERATOR
1229 nssv_constexpr nonstd::sv_lite::string_view operator "" _sv( const char* str, size_t len ) nssv_noexcept // (1)
1231 return nonstd::sv_lite::string_view{ str, len };
1234 nssv_constexpr nonstd::sv_lite::u16string_view operator "" _sv( const char16_t* str, size_t len ) nssv_noexcept // (2)
1236 return nonstd::sv_lite::u16string_view{ str, len };
1239 nssv_constexpr nonstd::sv_lite::u32string_view operator "" _sv( const char32_t* str, size_t len ) nssv_noexcept // (3)
1241 return nonstd::sv_lite::u32string_view{ str, len };
1244 nssv_constexpr nonstd::sv_lite::wstring_view operator "" _sv( const wchar_t* str, size_t len ) nssv_noexcept // (4)
1246 return nonstd::sv_lite::wstring_view{ str, len };
1249 #endif // nssv_CONFIG_USR_SV_OPERATOR
1251 } // namespace string_view_literals
1252 } // namespace literals
1253 } // namespace nonstd
1255 #endif
1258 // Extensions for std::string:
1261 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1263 namespace nonstd {
1264 namespace sv_lite {
1266 // Exclude MSVC 14 (19.00): it yields ambiguous to_string():
1268 #if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140
1270 template< class CharT, class Traits, class Allocator = std::allocator<CharT> >
1271 std::basic_string<CharT, Traits, Allocator>
1272 to_string( basic_string_view<CharT, Traits> v, Allocator const & a = Allocator() )
1274 return std::basic_string<CharT,Traits, Allocator>( v.begin(), v.end(), a );
1277 #else
1279 template< class CharT, class Traits >
1280 std::basic_string<CharT, Traits>
1281 to_string( basic_string_view<CharT, Traits> v )
1283 return std::basic_string<CharT, Traits>( v.begin(), v.end() );
1286 template< class CharT, class Traits, class Allocator >
1287 std::basic_string<CharT, Traits, Allocator>
1288 to_string( basic_string_view<CharT, Traits> v, Allocator const & a )
1290 return std::basic_string<CharT, Traits, Allocator>( v.begin(), v.end(), a );
1293 #endif // nssv_CPP11_OR_GREATER
1295 template< class CharT, class Traits, class Allocator >
1296 basic_string_view<CharT, Traits>
1297 to_string_view( std::basic_string<CharT, Traits, Allocator> const & s )
1299 return basic_string_view<CharT, Traits>( s.data(), s.size() );
1302 } // namespace sv_lite
1303 } // namespace nonstd
1305 #endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1308 // make types and algorithms available in namespace nonstd:
1311 namespace nonstd {
1313 using sv_lite::basic_string_view;
1314 using sv_lite::string_view;
1315 using sv_lite::wstring_view;
1317 #if nssv_HAVE_WCHAR16_T
1318 using sv_lite::u16string_view;
1319 #endif
1320 #if nssv_HAVE_WCHAR32_T
1321 using sv_lite::u32string_view;
1322 #endif
1324 // literal "sv"
1326 using sv_lite::operator==;
1327 using sv_lite::operator!=;
1328 using sv_lite::operator<;
1329 using sv_lite::operator<=;
1330 using sv_lite::operator>;
1331 using sv_lite::operator>=;
1333 using sv_lite::operator<<;
1335 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1336 using sv_lite::to_string;
1337 using sv_lite::to_string_view;
1338 #endif
1340 } // namespace nonstd
1342 // 24.4.5 Hash support (C++11):
1344 // Note: The hash value of a string view object is equal to the hash value of
1345 // the corresponding string object.
1347 #if nssv_HAVE_STD_HASH
1349 #include <functional>
1351 namespace std {
1353 template<>
1354 struct hash< nonstd::string_view >
1356 public:
1357 std::size_t operator()( nonstd::string_view v ) const nssv_noexcept
1359 return std::hash<std::string>()( std::string( v.data(), v.size() ) );
1363 template<>
1364 struct hash< nonstd::wstring_view >
1366 public:
1367 std::size_t operator()( nonstd::wstring_view v ) const nssv_noexcept
1369 return std::hash<std::wstring>()( std::wstring( v.data(), v.size() ) );
1373 template<>
1374 struct hash< nonstd::u16string_view >
1376 public:
1377 std::size_t operator()( nonstd::u16string_view v ) const nssv_noexcept
1379 return std::hash<std::u16string>()( std::u16string( v.data(), v.size() ) );
1383 template<>
1384 struct hash< nonstd::u32string_view >
1386 public:
1387 std::size_t operator()( nonstd::u32string_view v ) const nssv_noexcept
1389 return std::hash<std::u32string>()( std::u32string( v.data(), v.size() ) );
1393 } // namespace std
1395 #endif // nssv_HAVE_STD_HASH
1397 nssv_RESTORE_WARNINGS()
1399 #endif // nssv_HAVE_STD_STRING_VIEW
1401 namespace gmx
1403 namespace compat
1405 using namespace nonstd;
1406 } // namespace compat
1407 } // namespace gmx
1409 // GMX modification to suppress Doxygen checking
1410 #endif // DOXYGEN
1412 #endif