1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684 |
- // 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
- // 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 variant-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 defined(__GNUC__)
- # 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 defined(__GNUC__)
- # 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:
- 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() );
- }
- #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_constexpr 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
|