--- /dev/null
+// Copyright 2017-2020 by Martin Moene
+//
+// string-view lite, a C++17-like string_view for C++98 and later.
+// For more information see https://github.com/martinmoene/string-view-lite
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#pragma once
+
+#ifndef NONSTD_SV_LITE_H_INCLUDED
+#define NONSTD_SV_LITE_H_INCLUDED
+
+#define string_view_lite_MAJOR 1
+#define string_view_lite_MINOR 7
+#define string_view_lite_PATCH 0
+
+#define string_view_lite_VERSION nssv_STRINGIFY(string_view_lite_MAJOR) "." nssv_STRINGIFY(string_view_lite_MINOR) "." nssv_STRINGIFY(string_view_lite_PATCH)
+
+#define nssv_STRINGIFY( x ) nssv_STRINGIFY_( x )
+#define nssv_STRINGIFY_( x ) #x
+
+// string-view lite configuration:
+
+#define nssv_STRING_VIEW_DEFAULT 0
+#define nssv_STRING_VIEW_NONSTD 1
+#define nssv_STRING_VIEW_STD 2
+
+// tweak header support:
+
+#ifdef __has_include
+# if __has_include(<nonstd/string_view.tweak.hpp>)
+# include <nonstd/string_view.tweak.hpp>
+# endif
+#define nssv_HAVE_TWEAK_HEADER 1
+#else
+#define nssv_HAVE_TWEAK_HEADER 0
+//# pragma message("string_view.hpp: Note: Tweak header not supported.")
+#endif
+
+// string_view selection and configuration:
+
+#if !defined( nssv_CONFIG_SELECT_STRING_VIEW )
+# define nssv_CONFIG_SELECT_STRING_VIEW ( nssv_HAVE_STD_STRING_VIEW ? nssv_STRING_VIEW_STD : nssv_STRING_VIEW_NONSTD )
+#endif
+
+#ifndef nssv_CONFIG_STD_SV_OPERATOR
+# define nssv_CONFIG_STD_SV_OPERATOR 0
+#endif
+
+#ifndef nssv_CONFIG_USR_SV_OPERATOR
+# define nssv_CONFIG_USR_SV_OPERATOR 1
+#endif
+
+#ifdef nssv_CONFIG_CONVERSION_STD_STRING
+# define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS nssv_CONFIG_CONVERSION_STD_STRING
+# define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS nssv_CONFIG_CONVERSION_STD_STRING
+#endif
+
+#ifndef nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
+# define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS 1
+#endif
+
+#ifndef nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
+# define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS 1
+#endif
+
+#ifndef nssv_CONFIG_NO_STREAM_INSERTION
+# define nssv_CONFIG_NO_STREAM_INSERTION 0
+#endif
+
+#ifndef nssv_CONFIG_CONSTEXPR11_STD_SEARCH
+# define nssv_CONFIG_CONSTEXPR11_STD_SEARCH 1
+#endif
+
+// Control presence of exception handling (try and auto discover):
+
+#ifndef nssv_CONFIG_NO_EXCEPTIONS
+# if defined(_MSC_VER)
+# include <cstddef> // for _HAS_EXCEPTIONS
+# endif
+# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
+# define nssv_CONFIG_NO_EXCEPTIONS 0
+# else
+# define nssv_CONFIG_NO_EXCEPTIONS 1
+# endif
+#endif
+
+// C++ language version detection (C++23 is speculative):
+// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
+
+#ifndef nssv_CPLUSPLUS
+# if defined(_MSVC_LANG ) && !defined(__clang__)
+# define nssv_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
+# else
+# define nssv_CPLUSPLUS __cplusplus
+# endif
+#endif
+
+#define nssv_CPP98_OR_GREATER ( nssv_CPLUSPLUS >= 199711L )
+#define nssv_CPP11_OR_GREATER ( nssv_CPLUSPLUS >= 201103L )
+#define nssv_CPP11_OR_GREATER_ ( nssv_CPLUSPLUS >= 201103L )
+#define nssv_CPP14_OR_GREATER ( nssv_CPLUSPLUS >= 201402L )
+#define nssv_CPP17_OR_GREATER ( nssv_CPLUSPLUS >= 201703L )
+#define nssv_CPP20_OR_GREATER ( nssv_CPLUSPLUS >= 202002L )
+#define nssv_CPP23_OR_GREATER ( nssv_CPLUSPLUS >= 202300L )
+
+// use C++17 std::string_view if available and requested:
+
+#if nssv_CPP17_OR_GREATER && defined(__has_include )
+# if __has_include( <string_view> )
+# define nssv_HAVE_STD_STRING_VIEW 1
+# else
+# define nssv_HAVE_STD_STRING_VIEW 0
+# endif
+#else
+# define nssv_HAVE_STD_STRING_VIEW 0
+#endif
+
+#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) )
+
+#define nssv_HAVE_STARTS_WITH ( nssv_CPP20_OR_GREATER || !nssv_USES_STD_STRING_VIEW )
+#define nssv_HAVE_ENDS_WITH nssv_HAVE_STARTS_WITH
+
+//
+// Use C++17 std::string_view:
+//
+
+#if nssv_USES_STD_STRING_VIEW
+
+#include <string_view>
+
+// Extensions for std::string:
+
+#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
+
+namespace nonstd {
+
+template< class CharT, class Traits, class Allocator = std::allocator<CharT> >
+std::basic_string<CharT, Traits, Allocator>
+to_string( std::basic_string_view<CharT, Traits> v, Allocator const & a = Allocator() )
+{
+ return std::basic_string<CharT,Traits, Allocator>( v.begin(), v.end(), a );
+}
+
+template< class CharT, class Traits, class Allocator >
+std::basic_string_view<CharT, Traits>
+to_string_view( std::basic_string<CharT, Traits, Allocator> const & s )
+{
+ return std::basic_string_view<CharT, Traits>( s.data(), s.size() );
+}
+
+// Literal operators sv and _sv:
+
+#if nssv_CONFIG_STD_SV_OPERATOR
+
+using namespace std::literals::string_view_literals;
+
+#endif
+
+#if nssv_CONFIG_USR_SV_OPERATOR
+
+inline namespace literals {
+inline namespace string_view_literals {
+
+
+constexpr std::string_view operator "" _sv( const char* str, size_t len ) noexcept // (1)
+{
+ return std::string_view{ str, len };
+}
+
+constexpr std::u16string_view operator "" _sv( const char16_t* str, size_t len ) noexcept // (2)
+{
+ return std::u16string_view{ str, len };
+}
+
+constexpr std::u32string_view operator "" _sv( const char32_t* str, size_t len ) noexcept // (3)
+{
+ return std::u32string_view{ str, len };
+}
+
+constexpr std::wstring_view operator "" _sv( const wchar_t* str, size_t len ) noexcept // (4)
+{
+ return std::wstring_view{ str, len };
+}
+
+}} // namespace literals::string_view_literals
+
+#endif // nssv_CONFIG_USR_SV_OPERATOR
+
+} // namespace nonstd
+
+#endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
+
+namespace nonstd {
+
+using std::string_view;
+using std::wstring_view;
+using std::u16string_view;
+using std::u32string_view;
+using std::basic_string_view;
+
+// literal "sv" and "_sv", see above
+
+using std::operator==;
+using std::operator!=;
+using std::operator<;
+using std::operator<=;
+using std::operator>;
+using std::operator>=;
+
+using std::operator<<;
+
+} // namespace nonstd
+
+#else // nssv_HAVE_STD_STRING_VIEW
+
+//
+// Before C++17: use string_view lite:
+//
+
+// Compiler versions:
+//
+// MSVC++ 6.0 _MSC_VER == 1200 nssv_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0)
+// MSVC++ 7.0 _MSC_VER == 1300 nssv_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002)
+// MSVC++ 7.1 _MSC_VER == 1310 nssv_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003)
+// MSVC++ 8.0 _MSC_VER == 1400 nssv_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005)
+// MSVC++ 9.0 _MSC_VER == 1500 nssv_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008)
+// MSVC++ 10.0 _MSC_VER == 1600 nssv_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010)
+// MSVC++ 11.0 _MSC_VER == 1700 nssv_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012)
+// MSVC++ 12.0 _MSC_VER == 1800 nssv_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013)
+// MSVC++ 14.0 _MSC_VER == 1900 nssv_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015)
+// MSVC++ 14.1 _MSC_VER >= 1910 nssv_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017)
+// MSVC++ 14.2 _MSC_VER >= 1920 nssv_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019)
+
+#if defined(_MSC_VER ) && !defined(__clang__)
+# define nssv_COMPILER_MSVC_VER (_MSC_VER )
+# define nssv_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
+#else
+# define nssv_COMPILER_MSVC_VER 0
+# define nssv_COMPILER_MSVC_VERSION 0
+#endif
+
+#define nssv_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) )
+
+#if defined( __apple_build_version__ )
+# define nssv_COMPILER_APPLECLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
+# define nssv_COMPILER_CLANG_VERSION 0
+#elif defined( __clang__ )
+# define nssv_COMPILER_APPLECLANG_VERSION 0
+# define nssv_COMPILER_CLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
+#else
+# define nssv_COMPILER_APPLECLANG_VERSION 0
+# define nssv_COMPILER_CLANG_VERSION 0
+#endif
+
+#if defined(__GNUC__) && !defined(__clang__)
+# define nssv_COMPILER_GNUC_VERSION nssv_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
+#else
+# define nssv_COMPILER_GNUC_VERSION 0
+#endif
+
+// half-open range [lo..hi):
+#define nssv_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
+
+// Presence of language and library features:
+
+#ifdef _HAS_CPP0X
+# define nssv_HAS_CPP0X _HAS_CPP0X
+#else
+# define nssv_HAS_CPP0X 0
+#endif
+
+// Unless defined otherwise below, consider VC14 as C++11 for string-view-lite:
+
+#if nssv_COMPILER_MSVC_VER >= 1900
+# undef nssv_CPP11_OR_GREATER
+# define nssv_CPP11_OR_GREATER 1
+#endif
+
+#define nssv_CPP11_90 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1500)
+#define nssv_CPP11_100 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1600)
+#define nssv_CPP11_110 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1700)
+#define nssv_CPP11_120 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1800)
+#define nssv_CPP11_140 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1900)
+#define nssv_CPP11_141 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1910)
+
+#define nssv_CPP14_000 (nssv_CPP14_OR_GREATER)
+#define nssv_CPP17_000 (nssv_CPP17_OR_GREATER)
+
+// Presence of C++11 language features:
+
+#define nssv_HAVE_CONSTEXPR_11 nssv_CPP11_140
+#define nssv_HAVE_EXPLICIT_CONVERSION nssv_CPP11_140
+#define nssv_HAVE_INLINE_NAMESPACE nssv_CPP11_140
+#define nssv_HAVE_IS_DEFAULT nssv_CPP11_140
+#define nssv_HAVE_IS_DELETE nssv_CPP11_140
+#define nssv_HAVE_NOEXCEPT nssv_CPP11_140
+#define nssv_HAVE_NULLPTR nssv_CPP11_100
+#define nssv_HAVE_REF_QUALIFIER nssv_CPP11_140
+#define nssv_HAVE_UNICODE_LITERALS nssv_CPP11_140
+#define nssv_HAVE_USER_DEFINED_LITERALS nssv_CPP11_140
+#define nssv_HAVE_WCHAR16_T nssv_CPP11_100
+#define nssv_HAVE_WCHAR32_T nssv_CPP11_100
+
+#if ! ( ( nssv_CPP11_OR_GREATER && nssv_COMPILER_CLANG_VERSION ) || nssv_BETWEEN( nssv_COMPILER_CLANG_VERSION, 300, 400 ) )
+# define nssv_HAVE_STD_DEFINED_LITERALS nssv_CPP11_140
+#else
+# define nssv_HAVE_STD_DEFINED_LITERALS 0
+#endif
+
+// Presence of C++14 language features:
+
+#define nssv_HAVE_CONSTEXPR_14 nssv_CPP14_000
+
+// Presence of C++17 language features:
+
+#define nssv_HAVE_NODISCARD nssv_CPP17_000
+
+// Presence of C++ library features:
+
+#define nssv_HAVE_STD_HASH nssv_CPP11_120
+
+// Presence of compiler intrinsics:
+
+// Providing char-type specializations for compare() and length() that
+// use compiler intrinsics can improve compile- and run-time performance.
+//
+// The challenge is in using the right combinations of builtin availability
+// and its constexpr-ness.
+//
+// | compiler | __builtin_memcmp (constexpr) | memcmp (constexpr) |
+// |----------|------------------------------|---------------------|
+// | clang | 4.0 (>= 4.0 ) | any (? ) |
+// | clang-a | 9.0 (>= 9.0 ) | any (? ) |
+// | gcc | any (constexpr) | any (? ) |
+// | msvc | >= 14.2 C++17 (>= 14.2 ) | any (? ) |
+
+#define nssv_HAVE_BUILTIN_VER ( (nssv_CPP17_000 && nssv_COMPILER_MSVC_VERSION >= 142) || nssv_COMPILER_GNUC_VERSION > 0 || nssv_COMPILER_CLANG_VERSION >= 400 || nssv_COMPILER_APPLECLANG_VERSION >= 900 )
+#define nssv_HAVE_BUILTIN_CE ( nssv_HAVE_BUILTIN_VER )
+
+#define nssv_HAVE_BUILTIN_MEMCMP ( (nssv_HAVE_CONSTEXPR_14 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_14 )
+#define nssv_HAVE_BUILTIN_STRLEN ( (nssv_HAVE_CONSTEXPR_11 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_11 )
+
+#ifdef __has_builtin
+# define nssv_HAVE_BUILTIN( x ) __has_builtin( x )
+#else
+# define nssv_HAVE_BUILTIN( x ) 0
+#endif
+
+#if nssv_HAVE_BUILTIN(__builtin_memcmp) || nssv_HAVE_BUILTIN_VER
+# define nssv_BUILTIN_MEMCMP __builtin_memcmp
+#else
+# define nssv_BUILTIN_MEMCMP memcmp
+#endif
+
+#if nssv_HAVE_BUILTIN(__builtin_strlen) || nssv_HAVE_BUILTIN_VER
+# define nssv_BUILTIN_STRLEN __builtin_strlen
+#else
+# define nssv_BUILTIN_STRLEN strlen
+#endif
+
+// C++ feature usage:
+
+#if nssv_HAVE_CONSTEXPR_11
+# define nssv_constexpr constexpr
+#else
+# define nssv_constexpr /*constexpr*/
+#endif
+
+#if nssv_HAVE_CONSTEXPR_14
+# define nssv_constexpr14 constexpr
+#else
+# define nssv_constexpr14 /*constexpr*/
+#endif
+
+#if nssv_HAVE_EXPLICIT_CONVERSION
+# define nssv_explicit explicit
+#else
+# define nssv_explicit /*explicit*/
+#endif
+
+#if nssv_HAVE_INLINE_NAMESPACE
+# define nssv_inline_ns inline
+#else
+# define nssv_inline_ns /*inline*/
+#endif
+
+#if nssv_HAVE_NOEXCEPT
+# define nssv_noexcept noexcept
+#else
+# define nssv_noexcept /*noexcept*/
+#endif
+
+//#if nssv_HAVE_REF_QUALIFIER
+//# define nssv_ref_qual &
+//# define nssv_refref_qual &&
+//#else
+//# define nssv_ref_qual /*&*/
+//# define nssv_refref_qual /*&&*/
+//#endif
+
+#if nssv_HAVE_NULLPTR
+# define nssv_nullptr nullptr
+#else
+# define nssv_nullptr NULL
+#endif
+
+#if nssv_HAVE_NODISCARD
+# define nssv_nodiscard [[nodiscard]]
+#else
+# define nssv_nodiscard /*[[nodiscard]]*/
+#endif
+
+// Additional includes:
+
+#include <algorithm>
+#include <cassert>
+#include <iterator>
+#include <limits>
+#include <string> // std::char_traits<>
+
+#if ! nssv_CONFIG_NO_STREAM_INSERTION
+# include <ostream>
+#endif
+
+#if ! nssv_CONFIG_NO_EXCEPTIONS
+# include <stdexcept>
+#endif
+
+#if nssv_CPP11_OR_GREATER
+# include <type_traits>
+#endif
+
+// Clang, GNUC, MSVC warning suppression macros:
+
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wuser-defined-literals"
+#elif nssv_COMPILER_GNUC_VERSION >= 480
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wliteral-suffix"
+#endif // __clang__
+
+#if nssv_COMPILER_MSVC_VERSION >= 140
+# define nssv_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]]
+# define nssv_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress: code) )
+# define nssv_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable: codes))
+#else
+# define nssv_SUPPRESS_MSGSL_WARNING(expr)
+# define nssv_SUPPRESS_MSVC_WARNING(code, descr)
+# define nssv_DISABLE_MSVC_WARNINGS(codes)
+#endif
+
+#if defined(__clang__)
+# define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
+#elif nssv_COMPILER_GNUC_VERSION >= 480
+# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
+#elif nssv_COMPILER_MSVC_VERSION >= 140
+# define nssv_RESTORE_WARNINGS() __pragma(warning(pop ))
+#else
+# define nssv_RESTORE_WARNINGS()
+#endif
+
+// Suppress the following MSVC (GSL) warnings:
+// - C4455, non-gsl : 'operator ""sv': literal suffix identifiers that do not
+// start with an underscore are reserved
+// - C26472, gsl::t.1 : don't use a static_cast for arithmetic conversions;
+// use brace initialization, gsl::narrow_cast or gsl::narow
+// - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead
+
+nssv_DISABLE_MSVC_WARNINGS( 4455 26481 26472 )
+//nssv_DISABLE_CLANG_WARNINGS( "-Wuser-defined-literals" )
+//nssv_DISABLE_GNUC_WARNINGS( -Wliteral-suffix )
+
+namespace nonstd { namespace sv_lite {
+
+//
+// basic_string_view declaration:
+//
+
+template
+<
+ class CharT,
+ class Traits = std::char_traits<CharT>
+>
+class basic_string_view;
+
+namespace detail {
+
+// support constexpr comparison in C++14;
+// for C++17 and later, use provided traits:
+
+template< typename CharT >
+inline nssv_constexpr14 int compare( CharT const * s1, CharT const * s2, std::size_t count )
+{
+ while ( count-- != 0 )
+ {
+ if ( *s1 < *s2 ) return -1;
+ if ( *s1 > *s2 ) return +1;
+ ++s1; ++s2;
+ }
+ return 0;
+}
+
+#if nssv_HAVE_BUILTIN_MEMCMP
+
+// specialization of compare() for char, see also generic compare() above:
+
+inline nssv_constexpr14 int compare( char const * s1, char const * s2, std::size_t count )
+{
+ return nssv_BUILTIN_MEMCMP( s1, s2, count );
+}
+
+#endif
+
+#if nssv_HAVE_BUILTIN_STRLEN
+
+// specialization of length() for char, see also generic length() further below:
+
+inline nssv_constexpr std::size_t length( char const * s )
+{
+ return nssv_BUILTIN_STRLEN( s );
+}
+
+#endif
+
+#if defined(__OPTIMIZE__)
+
+// gcc, clang provide __OPTIMIZE__
+// Expect tail call optimization to make length() non-recursive:
+
+template< typename CharT >
+inline nssv_constexpr std::size_t length( CharT * s, std::size_t result = 0 )
+{
+ return *s == '\0' ? result : length( s + 1, result + 1 );
+}
+
+#else // OPTIMIZE
+
+// non-recursive:
+
+template< typename CharT >
+inline nssv_constexpr14 std::size_t length( CharT * s )
+{
+ std::size_t result = 0;
+ while ( *s++ != '\0' )
+ {
+ ++result;
+ }
+ return result;
+}
+
+#endif // OPTIMIZE
+
+#if nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
+#if defined(__OPTIMIZE__)
+
+// gcc, clang provide __OPTIMIZE__
+// Expect tail call optimization to make search() non-recursive:
+
+template< class CharT, class Traits = std::char_traits<CharT> >
+constexpr const CharT* search( basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle )
+{
+ return haystack.starts_with( needle ) ? haystack.begin() :
+ haystack.empty() ? haystack.end() : search( haystack.substr(1), needle );
+}
+
+#else // OPTIMIZE
+
+// non-recursive:
+
+#if nssv_CONFIG_CONSTEXPR11_STD_SEARCH
+
+template< class CharT, class Traits = std::char_traits<CharT> >
+constexpr const CharT* search( basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle )
+{
+ return std::search( haystack.begin(), haystack.end(), needle.begin(), needle.end() );
+}
+
+#else // nssv_CONFIG_CONSTEXPR11_STD_SEARCH
+
+template< class CharT, class Traits = std::char_traits<CharT> >
+nssv_constexpr14 const CharT* search( basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle )
+{
+ while ( needle.size() <= haystack.size() )
+ {
+ if ( haystack.starts_with(needle) )
+ {
+ return haystack.cbegin();
+ }
+ haystack = basic_string_view<CharT, Traits>{ haystack.begin() + 1, haystack.size() - 1U };
+ }
+ return haystack.cend();
+}
+#endif // nssv_CONFIG_CONSTEXPR11_STD_SEARCH
+
+#endif // OPTIMIZE
+#endif // nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
+
+} // namespace detail
+
+//
+// basic_string_view:
+//
+
+template
+<
+ class CharT,
+ class Traits /* = std::char_traits<CharT> */
+>
+class basic_string_view
+{
+public:
+ // Member types:
+
+ typedef Traits traits_type;
+ typedef CharT value_type;
+
+ typedef CharT * pointer;
+ typedef CharT const * const_pointer;
+ typedef CharT & reference;
+ typedef CharT const & const_reference;
+
+ typedef const_pointer iterator;
+ typedef const_pointer const_iterator;
+ typedef std::reverse_iterator< const_iterator > reverse_iterator;
+ typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
+
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ // 24.4.2.1 Construction and assignment:
+
+ nssv_constexpr basic_string_view() nssv_noexcept
+ : data_( nssv_nullptr )
+ , size_( 0 )
+ {}
+
+#if nssv_CPP11_OR_GREATER
+ nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept = default;
+#else
+ nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept
+ : data_( other.data_)
+ , size_( other.size_)
+ {}
+#endif
+
+ nssv_constexpr basic_string_view( CharT const * s, size_type count ) nssv_noexcept // non-standard noexcept
+ : data_( s )
+ , size_( count )
+ {}
+
+ nssv_constexpr basic_string_view( CharT const * s) nssv_noexcept // non-standard noexcept
+ : data_( s )
+#if nssv_CPP17_OR_GREATER
+ , size_( Traits::length(s) )
+#elif nssv_CPP11_OR_GREATER
+ , size_( detail::length(s) )
+#else
+ , size_( Traits::length(s) )
+#endif
+ {}
+
+#if nssv_HAVE_NULLPTR
+# if nssv_HAVE_IS_DELETE
+ nssv_constexpr basic_string_view( std::nullptr_t ) nssv_noexcept = delete;
+# else
+ private: nssv_constexpr basic_string_view( std::nullptr_t ) nssv_noexcept; public:
+# endif
+#endif
+
+ // Assignment:
+
+#if nssv_CPP11_OR_GREATER
+ nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept = default;
+#else
+ nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept
+ {
+ data_ = other.data_;
+ size_ = other.size_;
+ return *this;
+ }
+#endif
+
+ // 24.4.2.2 Iterator support:
+
+ nssv_constexpr const_iterator begin() const nssv_noexcept { return data_; }
+ nssv_constexpr const_iterator end() const nssv_noexcept { return data_ + size_; }
+
+ nssv_constexpr const_iterator cbegin() const nssv_noexcept { return begin(); }
+ nssv_constexpr const_iterator cend() const nssv_noexcept { return end(); }
+
+ nssv_constexpr const_reverse_iterator rbegin() const nssv_noexcept { return const_reverse_iterator( end() ); }
+ nssv_constexpr const_reverse_iterator rend() const nssv_noexcept { return const_reverse_iterator( begin() ); }
+
+ nssv_constexpr const_reverse_iterator crbegin() const nssv_noexcept { return rbegin(); }
+ nssv_constexpr const_reverse_iterator crend() const nssv_noexcept { return rend(); }
+
+ // 24.4.2.3 Capacity:
+
+ nssv_constexpr size_type size() const nssv_noexcept { return size_; }
+ nssv_constexpr size_type length() const nssv_noexcept { return size_; }
+ nssv_constexpr size_type max_size() const nssv_noexcept { return (std::numeric_limits< size_type >::max)(); }
+
+ // since C++20
+ nssv_nodiscard nssv_constexpr bool empty() const nssv_noexcept
+ {
+ return 0 == size_;
+ }
+
+ // 24.4.2.4 Element access:
+
+ nssv_constexpr const_reference operator[]( size_type pos ) const
+ {
+ return data_at( pos );
+ }
+
+ nssv_constexpr14 const_reference at( size_type pos ) const
+ {
+#if nssv_CONFIG_NO_EXCEPTIONS
+ assert( pos < size() );
+#else
+ if ( pos >= size() )
+ {
+ throw std::out_of_range("nonstd::string_view::at()");
+ }
+#endif
+ return data_at( pos );
+ }
+
+ nssv_constexpr const_reference front() const { return data_at( 0 ); }
+ nssv_constexpr const_reference back() const { return data_at( size() - 1 ); }
+
+ nssv_constexpr const_pointer data() const nssv_noexcept { return data_; }
+
+ // 24.4.2.5 Modifiers:
+
+ nssv_constexpr14 void remove_prefix( size_type n )
+ {
+ assert( n <= size() );
+ data_ += n;
+ size_ -= n;
+ }
+
+ nssv_constexpr14 void remove_suffix( size_type n )
+ {
+ assert( n <= size() );
+ size_ -= n;
+ }
+
+ nssv_constexpr14 void swap( basic_string_view & other ) nssv_noexcept
+ {
+ const basic_string_view tmp(other);
+ other = *this;
+ *this = tmp;
+ }
+
+ // 24.4.2.6 String operations:
+
+ size_type copy( CharT * dest, size_type n, size_type pos = 0 ) const
+ {
+#if nssv_CONFIG_NO_EXCEPTIONS
+ assert( pos <= size() );
+#else
+ if ( pos > size() )
+ {
+ throw std::out_of_range("nonstd::string_view::copy()");
+ }
+#endif
+ const size_type rlen = (std::min)( n, size() - pos );
+
+ (void) Traits::copy( dest, data() + pos, rlen );
+
+ return rlen;
+ }
+
+ nssv_constexpr14 basic_string_view substr( size_type pos = 0, size_type n = npos ) const
+ {
+#if nssv_CONFIG_NO_EXCEPTIONS
+ assert( pos <= size() );
+#else
+ if ( pos > size() )
+ {
+ throw std::out_of_range("nonstd::string_view::substr()");
+ }
+#endif
+ return basic_string_view( data() + pos, (std::min)( n, size() - pos ) );
+ }
+
+ // compare(), 6x:
+
+ nssv_constexpr14 int compare( basic_string_view other ) const nssv_noexcept // (1)
+ {
+#if nssv_CPP17_OR_GREATER
+ if ( const int result = Traits::compare( data(), other.data(), (std::min)( size(), other.size() ) ) )
+#else
+ if ( const int result = detail::compare( data(), other.data(), (std::min)( size(), other.size() ) ) )
+#endif
+ {
+ return result;
+ }
+
+ return size() == other.size() ? 0 : size() < other.size() ? -1 : 1;
+ }
+
+ nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other ) const // (2)
+ {
+ return substr( pos1, n1 ).compare( other );
+ }
+
+ nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other, size_type pos2, size_type n2 ) const // (3)
+ {
+ return substr( pos1, n1 ).compare( other.substr( pos2, n2 ) );
+ }
+
+ nssv_constexpr int compare( CharT const * s ) const // (4)
+ {
+ return compare( basic_string_view( s ) );
+ }
+
+ nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s ) const // (5)
+ {
+ return substr( pos1, n1 ).compare( basic_string_view( s ) );
+ }
+
+ nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s, size_type n2 ) const // (6)
+ {
+ return substr( pos1, n1 ).compare( basic_string_view( s, n2 ) );
+ }
+
+ // 24.4.2.7 Searching:
+
+ // starts_with(), 3x, since C++20:
+
+ nssv_constexpr bool starts_with( basic_string_view v ) const nssv_noexcept // (1)
+ {
+ return size() >= v.size() && compare( 0, v.size(), v ) == 0;
+ }
+
+ nssv_constexpr bool starts_with( CharT c ) const nssv_noexcept // (2)
+ {
+ return starts_with( basic_string_view( &c, 1 ) );
+ }
+
+ nssv_constexpr bool starts_with( CharT const * s ) const // (3)
+ {
+ return starts_with( basic_string_view( s ) );
+ }
+
+ // ends_with(), 3x, since C++20:
+
+ nssv_constexpr bool ends_with( basic_string_view v ) const nssv_noexcept // (1)
+ {
+ return size() >= v.size() && compare( size() - v.size(), npos, v ) == 0;
+ }
+
+ nssv_constexpr bool ends_with( CharT c ) const nssv_noexcept // (2)
+ {
+ return ends_with( basic_string_view( &c, 1 ) );
+ }
+
+ nssv_constexpr bool ends_with( CharT const * s ) const // (3)
+ {
+ return ends_with( basic_string_view( s ) );
+ }
+
+ // find(), 4x:
+
+ nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
+ {
+ return assert( v.size() == 0 || v.data() != nssv_nullptr )
+ , pos >= size()
+ ? npos : to_pos(
+#if nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
+ detail::search( substr(pos), v )
+#else
+ std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq )
+#endif
+ );
+ }
+
+ nssv_constexpr size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
+ {
+ return find( basic_string_view( &c, 1 ), pos );
+ }
+
+ nssv_constexpr size_type find( CharT const * s, size_type pos, size_type n ) const // (3)
+ {
+ return find( basic_string_view( s, n ), pos );
+ }
+
+ nssv_constexpr size_type find( CharT const * s, size_type pos = 0 ) const // (4)
+ {
+ return find( basic_string_view( s ), pos );
+ }
+
+ // rfind(), 4x:
+
+ nssv_constexpr14 size_type rfind( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1)
+ {
+ if ( size() < v.size() )
+ {
+ return npos;
+ }
+
+ if ( v.empty() )
+ {
+ return (std::min)( size(), pos );
+ }
+
+ const_iterator last = cbegin() + (std::min)( size() - v.size(), pos ) + v.size();
+ const_iterator result = std::find_end( cbegin(), last, v.cbegin(), v.cend(), Traits::eq );
+
+ return result != last ? size_type( result - cbegin() ) : npos;
+ }
+
+ nssv_constexpr14 size_type rfind( CharT c, size_type pos = npos ) const nssv_noexcept // (2)
+ {
+ return rfind( basic_string_view( &c, 1 ), pos );
+ }
+
+ nssv_constexpr14 size_type rfind( CharT const * s, size_type pos, size_type n ) const // (3)
+ {
+ return rfind( basic_string_view( s, n ), pos );
+ }
+
+ nssv_constexpr14 size_type rfind( CharT const * s, size_type pos = npos ) const // (4)
+ {
+ return rfind( basic_string_view( s ), pos );
+ }
+
+ // find_first_of(), 4x:
+
+ nssv_constexpr size_type find_first_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
+ {
+ return pos >= size()
+ ? npos
+ : to_pos( std::find_first_of( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
+ }
+
+ nssv_constexpr size_type find_first_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
+ {
+ return find_first_of( basic_string_view( &c, 1 ), pos );
+ }
+
+ nssv_constexpr size_type find_first_of( CharT const * s, size_type pos, size_type n ) const // (3)
+ {
+ return find_first_of( basic_string_view( s, n ), pos );
+ }
+
+ nssv_constexpr size_type find_first_of( CharT const * s, size_type pos = 0 ) const // (4)
+ {
+ return find_first_of( basic_string_view( s ), pos );
+ }
+
+ // find_last_of(), 4x:
+
+ nssv_constexpr size_type find_last_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1)
+ {
+ return empty()
+ ? npos
+ : pos >= size()
+ ? find_last_of( v, size() - 1 )
+ : to_pos( std::find_first_of( const_reverse_iterator( cbegin() + pos + 1 ), crend(), v.cbegin(), v.cend(), Traits::eq ) );
+ }
+
+ nssv_constexpr size_type find_last_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2)
+ {
+ return find_last_of( basic_string_view( &c, 1 ), pos );
+ }
+
+ nssv_constexpr size_type find_last_of( CharT const * s, size_type pos, size_type count ) const // (3)
+ {
+ return find_last_of( basic_string_view( s, count ), pos );
+ }
+
+ nssv_constexpr size_type find_last_of( CharT const * s, size_type pos = npos ) const // (4)
+ {
+ return find_last_of( basic_string_view( s ), pos );
+ }
+
+ // find_first_not_of(), 4x:
+
+ nssv_constexpr size_type find_first_not_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
+ {
+ return pos >= size()
+ ? npos
+ : to_pos( std::find_if( cbegin() + pos, cend(), not_in_view( v ) ) );
+ }
+
+ nssv_constexpr size_type find_first_not_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
+ {
+ return find_first_not_of( basic_string_view( &c, 1 ), pos );
+ }
+
+ nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos, size_type count ) const // (3)
+ {
+ return find_first_not_of( basic_string_view( s, count ), pos );
+ }
+
+ nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos = 0 ) const // (4)
+ {
+ return find_first_not_of( basic_string_view( s ), pos );
+ }
+
+ // find_last_not_of(), 4x:
+
+ nssv_constexpr size_type find_last_not_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1)
+ {
+ return empty()
+ ? npos
+ : pos >= size()
+ ? find_last_not_of( v, size() - 1 )
+ : to_pos( std::find_if( const_reverse_iterator( cbegin() + pos + 1 ), crend(), not_in_view( v ) ) );
+ }
+
+ nssv_constexpr size_type find_last_not_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2)
+ {
+ return find_last_not_of( basic_string_view( &c, 1 ), pos );
+ }
+
+ nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos, size_type count ) const // (3)
+ {
+ return find_last_not_of( basic_string_view( s, count ), pos );
+ }
+
+ nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos = npos ) const // (4)
+ {
+ return find_last_not_of( basic_string_view( s ), pos );
+ }
+
+ // Constants:
+
+#if nssv_CPP17_OR_GREATER
+ static nssv_constexpr size_type npos = size_type(-1);
+#elif nssv_CPP11_OR_GREATER
+ enum : size_type { npos = size_type(-1) };
+#else
+ enum { npos = size_type(-1) };
+#endif
+
+private:
+ struct not_in_view
+ {
+ const basic_string_view v;
+
+ nssv_constexpr explicit not_in_view( basic_string_view v_ ) : v( v_ ) {}
+
+ nssv_constexpr bool operator()( CharT c ) const
+ {
+ return npos == v.find_first_of( c );
+ }
+ };
+
+ nssv_constexpr size_type to_pos( const_iterator it ) const
+ {
+ return it == cend() ? npos : size_type( it - cbegin() );
+ }
+
+ nssv_constexpr size_type to_pos( const_reverse_iterator it ) const
+ {
+ return it == crend() ? npos : size_type( crend() - it - 1 );
+ }
+
+ nssv_constexpr const_reference data_at( size_type pos ) const
+ {
+#if nssv_BETWEEN( nssv_COMPILER_GNUC_VERSION, 1, 500 )
+ return data_[pos];
+#else
+ return assert( pos < size() ), data_[pos];
+#endif
+ }
+
+private:
+ const_pointer data_;
+ size_type size_;
+
+public:
+#if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
+
+ template< class Allocator >
+ basic_string_view( std::basic_string<CharT, Traits, Allocator> const & s ) nssv_noexcept
+ : data_( s.data() )
+ , size_( s.size() )
+ {}
+
+#if nssv_HAVE_EXPLICIT_CONVERSION
+
+ template< class Allocator >
+ explicit operator std::basic_string<CharT, Traits, Allocator>() const
+ {
+ return to_string( Allocator() );
+ }
+
+#endif // nssv_HAVE_EXPLICIT_CONVERSION
+
+#if nssv_CPP11_OR_GREATER
+
+ template< class Allocator = std::allocator<CharT> >
+ std::basic_string<CharT, Traits, Allocator>
+ to_string( Allocator const & a = Allocator() ) const
+ {
+ return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
+ }
+
+#else
+
+ std::basic_string<CharT, Traits>
+ to_string() const
+ {
+ return std::basic_string<CharT, Traits>( begin(), end() );
+ }
+
+ template< class Allocator >
+ std::basic_string<CharT, Traits, Allocator>
+ to_string( Allocator const & a ) const
+ {
+ return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
+ }
+
+#endif // nssv_CPP11_OR_GREATER
+
+#endif // nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
+};
+
+//
+// Non-member functions:
+//
+
+// 24.4.3 Non-member comparison functions:
+// lexicographically compare two string views (function template):
+
+template< class CharT, class Traits >
+nssv_constexpr bool operator== (
+ basic_string_view <CharT, Traits> lhs,
+ basic_string_view <CharT, Traits> rhs ) nssv_noexcept
+{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
+
+template< class CharT, class Traits >
+nssv_constexpr bool operator!= (
+ basic_string_view <CharT, Traits> lhs,
+ basic_string_view <CharT, Traits> rhs ) nssv_noexcept
+{ return !( lhs == rhs ); }
+
+template< class CharT, class Traits >
+nssv_constexpr bool operator< (
+ basic_string_view <CharT, Traits> lhs,
+ basic_string_view <CharT, Traits> rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) < 0; }
+
+template< class CharT, class Traits >
+nssv_constexpr bool operator<= (
+ basic_string_view <CharT, Traits> lhs,
+ basic_string_view <CharT, Traits> rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) <= 0; }
+
+template< class CharT, class Traits >
+nssv_constexpr bool operator> (
+ basic_string_view <CharT, Traits> lhs,
+ basic_string_view <CharT, Traits> rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) > 0; }
+
+template< class CharT, class Traits >
+nssv_constexpr bool operator>= (
+ basic_string_view <CharT, Traits> lhs,
+ basic_string_view <CharT, Traits> rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) >= 0; }
+
+// Let S be basic_string_view<CharT, Traits>, and sv be an instance of S.
+// Implementations shall provide sufficient additional overloads marked
+// constexpr and noexcept so that an object t with an implicit conversion
+// to S can be compared according to Table 67.
+
+#if ! nssv_CPP11_OR_GREATER || nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 100, 141 )
+
+// accommodate for older compilers:
+
+// ==
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator==(
+ basic_string_view<CharT, Traits> lhs,
+ CharT const * rhs ) nssv_noexcept
+{ return lhs.size() == detail::length( rhs ) && lhs.compare( rhs ) == 0; }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator==(
+ CharT const * lhs,
+ basic_string_view<CharT, Traits> rhs ) nssv_noexcept
+{ return detail::length( lhs ) == rhs.size() && rhs.compare( lhs ) == 0; }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator==(
+ basic_string_view<CharT, Traits> lhs,
+ std::basic_string<CharT, Traits> rhs ) nssv_noexcept
+{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator==(
+ std::basic_string<CharT, Traits> rhs,
+ basic_string_view<CharT, Traits> lhs ) nssv_noexcept
+{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
+
+// !=
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator!=(
+ basic_string_view<CharT, Traits> lhs,
+ CharT const * rhs ) nssv_noexcept
+{ return !( lhs == rhs ); }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator!=(
+ CharT const * lhs,
+ basic_string_view<CharT, Traits> rhs ) nssv_noexcept
+{ return !( lhs == rhs ); }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator!=(
+ basic_string_view<CharT, Traits> lhs,
+ std::basic_string<CharT, Traits> rhs ) nssv_noexcept
+{ return !( lhs == rhs ); }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator!=(
+ std::basic_string<CharT, Traits> rhs,
+ basic_string_view<CharT, Traits> lhs ) nssv_noexcept
+{ return !( lhs == rhs ); }
+
+// <
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator<(
+ basic_string_view<CharT, Traits> lhs,
+ CharT const * rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) < 0; }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator<(
+ CharT const * lhs,
+ basic_string_view<CharT, Traits> rhs ) nssv_noexcept
+{ return rhs.compare( lhs ) > 0; }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator<(
+ basic_string_view<CharT, Traits> lhs,
+ std::basic_string<CharT, Traits> rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) < 0; }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator<(
+ std::basic_string<CharT, Traits> rhs,
+ basic_string_view<CharT, Traits> lhs ) nssv_noexcept
+{ return rhs.compare( lhs ) > 0; }
+
+// <=
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator<=(
+ basic_string_view<CharT, Traits> lhs,
+ CharT const * rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) <= 0; }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator<=(
+ CharT const * lhs,
+ basic_string_view<CharT, Traits> rhs ) nssv_noexcept
+{ return rhs.compare( lhs ) >= 0; }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator<=(
+ basic_string_view<CharT, Traits> lhs,
+ std::basic_string<CharT, Traits> rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) <= 0; }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator<=(
+ std::basic_string<CharT, Traits> rhs,
+ basic_string_view<CharT, Traits> lhs ) nssv_noexcept
+{ return rhs.compare( lhs ) >= 0; }
+
+// >
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator>(
+ basic_string_view<CharT, Traits> lhs,
+ CharT const * rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) > 0; }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator>(
+ CharT const * lhs,
+ basic_string_view<CharT, Traits> rhs ) nssv_noexcept
+{ return rhs.compare( lhs ) < 0; }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator>(
+ basic_string_view<CharT, Traits> lhs,
+ std::basic_string<CharT, Traits> rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) > 0; }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator>(
+ std::basic_string<CharT, Traits> rhs,
+ basic_string_view<CharT, Traits> lhs ) nssv_noexcept
+{ return rhs.compare( lhs ) < 0; }
+
+// >=
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator>=(
+ basic_string_view<CharT, Traits> lhs,
+ CharT const * rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) >= 0; }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator>=(
+ CharT const * lhs,
+ basic_string_view<CharT, Traits> rhs ) nssv_noexcept
+{ return rhs.compare( lhs ) <= 0; }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator>=(
+ basic_string_view<CharT, Traits> lhs,
+ std::basic_string<CharT, Traits> rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) >= 0; }
+
+template< class CharT, class Traits>
+nssv_constexpr bool operator>=(
+ std::basic_string<CharT, Traits> rhs,
+ basic_string_view<CharT, Traits> lhs ) nssv_noexcept
+{ return rhs.compare( lhs ) <= 0; }
+
+#else // newer compilers:
+
+#define nssv_BASIC_STRING_VIEW_I(T,U) typename std::decay< basic_string_view<T,U> >::type
+
+#if defined(_MSC_VER) // issue 40
+# define nssv_MSVC_ORDER(x) , int=x
+#else
+# define nssv_MSVC_ORDER(x) /*, int=x*/
+#endif
+
+// ==
+
+template< class CharT, class Traits nssv_MSVC_ORDER(1) >
+nssv_constexpr bool operator==(
+ basic_string_view <CharT, Traits> lhs,
+ nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs ) nssv_noexcept
+{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
+
+template< class CharT, class Traits nssv_MSVC_ORDER(2) >
+nssv_constexpr bool operator==(
+ nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
+ basic_string_view <CharT, Traits> rhs ) nssv_noexcept
+{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
+
+// !=
+
+template< class CharT, class Traits nssv_MSVC_ORDER(1) >
+nssv_constexpr bool operator!= (
+ basic_string_view < CharT, Traits > lhs,
+ nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
+{ return !( lhs == rhs ); }
+
+template< class CharT, class Traits nssv_MSVC_ORDER(2) >
+nssv_constexpr bool operator!= (
+ nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
+ basic_string_view < CharT, Traits > rhs ) nssv_noexcept
+{ return !( lhs == rhs ); }
+
+// <
+
+template< class CharT, class Traits nssv_MSVC_ORDER(1) >
+nssv_constexpr bool operator< (
+ basic_string_view < CharT, Traits > lhs,
+ nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) < 0; }
+
+template< class CharT, class Traits nssv_MSVC_ORDER(2) >
+nssv_constexpr bool operator< (
+ nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
+ basic_string_view < CharT, Traits > rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) < 0; }
+
+// <=
+
+template< class CharT, class Traits nssv_MSVC_ORDER(1) >
+nssv_constexpr bool operator<= (
+ basic_string_view < CharT, Traits > lhs,
+ nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) <= 0; }
+
+template< class CharT, class Traits nssv_MSVC_ORDER(2) >
+nssv_constexpr bool operator<= (
+ nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
+ basic_string_view < CharT, Traits > rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) <= 0; }
+
+// >
+
+template< class CharT, class Traits nssv_MSVC_ORDER(1) >
+nssv_constexpr bool operator> (
+ basic_string_view < CharT, Traits > lhs,
+ nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) > 0; }
+
+template< class CharT, class Traits nssv_MSVC_ORDER(2) >
+nssv_constexpr bool operator> (
+ nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
+ basic_string_view < CharT, Traits > rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) > 0; }
+
+// >=
+
+template< class CharT, class Traits nssv_MSVC_ORDER(1) >
+nssv_constexpr bool operator>= (
+ basic_string_view < CharT, Traits > lhs,
+ nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) >= 0; }
+
+template< class CharT, class Traits nssv_MSVC_ORDER(2) >
+nssv_constexpr bool operator>= (
+ nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
+ basic_string_view < CharT, Traits > rhs ) nssv_noexcept
+{ return lhs.compare( rhs ) >= 0; }
+
+#undef nssv_MSVC_ORDER
+#undef nssv_BASIC_STRING_VIEW_I
+
+#endif // compiler-dependent approach to comparisons
+
+// 24.4.4 Inserters and extractors:
+
+#if ! nssv_CONFIG_NO_STREAM_INSERTION
+
+namespace detail {
+
+template< class Stream >
+void write_padding( Stream & os, std::streamsize n )
+{
+ for ( std::streamsize i = 0; i < n; ++i )
+ os.rdbuf()->sputc( os.fill() );
+}
+
+template< class Stream, class View >
+Stream & write_to_stream( Stream & os, View const & sv )
+{
+ typename Stream::sentry sentry( os );
+
+ if ( !sentry )
+ return os;
+
+ const std::streamsize length = static_cast<std::streamsize>( sv.length() );
+
+ // Whether, and how, to pad:
+ const bool pad = ( length < os.width() );
+ const bool left_pad = pad && ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::right;
+
+ if ( left_pad )
+ write_padding( os, os.width() - length );
+
+ // Write span characters:
+ os.rdbuf()->sputn( sv.begin(), length );
+
+ if ( pad && !left_pad )
+ write_padding( os, os.width() - length );
+
+ // Reset output stream width:
+ os.width( 0 );
+
+ return os;
+}
+
+} // namespace detail
+
+template< class CharT, class Traits >
+std::basic_ostream<CharT, Traits> &
+operator<<(
+ std::basic_ostream<CharT, Traits>& os,
+ basic_string_view <CharT, Traits> sv )
+{
+ return detail::write_to_stream( os, sv );
+}
+
+#endif // nssv_CONFIG_NO_STREAM_INSERTION
+
+// Several typedefs for common character types are provided:
+
+typedef basic_string_view<char> string_view;
+typedef basic_string_view<wchar_t> wstring_view;
+#if nssv_HAVE_WCHAR16_T
+typedef basic_string_view<char16_t> u16string_view;
+typedef basic_string_view<char32_t> u32string_view;
+#endif
+
+}} // namespace nonstd::sv_lite
+
+//
+// 24.4.6 Suffix for basic_string_view literals:
+//
+
+#if nssv_HAVE_USER_DEFINED_LITERALS
+
+namespace nonstd {
+nssv_inline_ns namespace literals {
+nssv_inline_ns namespace string_view_literals {
+
+#if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
+
+nssv_constexpr nonstd::sv_lite::string_view operator "" sv( const char* str, size_t len ) nssv_noexcept // (1)
+{
+ return nonstd::sv_lite::string_view{ str, len };
+}
+
+nssv_constexpr nonstd::sv_lite::u16string_view operator "" sv( const char16_t* str, size_t len ) nssv_noexcept // (2)
+{
+ return nonstd::sv_lite::u16string_view{ str, len };
+}
+
+nssv_constexpr nonstd::sv_lite::u32string_view operator "" sv( const char32_t* str, size_t len ) nssv_noexcept // (3)
+{
+ return nonstd::sv_lite::u32string_view{ str, len };
+}
+
+nssv_constexpr nonstd::sv_lite::wstring_view operator "" sv( const wchar_t* str, size_t len ) nssv_noexcept // (4)
+{
+ return nonstd::sv_lite::wstring_view{ str, len };
+}
+
+#endif // nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
+
+#if nssv_CONFIG_USR_SV_OPERATOR
+
+nssv_constexpr nonstd::sv_lite::string_view operator "" _sv( const char* str, size_t len ) nssv_noexcept // (1)
+{
+ return nonstd::sv_lite::string_view{ str, len };
+}
+
+nssv_constexpr nonstd::sv_lite::u16string_view operator "" _sv( const char16_t* str, size_t len ) nssv_noexcept // (2)
+{
+ return nonstd::sv_lite::u16string_view{ str, len };
+}
+
+nssv_constexpr nonstd::sv_lite::u32string_view operator "" _sv( const char32_t* str, size_t len ) nssv_noexcept // (3)
+{
+ return nonstd::sv_lite::u32string_view{ str, len };
+}
+
+nssv_constexpr nonstd::sv_lite::wstring_view operator "" _sv( const wchar_t* str, size_t len ) nssv_noexcept // (4)
+{
+ return nonstd::sv_lite::wstring_view{ str, len };
+}
+
+#endif // nssv_CONFIG_USR_SV_OPERATOR
+
+}}} // namespace nonstd::literals::string_view_literals
+
+#endif
+
+//
+// Extensions for std::string:
+//
+
+#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
+
+namespace nonstd {
+namespace sv_lite {
+
+// Exclude MSVC 14 (19.00): it yields ambiguous to_string():
+
+#if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140
+
+template< class CharT, class Traits, class Allocator = std::allocator<CharT> >
+std::basic_string<CharT, Traits, Allocator>
+to_string( basic_string_view<CharT, Traits> v, Allocator const & a = Allocator() )
+{
+ return std::basic_string<CharT,Traits, Allocator>( v.begin(), v.end(), a );
+}
+
+#else
+
+template< class CharT, class Traits >
+std::basic_string<CharT, Traits>
+to_string( basic_string_view<CharT, Traits> v )
+{
+ return std::basic_string<CharT, Traits>( v.begin(), v.end() );
+}
+
+template< class CharT, class Traits, class Allocator >
+std::basic_string<CharT, Traits, Allocator>
+to_string( basic_string_view<CharT, Traits> v, Allocator const & a )
+{
+ return std::basic_string<CharT, Traits, Allocator>( v.begin(), v.end(), a );
+}
+
+#endif // nssv_CPP11_OR_GREATER
+
+template< class CharT, class Traits, class Allocator >
+basic_string_view<CharT, Traits>
+to_string_view( std::basic_string<CharT, Traits, Allocator> const & s )
+{
+ return basic_string_view<CharT, Traits>( s.data(), s.size() );
+}
+
+}} // namespace nonstd::sv_lite
+
+#endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
+
+//
+// make types and algorithms available in namespace nonstd:
+//
+
+namespace nonstd {
+
+using sv_lite::basic_string_view;
+using sv_lite::string_view;
+using sv_lite::wstring_view;
+
+#if nssv_HAVE_WCHAR16_T
+using sv_lite::u16string_view;
+#endif
+#if nssv_HAVE_WCHAR32_T
+using sv_lite::u32string_view;
+#endif
+
+// literal "sv"
+
+using sv_lite::operator==;
+using sv_lite::operator!=;
+using sv_lite::operator<;
+using sv_lite::operator<=;
+using sv_lite::operator>;
+using sv_lite::operator>=;
+
+#if ! nssv_CONFIG_NO_STREAM_INSERTION
+using sv_lite::operator<<;
+#endif
+
+#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
+using sv_lite::to_string;
+using sv_lite::to_string_view;
+#endif
+
+} // namespace nonstd
+
+// 24.4.5 Hash support (C++11):
+
+// Note: The hash value of a string view object is equal to the hash value of
+// the corresponding string object.
+
+#if nssv_HAVE_STD_HASH
+
+#include <functional>
+
+namespace std {
+
+template<>
+struct hash< nonstd::string_view >
+{
+public:
+ std::size_t operator()( nonstd::string_view v ) const nssv_noexcept
+ {
+ return std::hash<std::string>()( std::string( v.data(), v.size() ) );
+ }
+};
+
+template<>
+struct hash< nonstd::wstring_view >
+{
+public:
+ std::size_t operator()( nonstd::wstring_view v ) const nssv_noexcept
+ {
+ return std::hash<std::wstring>()( std::wstring( v.data(), v.size() ) );
+ }
+};
+
+template<>
+struct hash< nonstd::u16string_view >
+{
+public:
+ std::size_t operator()( nonstd::u16string_view v ) const nssv_noexcept
+ {
+ return std::hash<std::u16string>()( std::u16string( v.data(), v.size() ) );
+ }
+};
+
+template<>
+struct hash< nonstd::u32string_view >
+{
+public:
+ std::size_t operator()( nonstd::u32string_view v ) const nssv_noexcept
+ {
+ return std::hash<std::u32string>()( std::u32string( v.data(), v.size() ) );
+ }
+};
+
+} // namespace std
+
+#endif // nssv_HAVE_STD_HASH
+
+nssv_RESTORE_WARNINGS()
+
+#endif // nssv_HAVE_STD_STRING_VIEW
+#endif // NONSTD_SV_LITE_H_INCLUDED
+++ /dev/null
-/*
- * Copyright (c) 2016 Matthew Rodusek <http://rodusek.me>
- *
- * SPDX-License-Identifier: MIT
- */
-
-/**
- * \file string_view.hpp
- *
- * \brief This header contains the definition of the string_view type, as
- * described by the C++17 standard.
- *
- * \author Matthew Rodusek (matthew.rodusek@gmail.com)
- * \copyright Matthew Rodusek
- */
-
-/*
- * The MIT License (MIT)
- *
- * Licensed under the MIT License <http://opensource.org/licenses/MIT>.
- * Copyright (c) 2016 Matthew Rodusek <http://rodusek.me>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-#ifndef BPSTD_STRING_VIEW_HPP
-#define BPSTD_STRING_VIEW_HPP
-
-#include <algorithm> // std::
-#include <string> // std::char_traits
-#include <ostream> // std::basic_ostream
-#include <cstddef> // std::size_t
-#include <memory> // std::allocator
-#include <stdexcept> // std::out_of_range
-#include <iterator> // std::reverse_iterator
-namespace bpstd { // back-port std
-
- ////////////////////////////////////////////////////////////////////////////
- /// \brief A wrapper around non-owned strings.
- ///
- /// This is an implementation of the C++17 string_view proposal
- ///
- /// \ingroup core
- ////////////////////////////////////////////////////////////////////////////
- template<
- typename CharT,
- typename Traits = std::char_traits<CharT>
- >
- class basic_string_view final
- {
- //------------------------------------------------------------------------
- // Public Member Types
- //------------------------------------------------------------------------
- public:
-
- using char_type = CharT;
- using traits_type = Traits;
- using size_type = std::size_t;
-
- using value_type = CharT;
- using reference = value_type&;
- using const_reference = const value_type&;
- using pointer = value_type*;
- using const_pointer = const value_type*;
-
- using iterator = const CharT*;
- using const_iterator = const CharT*;
- using reverse_iterator = std::reverse_iterator<iterator>;
- using const_reverse_iterator = std::reverse_iterator<const_iterator>;
-
- //------------------------------------------------------------------------
- // Public Members
- //------------------------------------------------------------------------
- public:
-
- static constexpr size_type npos = size_type(-1);
-
- //------------------------------------------------------------------------
- // Constructors
- //------------------------------------------------------------------------
- public:
-
- /// \brief Default constructs a basic_string_view without any content
- constexpr basic_string_view() noexcept;
-
- /// \brief Constructs a basic_string_view by copying another one
- ///
- /// \param other the string view being copied
- constexpr basic_string_view(const basic_string_view& other) noexcept = default;
-
- /// \brief Constructs a basic_string_view by moving anothe rone
- ///
- /// \param other the string view being moved
- constexpr basic_string_view(basic_string_view&& other) noexcept = default;
-
- /// \brief Constructs a basic_string_view from a std::basic_string
- ///
- /// \param str the string to view
- template<typename Allocator>
- basic_string_view(const std::basic_string<CharT,Traits,Allocator>& str) noexcept;
-
- /// \brief Constructs a basic_string_view from an ansi-string
- ///
- /// \param str the string to view
- constexpr basic_string_view(const char_type* str) noexcept;
-
- /// \brief Constructs a basic_string_view from an ansi string of a given size
- ///
- /// \param str the string to view
- /// \param count the size of the string
- constexpr basic_string_view(const char_type* str, size_type count) noexcept;
-
- //------------------------------------------------------------------------
- // Assignment
- //------------------------------------------------------------------------
- public:
-
- /// \brief Assigns a basic_string_view from an ansi-string
- ///
- /// \param view the string to view
- /// \return reference to \c (*this)
- basic_string_view& operator=(const basic_string_view& view) = default;
-
- //------------------------------------------------------------------------
- // Capacity
- //------------------------------------------------------------------------
- public:
-
- /// \brief Returns the length of the string, in terms of bytes
- ///
- /// \return the length of the string, in terms of bytes
- constexpr size_type size() const noexcept;
-
- /// \copydoc basic_string_view::size
- constexpr size_type length() const noexcept;
-
- /// \brief The largest possible number of char-like objects that can be
- /// referred to by a basic_string_view.
- /// \return Maximum number of characters
- constexpr size_type max_size() const noexcept;
-
- /// \brief Returns whether the basic_string_view is empty
- /// (i.e. whether its length is 0).
- ///
- /// \return whether the basic_string_view is empty
- constexpr bool empty() const noexcept;
-
- //------------------------------------------------------------------------
- // Element Access
- //------------------------------------------------------------------------
- public:
-
- /// \brief Gets the ansi-string of the current basic_string_view
- ///
- /// \return the ansi-string pointer
- constexpr const char_type* c_str() const noexcept;
-
- /// \brief Gets the data of the current basic_string_view
- ///
- /// \note This is an alias of #c_str
- ///
- /// \return the data this basic_string_view contains
- constexpr const char_type* data() const noexcept;
-
- /// \brief Accesses the element at index \p pos
- ///
- /// \param pos the index to access
- /// \return const reference to the character
- constexpr const_reference operator[](size_type pos) const noexcept;
-
- /// \brief Accesses the element at index \p pos
- ///
- /// \param pos the index to access
- /// \return const reference to the character
- constexpr const_reference at(size_type pos) const;
-
- /// \brief Access the first character of the string
- ///
- /// \note Undefined behavior if basic_string_view is empty
- ///
- /// \return reference to the first character of the string
- constexpr const_reference front() const noexcept;
-
- /// \brief References the last character of the string
- ///
- /// \note Undefined behavior if basic_string_view is empty
- ///
- /// \return reference to the last character of the string
- constexpr const_reference back() const noexcept;
-
- //------------------------------------------------------------------------
- // Modifiers
- //------------------------------------------------------------------------
- public:
-
- /// \brief Moves the start of the view forward by n characters.
- ///
- /// The behavior is undefined if n > size().
- ///
- /// \param n number of characters to remove from the start of the view
- void remove_prefix(size_type n) noexcept;
-
- /// \brief Moves the end of the view back by n characters.
- ///
- /// The behavior is undefined if n > size().
- ///
- /// \param n number of characters to remove from the end of the view
- void remove_suffix(size_type n) noexcept;
-
- /// \brief Exchanges the view with that of v.
- ///
- /// \param v view to swap with
- void swap(basic_string_view& v) noexcept;
-
- //------------------------------------------------------------------------
- // Conversions
- //------------------------------------------------------------------------
- public:
-
- /// \brief Creates a basic_string with a copy of the content of the current view.
- ///
- /// \tparam Allocator type used to allocate internal storage
- /// \param a Allocator instance to use for allocating the new string
- ///
- /// \return A basic_string containing a copy of the characters of the current view.
- template<class Allocator = std::allocator<CharT>>
- constexpr std::basic_string<CharT, Traits, Allocator>
- to_string(const Allocator& a = Allocator()) const;
-
- /// \copydoc basic_string_view::to_string
- template<class Allocator>
- explicit constexpr operator std::basic_string<CharT, Traits, Allocator>() const;
-
- //------------------------------------------------------------------------
- // Operations
- //------------------------------------------------------------------------
- public:
-
- /// \brief Copies the substring [pos, pos + rcount) to the character string pointed
- /// to by dest, where rcount is the smaller of count and size() - pos.
- ///
- /// \param dest pointer to the destination character string
- /// \param count requested substring length
- /// \param pos position of the first character
- size_type copy( char_type* dest,
- size_type count = npos,
- size_type pos = 0 ) const;
-
- /// \brief Returns a substring of this viewed string
- ///
- /// \param pos the position of the first character in the substring
- /// \param len the length of the substring
- /// \return the created substring
- basic_string_view substr(size_t pos = 0, size_t len = npos) const;
-
- //------------------------------------------------------------------------
-
- /// \brief Compares two character sequences
- ///
- /// \param v view to compare
- /// \return negative value if this view is less than the other character
- /// sequence, zero if the both character sequences are equal, positive
- /// value if this view is greater than the other character sequence.
- int compare(basic_string_view v) const noexcept;
-
- /// \brief Compares two character sequences
- ///
- /// \param pos position of the first character in this view to compare
- /// \param count number of characters of this view to compare
- /// \param v view to compare
- /// \return negative value if this view is less than the other character
- /// sequence, zero if the both character sequences are equal, positive
- /// value if this view is greater than the other character sequence.
- int compare(size_type pos, size_type count, basic_string_view v) const;
-
- /// \brief Compares two character sequences
- ///
- /// \param pos1 position of the first character in this view to compare
- /// \param count1 number of characters of this view to compare
- /// \param v view to compare
- /// \param pos2 position of the second character in this view to compare
- /// \param count2 number of characters of the given view to compare
- /// \return negative value if this view is less than the other character
- /// sequence, zero if the both character sequences are equal, positive
- /// value if this view is greater than the other character sequence.
- int compare( size_type pos1, size_type count1, basic_string_view v,
- size_type pos2, size_type count2 ) const;
-
- /// \brief Compares two character sequences
- ///
- /// \param s pointer to the character string to compare to
- /// \return negative value if this view is less than the other character
- /// sequence, zero if the both character sequences are equal, positive
- /// value if this view is greater than the other character sequence.
- int compare(const char_type* s) const;
-
- /// \brief Compares two character sequences
- ///
- /// \param pos position of the first character in this view to compare
- /// \param count number of characters of this view to compare
- /// \param s pointer to the character string to compare to
- /// \return negative value if this view is less than the other character
- /// sequence, zero if the both character sequences are equal, positive
- /// value if this view is greater than the other character sequence.
- int compare(size_type pos, size_type count, const char_type* s) const;
-
- /// \brief Compares two character sequences
- ///
- /// \param pos position of the first character in this view to compare
- /// \param count1 number of characters of this view to compare
- /// \param s pointer to the character string to compare to
- /// \param count2 number of characters of the given view to compare
- /// \return negative value if this view is less than the other character
- /// sequence, zero if the both character sequences are equal, positive
- /// value if this view is greater than the other character sequence.
- int compare( size_type pos, size_type count1, const char_type* s,
- size_type count2 ) const;
-
- //------------------------------------------------------------------------
-
- size_type find(basic_string_view v, size_type pos = 0) const;
-
- size_type find(char_type c, size_type pos = 0) const;
-
- size_type find(const char_type* s, size_type pos, size_type count) const;
-
- size_type find(const char_type* s, size_type pos = 0) const;
-
- //------------------------------------------------------------------------
-
- size_type rfind(basic_string_view v, size_type pos = npos) const;
-
- size_type rfind(char_type c, size_type pos = npos) const;
-
- size_type rfind(const char_type* s, size_type pos, size_type count) const;
-
- size_type rfind(const char_type* s, size_type pos = npos) const;
-
- //------------------------------------------------------------------------
-
- size_type find_first_of(basic_string_view v, size_type pos = 0) const;
-
- size_type find_first_of(char_type c, size_type pos = 0) const;
-
- size_type find_first_of(const char_type* s, size_type pos, size_type count) const;
-
- size_type find_first_of(const char_type* s, size_type pos = 0) const;
-
- //------------------------------------------------------------------------
-
- size_type find_last_of(basic_string_view v, size_type pos = npos) const;
-
- size_type find_last_of(char_type c, size_type pos = npos) const;
-
- size_type find_last_of(const char_type* s, size_type pos, size_type count) const;
-
- size_type find_last_of(const char_type* s, size_type pos = npos) const;
-
- //------------------------------------------------------------------------
-
- size_type find_first_not_of(basic_string_view v, size_type pos = 0) const;
-
- size_type find_first_not_of(char_type c, size_type pos = 0) const;
-
- size_type find_first_not_of(const char_type* s, size_type pos, size_type count) const;
-
- size_type find_first_not_of(const char_type* s, size_type pos = 0) const;
-
- //------------------------------------------------------------------------
-
- size_type find_last_not_of(basic_string_view v, size_type pos = npos) const;
-
- size_type find_last_not_of(char_type c, size_type pos = npos) const;
-
- size_type find_last_not_of(const char_type* s, size_type pos, size_type count) const;
-
- size_type find_last_not_of(const char_type* s, size_type pos = npos) const;
-
- //------------------------------------------------------------------------
- // Iterators
- //------------------------------------------------------------------------
- public:
-
- /// \{
- /// \brief Retrieves the begin iterator for this basic_string_view
- ///
- /// \return the begin iterator
- const_iterator begin() const noexcept;
- const_iterator cbegin() const noexcept;
- /// \}
-
- /// \{
- /// \brief Retrieves the end iterator for this basic_string_view
- ///
- /// \return the end iterator
- const_iterator end() const noexcept;
- const_iterator cend() const noexcept;
- /// \}
-
- /// \{
- /// \brief Retrieves the reverse begin iterator for this basic_string_view
- ///
- /// \return the reverse begin iterator
- const_reverse_iterator rbegin() const noexcept;
- const_reverse_iterator rend() const noexcept;
- /// \}
-
- /// \{
- /// \brief Retrieves the reverse end iterator for this basic_string_view
- ///
- /// \return the reverse end iterator
- const_reverse_iterator crbegin() const noexcept;
- const_reverse_iterator crend() const noexcept;
- /// \}
-
- //------------------------------------------------------------------------
- // Private Member
- //------------------------------------------------------------------------
- private:
-
- const char_type* m_str; ///< The internal string type
- size_type m_size; ///< The size of this string
-
- /// \brief Checks whether \p c is one of the characters in \p str
- ///
- /// \param c the character to check
- /// \param str the characters to compare against
- /// \return true if \p c is one of the characters in \p str
- static bool is_one_of(CharT c, basic_string_view str);
- };
-
- template <typename CharT, typename Traits>
- const typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::npos;
-
- //--------------------------------------------------------------------------
- // Public Functions
- //--------------------------------------------------------------------------
-
- /// \brief Overload for ostream output of basic_string_view
- ///
- /// \param o The output stream to print to
- /// \param str the string to print
- /// \return reference to the output stream
- template<typename CharT, typename Traits>
- std::basic_ostream<CharT,Traits>& operator<<(std::basic_ostream<CharT,Traits>& o,
- const basic_string_view<CharT,Traits>& str);
-
- template<typename CharT, typename Traits>
- void swap(basic_string_view<CharT,Traits>& lhs,
- basic_string_view<CharT,Traits>& rhs) noexcept;
-
- //--------------------------------------------------------------------------
- // Comparison Functions
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- bool operator==(const basic_string_view<CharT,Traits>& lhs,
- const basic_string_view<CharT,Traits>& rhs) noexcept;
- template<typename CharT, typename Traits>
- bool operator!=(const basic_string_view<CharT,Traits>& lhs,
- const basic_string_view<CharT,Traits>& rhs) noexcept;
- template<typename CharT, typename Traits>
- bool operator<(const basic_string_view<CharT,Traits>& lhs,
- const basic_string_view<CharT,Traits>& rhs) noexcept;
- template<typename CharT, typename Traits>
- bool operator>(const basic_string_view<CharT,Traits>& lhs,
- const basic_string_view<CharT,Traits>& rhs) noexcept;
- template<typename CharT, typename Traits>
- bool operator<=(const basic_string_view<CharT,Traits>& lhs,
- const basic_string_view<CharT,Traits>& rhs) noexcept;
- template<typename CharT, typename Traits>
- bool operator>=(const basic_string_view<CharT,Traits>& lhs,
- const basic_string_view<CharT,Traits>& rhs) noexcept;
-
- //--------------------------------------------------------------------------
- // Type Aliases
- //--------------------------------------------------------------------------
-
- using string_view = basic_string_view<char>;
- using wstring_view = basic_string_view<wchar_t>;
- using u16string_view = basic_string_view<char16_t>;
- using u32string_view = basic_string_view<char32_t>;
-
-} // namespace bpstd
-
-#ifndef BPSTD_DETAIL_STRING_VIEW_INL
-#define BPSTD_DETAIL_STRING_VIEW_INL
-
-namespace bpstd {
-
- //--------------------------------------------------------------------------
- // Constructor
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline constexpr basic_string_view<CharT,Traits>::basic_string_view()
- noexcept
- : m_str(nullptr),
- m_size(0)
- {
-
- }
-
- template<typename CharT, typename Traits>
- template<typename Allocator>
- inline basic_string_view<CharT,Traits>::basic_string_view(const std::basic_string<CharT,Traits,Allocator>& str)
- noexcept
- : m_str(str.c_str()),
- m_size(str.size())
- {
-
- }
-
- template<typename CharT, typename Traits>
- inline constexpr basic_string_view<CharT,Traits>::basic_string_view(const char_type* str)
- noexcept
- : m_str(str),
- m_size(traits_type::length(str))
- {
-
- }
-
- template<typename CharT, typename Traits>
- inline constexpr basic_string_view<CharT,Traits>::basic_string_view(const char_type* str, size_type count)
- noexcept
- : m_str(str),
- m_size(count)
- {
-
- }
-
- //--------------------------------------------------------------------------
- // Capacity
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline constexpr typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::size()
- const noexcept
- {
- return m_size;
- }
-
- template<typename CharT, typename Traits>
- inline constexpr typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::length()
- const noexcept
- {
- return size();
- }
-
- template<typename CharT, typename Traits>
- inline constexpr typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::max_size()
- const noexcept
- {
- return npos - 1;
- }
-
- template<typename CharT, typename Traits>
- inline constexpr bool basic_string_view<CharT,Traits>::empty()
- const noexcept
- {
- return m_size == 0;
- }
-
- //--------------------------------------------------------------------------
- // Element Access
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline constexpr const typename basic_string_view<CharT,Traits>::char_type*
- basic_string_view<CharT,Traits>::c_str()
- const noexcept
- {
- return m_str;
- }
-
- template<typename CharT, typename Traits>
- inline constexpr const typename basic_string_view<CharT,Traits>::char_type*
- basic_string_view<CharT,Traits>::data()
- const noexcept
- {
- return m_str;
- }
-
- template<typename CharT, typename Traits>
- inline constexpr typename basic_string_view<CharT,Traits>::const_reference
- basic_string_view<CharT,Traits>::operator[](size_type pos)
- const noexcept
- {
- return m_str[pos];
- }
-
- template<typename CharT, typename Traits>
- inline constexpr typename basic_string_view<CharT,Traits>::const_reference
- basic_string_view<CharT,Traits>::at(size_type pos)
- const
- {
- return pos < m_size ? m_str[pos] : throw std::out_of_range("Input out of range in basic_string_view::at"), m_str[pos];
- }
-
- template<typename CharT, typename Traits>
- inline constexpr typename basic_string_view<CharT,Traits>::const_reference
- basic_string_view<CharT,Traits>::front( )
- const noexcept
- {
- return *m_str;
- }
-
- template<typename CharT, typename Traits>
- inline constexpr typename basic_string_view<CharT,Traits>::const_reference
- basic_string_view<CharT,Traits>::back( )
- const noexcept
- {
- return m_str[m_size-1];
- }
-
- //--------------------------------------------------------------------------
- // Modifiers
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline void
- basic_string_view<CharT,Traits>::remove_prefix(size_type n)
- noexcept
- {
- m_str += n, m_size -= n;
- }
-
- template<typename CharT, typename Traits>
- inline void
- basic_string_view<CharT,Traits>::remove_suffix(size_type n)
- noexcept
- {
- m_size -= n;
- }
-
- template<typename CharT, typename Traits>
- inline void
- basic_string_view<CharT,Traits>::swap(basic_string_view& v)
- noexcept
- {
- using std::swap;
- swap(m_size,v.m_size);
- swap(m_str,v.m_str);
- }
-
- //--------------------------------------------------------------------------
- // Conversions
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- template<class Allocator>
- inline constexpr std::basic_string<CharT, Traits, Allocator>
- basic_string_view<CharT,Traits>::to_string(const Allocator& a)
- const
- {
- return std::basic_string<CharT,Traits,Allocator>(m_str, m_size, a);
- }
-
- template<typename CharT, typename Traits>
- template<class Allocator>
- inline constexpr basic_string_view<CharT,Traits>::operator
- std::basic_string<CharT, Traits, Allocator>()
- const
- {
- return std::basic_string<CharT,Traits,Allocator>(m_str, m_size);
- }
-
- //--------------------------------------------------------------------------
- // String Operations
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::copy(char_type* dest,
- size_type count,
- size_type pos)
- const
- {
- if(pos >= m_size) {
- throw std::out_of_range("Index out of range in basic_string_view::copy");
- }
-
- const size_type rcount = std::min(m_size - pos,count+1);
- std::copy( m_str + pos, m_str + pos + rcount, dest);
- return rcount;
- }
-
- template<typename CharT, typename Traits>
- inline basic_string_view<CharT,Traits>
- basic_string_view<CharT,Traits>::substr(size_type pos,
- size_type len)
- const
- {
- const size_type max_length = pos > m_size ? 0 : m_size - pos;
-
- if (pos > size()) {
- throw std::out_of_range("Index out of range in basic_string_view::substr");
- }
-
- return basic_string_view(m_str + pos, std::min(len, max_length) );
- }
-
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline int basic_string_view<CharT,Traits>::compare(basic_string_view v)
- const noexcept
- {
- const size_type rlen = std::min(m_size,v.m_size);
- const int compare = Traits::compare(m_str,v.m_str,rlen);
-
- return (compare ? compare : (m_size < v.m_size ? -1 : (m_size > v.m_size ? 1 : 0)));
- }
-
- template<typename CharT, typename Traits>
- inline int basic_string_view<CharT,Traits>::compare(size_type pos,
- size_type count,
- basic_string_view v)
- const
- {
- return substr(pos,count).compare(v);
- }
-
- template<typename CharT, typename Traits>
- inline int basic_string_view<CharT,Traits>::compare(size_type pos1,
- size_type count1,
- basic_string_view v,
- size_type pos2,
- size_type count2)
- const
- {
- return substr(pos1,count1).compare(v.substr(pos2,count2));
- }
-
- template<typename CharT, typename Traits>
- inline int basic_string_view<CharT,Traits>::compare(const char_type* s)
- const
- {
- return compare(basic_string_view<CharT,Traits>(s));
- }
-
- template<typename CharT, typename Traits>
- inline int basic_string_view<CharT,Traits>::compare(size_type pos,
- size_type count,
- const char_type* s)
- const
- {
- return substr(pos, count).compare(basic_string_view<CharT,Traits>(s));
- }
-
- template<typename CharT, typename Traits>
- inline int basic_string_view<CharT,Traits>::compare(size_type pos,
- size_type count1,
- const char_type* s,
- size_type count2)
- const
- {
- return substr(pos, count1).compare(basic_string_view<CharT,Traits>(s, count2));
- }
-
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find(basic_string_view v,
- size_type pos)
- const
- {
- // Can't find a substring if the substring is bigger than this
- if (pos > size()) {
- return npos;
- }
- if ((pos + v.size()) > size()) {
- return npos;
- }
-
- const auto offset = pos;
- const auto increments = size() - v.size();
-
- for (auto i = 0u; i <= increments; ++i) {
- const auto j = i + offset;
- if (substr(j, v.size()) == v) {
- return j;
- }
- }
- return npos;
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find(char_type c,
- size_type pos)
- const
- {
- return find(basic_string_view<CharT,Traits>(&c, 1), pos);
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find(const char_type* s, size_type pos,
- size_type count)
- const
- {
- return find(basic_string_view<CharT,Traits>(s, count), pos);
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find(const char_type* s,
- size_type pos)
- const
- {
- return find(basic_string_view<CharT,Traits>(s), pos);
- }
-
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::rfind(basic_string_view v,
- size_type pos)
- const
- {
- if (empty()) {
- return v.empty() ? 0u : npos;
- }
- if (v.empty()) {
- return std::min(size() - 1, pos);
- }
- if (v.size() > size()) {
- return npos;
- }
-
- auto i = std::min(pos, (size() - v.size()));
- while (i != npos) {
- if (substr(i, v.size()) == v) {
- return i;
- }
- --i;
- }
-
- return npos;
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::rfind(char_type c,
- size_type pos)
- const
- {
- return rfind(basic_string_view<CharT,Traits>(&c, 1), pos);
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::rfind(const char_type* s, size_type pos,
- size_type count)
- const
- {
- return rfind(basic_string_view<CharT,Traits>(s, count), pos);
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::rfind(const char_type* s,
- size_type pos)
- const
- {
- return rfind(basic_string_view<CharT,Traits>(s), pos);
- }
-
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_first_of(basic_string_view v,
- size_type pos)
- const
- {
- const auto max_index = size();
- for (auto i = pos; i < max_index; ++i) {
- if (is_one_of(m_str[i],v)) {
- return i;
- }
- }
-
- return npos;
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_first_of(char_type c,
- size_type pos)
- const
- {
- return find_first_of(basic_string_view<CharT,Traits>(&c, 1), pos);
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_first_of(const char_type* s, size_type pos,
- size_type count)
- const
- {
- return find_first_of(basic_string_view<CharT,Traits>(s, count), pos);
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_first_of(const char_type* s,
- size_type pos)
- const
- {
- return find_first_of(basic_string_view<CharT,Traits>(s), pos);
- }
-
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_last_of(basic_string_view v,
- size_type pos)
- const
- {
- if (empty()) {
- return npos;
- }
- const auto max_index = std::min(size() - 1, pos);
- for (auto i = 0u; i <= max_index; ++i) {
- const auto j = max_index - i;
-
- if (is_one_of(m_str[j],v)) {
- return j;
- }
- }
-
- return npos;
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_last_of(char_type c,
- size_type pos)
- const
- {
- return find_last_of(basic_string_view<CharT,Traits>(&c, 1), pos);
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_last_of(const char_type* s, size_type pos,
- size_type count)
- const
- {
- return find_last_of(basic_string_view<CharT,Traits>(s, count), pos);
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_last_of(const char_type* s,
- size_type pos)
- const
- {
- return find_last_of(basic_string_view<CharT,Traits>(s), pos);
- }
-
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_first_not_of(basic_string_view v,
- size_type pos)
- const
- {
- const auto max_index = size();
- for (auto i = pos; i < max_index; ++i) {
- if (!is_one_of(m_str[i],v)) {
- return i;
- }
- }
-
- return npos;
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_first_not_of(char_type c,
- size_type pos)
- const
- {
- return find_first_not_of(basic_string_view<CharT,Traits>(&c, 1), pos);
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_first_not_of(const char_type* s,
- size_type pos,
- size_type count)
- const
- {
- return find_first_not_of(basic_string_view<CharT,Traits>(s, count), pos);
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_first_not_of(const char_type* s,
- size_type pos)
- const
- {
- return find_first_not_of(basic_string_view<CharT,Traits>(s), pos);
- }
-
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_last_not_of(basic_string_view v,
- size_type pos)
- const
- {
- if (empty()) {
- return npos;
- }
- const auto max_index = std::min(size() - 1, pos);
- for (auto i = 0u; i <= max_index; ++i) {
- const auto j = max_index - i;
-
- if (!is_one_of(m_str[j],v)) {
- return j;
- }
- }
-
- return npos;
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_last_not_of(char_type c,
- size_type pos)
- const
- {
- return find_last_not_of(basic_string_view<CharT,Traits>(&c, 1), pos);
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_last_not_of(const char_type* s,
- size_type pos,
- size_type count)
- const
- {
- return find_last_not_of(basic_string_view<CharT,Traits>(s, count), pos);
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::size_type
- basic_string_view<CharT,Traits>::find_last_not_of(const char_type* s,
- size_type pos)
- const
- {
- return find_last_not_of(basic_string_view<CharT,Traits>(s), pos);
- }
-
- //--------------------------------------------------------------------------
- // Iterator
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::const_iterator
- basic_string_view<CharT,Traits>::begin()
- const noexcept
- {
- return m_str;
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::const_iterator
- basic_string_view<CharT,Traits>::cbegin()
- const noexcept
- {
- return begin();
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::const_iterator
- basic_string_view<CharT,Traits>::end()
- const noexcept
- {
- return m_str + m_size;
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::const_iterator
- basic_string_view<CharT,Traits>::cend()
- const noexcept
- {
- return cend();
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::const_reverse_iterator
- basic_string_view<CharT,Traits>::rbegin()
- const noexcept
- {
- return const_reverse_iterator{end()};
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::const_reverse_iterator
- basic_string_view<CharT,Traits>::crbegin()
- const noexcept
- {
- return rbegin();
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::const_reverse_iterator
- basic_string_view<CharT,Traits>::rend()
- const noexcept
- {
- return const_reverse_iterator{begin()};
- }
-
- template<typename CharT, typename Traits>
- inline typename basic_string_view<CharT,Traits>::const_reverse_iterator
- basic_string_view<CharT,Traits>::crend()
- const noexcept
- {
- return crend();
- }
-
- template <typename CharT, typename Traits>
- inline bool basic_string_view<CharT,Traits>::is_one_of(CharT c,
- basic_string_view str)
- {
- for (auto s : str) {
- if (c == s) {
- return true;
- }
- }
- return false;
- }
-
- //--------------------------------------------------------------------------
- // Public Functions
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- std::basic_ostream<CharT,Traits>& operator<<(std::basic_ostream<CharT,Traits>& o,
- const basic_string_view<CharT,Traits>& str)
- {
- o.write(str.data(),str.size());
- return o;
- }
-
- template<typename CharT, typename Traits>
- inline void swap(basic_string_view<CharT,Traits>& lhs,
- basic_string_view<CharT,Traits>& rhs)
- noexcept
- {
- lhs.swap(rhs);
- }
-
- //--------------------------------------------------------------------------
- // Comparison Functions
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline bool operator==(const basic_string_view<CharT,Traits>& lhs,
- const basic_string_view<CharT,Traits>& rhs)
- noexcept
- {
- return lhs.compare(rhs) == 0;
- }
-
- template<typename CharT, typename Traits>
- inline bool operator==(basic_string_view<CharT,Traits> lhs,
- const CharT* rhs)
- noexcept
- {
- return lhs == basic_string_view<CharT,Traits>(rhs);
- }
-
- template<typename CharT, typename Traits>
- inline bool operator==(const CharT* lhs,
- const basic_string_view<CharT,Traits>& rhs)
- noexcept
- {
- return basic_string_view<CharT,Traits>(lhs) == rhs;
- }
-
- template<typename CharT, typename Traits, typename Allocator>
- inline bool operator==(const std::basic_string<CharT,Traits,Allocator>& lhs,
- const basic_string_view<CharT,Traits>& rhs)
- {
- return basic_string_view<CharT,Traits>(lhs) == rhs;
- }
-
- template<typename CharT, typename Traits, typename Allocator>
- inline bool operator==(const basic_string_view<CharT,Traits>& lhs,
- const std::basic_string<CharT,Traits,Allocator>& rhs)
- {
- return lhs == basic_string_view<CharT,Traits>(rhs);
- }
-
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline bool operator!=(const basic_string_view<CharT,Traits>& lhs,
- const basic_string_view<CharT,Traits>& rhs)
- noexcept
- {
- return lhs.compare(rhs) != 0;
- }
-
- template<typename CharT, typename Traits>
- inline bool operator!=(const basic_string_view<CharT,Traits>& lhs,
- const CharT* rhs)
- noexcept
- {
- return lhs != basic_string_view<CharT,Traits>(rhs);
- }
-
- template<typename CharT, typename Traits>
- inline bool operator!=(const CharT* lhs,
- const basic_string_view<CharT,Traits>& rhs)
- noexcept
- {
- return basic_string_view<CharT,Traits>(lhs) != rhs;
- }
-
- template<typename CharT, typename Traits, typename Allocator>
- inline bool operator!=(const std::basic_string<CharT,Traits,Allocator>& lhs,
- const basic_string_view<CharT,Traits>& rhs)
- {
- return basic_string_view<CharT,Traits>(lhs) != rhs;
- }
-
- template<typename CharT, typename Traits, typename Allocator>
- inline bool operator!=(const basic_string_view<CharT,Traits>& lhs,
- const std::basic_string<CharT,Traits,Allocator>& rhs)
- {
- return lhs != basic_string_view<CharT,Traits>(rhs);
- }
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline bool operator<(const basic_string_view<CharT,Traits>& lhs,
- const basic_string_view<CharT,Traits>& rhs)
- noexcept
- {
- return lhs.compare(rhs) < 0;
- }
-
- template<typename CharT, typename Traits>
- inline bool operator<(const basic_string_view<CharT,Traits>& lhs,
- const CharT* rhs)
- noexcept
- {
- return lhs < basic_string_view<CharT,Traits>(rhs);
- }
-
- template<typename CharT, typename Traits>
- inline bool operator<(const CharT* lhs,
- const basic_string_view<CharT,Traits>& rhs)
- noexcept
- {
- return basic_string_view<CharT,Traits>(lhs) < rhs;
- }
-
- template<typename CharT, typename Traits, typename Allocator>
- inline bool operator<(const std::basic_string<CharT,Traits,Allocator>& lhs,
- const basic_string_view<CharT,Traits>& rhs)
- {
- return basic_string_view<CharT,Traits>(lhs) < rhs;
- }
-
- template<typename CharT, typename Traits, typename Allocator>
- inline bool operator<(const basic_string_view<CharT,Traits>& lhs,
- const std::basic_string<CharT,Traits,Allocator>& rhs)
- {
- return lhs < basic_string_view<CharT,Traits>(rhs);
- }
-
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline bool operator>(const basic_string_view<CharT,Traits>& lhs,
- const basic_string_view<CharT,Traits>& rhs)
- noexcept
- {
- return lhs.compare(rhs) > 0;
- }
-
- template<typename CharT, typename Traits>
- inline bool operator>(const basic_string_view<CharT,Traits>& lhs,
- const CharT* rhs)
- noexcept
- {
- return lhs > basic_string_view<CharT,Traits>(rhs);
- }
-
- template<typename CharT, typename Traits>
- inline bool operator>(const CharT* lhs,
- const basic_string_view<CharT,Traits>& rhs)
- noexcept
- {
- return basic_string_view<CharT,Traits>(lhs) > rhs;
- }
-
- template<typename CharT, typename Traits, typename Allocator>
- inline bool operator>(const std::basic_string<CharT,Traits,Allocator>& lhs,
- const basic_string_view<CharT,Traits>& rhs)
- {
- return basic_string_view<CharT,Traits>(lhs) > rhs;
- }
-
- template<typename CharT, typename Traits, typename Allocator>
- inline bool operator>(const basic_string_view<CharT,Traits>& lhs,
- const std::basic_string<CharT,Traits,Allocator>& rhs)
- {
- return lhs > basic_string_view<CharT,Traits>(rhs);
- }
-
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline bool operator<=(const basic_string_view<CharT,Traits>& lhs,
- const basic_string_view<CharT,Traits>& rhs)
- noexcept
- {
- return lhs.compare(rhs) <= 0;
- }
-
- template<typename CharT, typename Traits>
- inline bool operator<=(const basic_string_view<CharT,Traits>& lhs,
- const CharT* rhs)
- noexcept
- {
- return lhs <= basic_string_view<CharT,Traits>(rhs);
- }
-
- template<typename CharT, typename Traits>
- inline bool operator<=(const CharT* lhs,
- const basic_string_view<CharT,Traits>& rhs)
- noexcept
- {
- return basic_string_view<CharT,Traits>(lhs) <= rhs;
- }
-
- template<typename CharT, typename Traits, typename Allocator>
- inline bool operator<=(const std::basic_string<CharT,Traits,Allocator>& lhs,
- const basic_string_view<CharT,Traits>& rhs)
- {
- return basic_string_view<CharT,Traits>(lhs) <= rhs;
- }
-
- template<typename CharT, typename Traits, typename Allocator>
- inline bool operator<=(const basic_string_view<CharT,Traits>& lhs,
- const std::basic_string<CharT,Traits,Allocator>& rhs)
- {
- return lhs <= basic_string_view<CharT,Traits>(rhs);
- }
-
- //--------------------------------------------------------------------------
-
- template<typename CharT, typename Traits>
- inline bool operator>=(const basic_string_view<CharT,Traits>& lhs,
- const basic_string_view<CharT,Traits>& rhs)
- noexcept
- {
- return lhs.compare(rhs) >= 0;
- }
-
- template<typename CharT, typename Traits>
- inline bool operator>=(const basic_string_view<CharT,Traits>& lhs,
- const CharT* rhs)
- noexcept
- {
- return lhs >= basic_string_view<CharT,Traits>(rhs);
- }
-
- template<typename CharT, typename Traits>
- inline bool operator>=(const CharT* lhs,
- const basic_string_view<CharT,Traits>& rhs)
- noexcept
- {
- return basic_string_view<CharT,Traits>(lhs) >= rhs;
- }
-
- template<typename CharT, typename Traits, typename Allocator>
- inline bool operator>=(const std::basic_string<CharT,Traits,Allocator>& lhs,
- const basic_string_view<CharT,Traits>& rhs)
- {
- return basic_string_view<CharT,Traits>(lhs) >= rhs;
- }
-
- template<typename CharT, typename Traits, typename Allocator>
- inline bool operator>=(const basic_string_view<CharT,Traits>& lhs,
- const std::basic_string<CharT,Traits,Allocator>& rhs)
- {
- return lhs >= basic_string_view<CharT,Traits>(rhs);
- }
-
-} // namespace bpstd
-
-#endif /* BPSTD_DETAIL_STRING_VIEW_INL */
-
-#endif /* BPSTD_STRING_VIEW_HPP */