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)
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
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
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 )
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_...
98 #ifndef nssv_CONFIG_STD_SV_OPERATOR
99 # define nssv_CONFIG_STD_SV_OPERATOR 0
102 #ifndef nssv_CONFIG_USR_SV_OPERATOR
103 # define nssv_CONFIG_USR_SV_OPERATOR 1
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
111 #ifndef nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
112 # define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS 1
115 #ifndef nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
116 # define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS 1
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
125 # define nssv_CONFIG_NO_EXCEPTIONS 1
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 )
136 # define nssv_CPLUSPLUS __cplusplus
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
153 # define nssv_HAVE_STD_STRING_VIEW 0
156 # define nssv_HAVE_STD_STRING_VIEW 0
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
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
;
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
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 ) ) )
278 # define nssv_COMPILER_MSVC_VER 0
279 # define nssv_COMPILER_MSVC_VERSION 0
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__)
287 # define nssv_COMPILER_CLANG_VERSION 0
290 #if defined(__GNUC__) && !defined(__clang__)
291 # define nssv_COMPILER_GNUC_VERSION nssv_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
293 # define nssv_COMPILER_GNUC_VERSION 0
296 // half-open range [lo..hi):
297 #define nssv_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
299 // Presence of language and library features:
302 # define nssv_HAS_CPP0X _HAS_CPP0X
304 # define nssv_HAS_CPP0X 0
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
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
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
359 # define nssv_constexpr /*constexpr*/
362 #if nssv_HAVE_CONSTEXPR_14
363 # define nssv_constexpr14 constexpr
365 # define nssv_constexpr14 /*constexpr*/
368 #if nssv_HAVE_EXPLICIT_CONVERSION
369 # define nssv_explicit explicit
371 # define nssv_explicit /*explicit*/
374 #if nssv_HAVE_INLINE_NAMESPACE
375 # define nssv_inline_ns inline
377 # define nssv_inline_ns /*inline*/
380 #if nssv_HAVE_NOEXCEPT
381 # define nssv_noexcept noexcept
383 # define nssv_noexcept /*noexcept*/
386 //#if nssv_HAVE_REF_QUALIFIER
387 //# define nssv_ref_qual &
388 //# define nssv_refref_qual &&
390 //# define nssv_ref_qual /*&*/
391 //# define nssv_refref_qual /*&&*/
394 #if nssv_HAVE_NULLPTR
395 # define nssv_nullptr nullptr
397 # define nssv_nullptr NULL
400 #if nssv_HAVE_NODISCARD
401 # define nssv_nodiscard [[nodiscard]]
403 # define nssv_nodiscard /*[[nodiscard]]*/
406 // Additional includes:
413 #include <string> // std::char_traits<>
415 #if ! nssv_CONFIG_NO_EXCEPTIONS
416 # include <stdexcept>
419 #if nssv_CPP11_OR_GREATER
420 # include <type_traits>
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"
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))
439 # define nssv_SUPPRESS_MSGSL_WARNING(expr)
440 # define nssv_SUPPRESS_MSVC_WARNING(code, descr)
441 # define nssv_DISABLE_MSVC_WARNINGS(codes)
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 ))
451 # define nssv_RESTORE_WARNINGS()
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
{
470 class Traits
= std::char_traits
<CharT
>
472 class basic_string_view
;
475 // basic_string_view:
481 class Traits
/* = std::char_traits<CharT> */
483 class basic_string_view
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
)
511 #if nssv_CPP11_OR_GREATER
512 nssv_constexpr
basic_string_view( basic_string_view
const & other
) nssv_noexcept
= default;
514 nssv_constexpr
basic_string_view( basic_string_view
const & other
) nssv_noexcept
515 : data_( other
.data_
)
516 , size_( other
.size_
)
520 nssv_constexpr
basic_string_view( CharT
const * s
, size_type count
)
525 nssv_constexpr
basic_string_view( CharT
const * s
)
527 , size_( Traits::length(s
) )
532 #if nssv_CPP11_OR_GREATER
533 nssv_constexpr14 basic_string_view
& operator=( basic_string_view
const & other
) nssv_noexcept
= default;
535 nssv_constexpr14 basic_string_view
& operator=( basic_string_view
const & other
) nssv_noexcept
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
)(); }
564 nssv_nodiscard nssv_constexpr
bool empty() const nssv_noexcept
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() );
583 throw std::out_of_range("nonst::string_view::at()");
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() );
603 nssv_constexpr14
void remove_suffix( size_type n
)
605 assert( n
<= size() );
609 nssv_constexpr14
void swap( basic_string_view
& other
) nssv_noexcept
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() );
625 throw std::out_of_range("nonst::string_view::copy()");
628 const size_type rlen
= (std::min
)( n
, size() - pos
);
630 (void) Traits::copy( dest
, data() + pos
, 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() );
642 throw std::out_of_range("nonst::string_view::substr()");
645 return basic_string_view( data() + pos
, (std::min
)( n
, size() - pos
) );
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() ) ) )
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
) );
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
)
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
);
748 nssv_constexpr14 size_type
rfind( basic_string_view v
, size_type pos
= npos
) const nssv_noexcept
// (1)
750 if ( size() < v
.size() )
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)
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)
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)
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)
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
);
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) };
888 enum { npos
= size_type(-1) };
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 )
919 return assert( pos
< size() ), data_
[pos
];
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
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
);
957 std::basic_string
<CharT
, Traits
>
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
1030 # define nssv_MSVC_ORDER(x) /*, int=x*/
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; }
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 ; }
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 ; }
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 ; }
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 ; }
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:
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
);
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
;
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:
1170 } // namespace detail
1172 template< class CharT
, class Traits
>
1173 std::basic_ostream
<CharT
, Traits
> &
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
;
1190 } // namespace sv_lite
1191 } // namespace nonstd
1194 // 24.4.6 Suffix for basic_string_view literals:
1197 #if nssv_HAVE_USER_DEFINED_LITERALS
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
1258 // Extensions for std::string:
1261 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
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
);
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:
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
;
1320 #if nssv_HAVE_WCHAR32_T
1321 using sv_lite::u32string_view
;
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
;
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>
1354 struct hash
< nonstd::string_view
>
1357 std::size_t operator()( nonstd::string_view v
) const nssv_noexcept
1359 return std::hash
<std::string
>()( std::string( v
.data(), v
.size() ) );
1364 struct hash
< nonstd::wstring_view
>
1367 std::size_t operator()( nonstd::wstring_view v
) const nssv_noexcept
1369 return std::hash
<std::wstring
>()( std::wstring( v
.data(), v
.size() ) );
1374 struct hash
< nonstd::u16string_view
>
1377 std::size_t operator()( nonstd::u16string_view v
) const nssv_noexcept
1379 return std::hash
<std::u16string
>()( std::u16string( v
.data(), v
.size() ) );
1384 struct hash
< nonstd::u32string_view
>
1387 std::size_t operator()( nonstd::u32string_view v
) const nssv_noexcept
1389 return std::hash
<std::u32string
>()( std::u32string( v
.data(), v
.size() ) );
1395 #endif // nssv_HAVE_STD_HASH
1397 nssv_RESTORE_WARNINGS()
1399 #endif // nssv_HAVE_STD_STRING_VIEW
1405 using namespace nonstd
;
1406 } // namespace compat
1409 // GMX modification to suppress Doxygen checking