11#ifndef NONSTD_SV_LITE_H_INCLUDED
12#define NONSTD_SV_LITE_H_INCLUDED
14#define string_view_lite_MAJOR 1
15#define string_view_lite_MINOR 8
16#define string_view_lite_PATCH 0
18#define string_view_lite_VERSION \
19 nssv_STRINGIFY(string_view_lite_MAJOR) "." nssv_STRINGIFY(string_view_lite_MINOR) "." nssv_STRINGIFY(string_view_lite_PATCH)
21#define nssv_STRINGIFY(x) nssv_STRINGIFY_(x)
22#define nssv_STRINGIFY_(x) #x
26#define nssv_STRING_VIEW_DEFAULT 0
27#define nssv_STRING_VIEW_NONSTD 1
28#define nssv_STRING_VIEW_STD 2
33#if __has_include(<nonstd/string_view.tweak.hpp>)
34#include <nonstd/string_view.tweak.hpp>
36#define nssv_HAVE_TWEAK_HEADER 1
38#define nssv_HAVE_TWEAK_HEADER 0
44#if !defined(nssv_CONFIG_SELECT_STRING_VIEW)
45#define nssv_CONFIG_SELECT_STRING_VIEW (nssv_HAVE_STD_STRING_VIEW ? nssv_STRING_VIEW_STD : nssv_STRING_VIEW_NONSTD)
48#ifndef nssv_CONFIG_STD_SV_OPERATOR
49#define nssv_CONFIG_STD_SV_OPERATOR 0
52#ifndef nssv_CONFIG_USR_SV_OPERATOR
53#define nssv_CONFIG_USR_SV_OPERATOR 1
56#ifdef nssv_CONFIG_CONVERSION_STD_STRING
57#define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS nssv_CONFIG_CONVERSION_STD_STRING
58#define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS nssv_CONFIG_CONVERSION_STD_STRING
61#ifndef nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
62#define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS 1
65#ifndef nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
66#define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS 1
69#ifndef nssv_CONFIG_NO_STREAM_INSERTION
70#define nssv_CONFIG_NO_STREAM_INSERTION 0
73#ifndef nssv_CONFIG_CONSTEXPR11_STD_SEARCH
74#define nssv_CONFIG_CONSTEXPR11_STD_SEARCH 1
79#ifndef nssv_CONFIG_NO_EXCEPTIONS
83#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
84#define nssv_CONFIG_NO_EXCEPTIONS 0
86#define nssv_CONFIG_NO_EXCEPTIONS 1
94#if defined(_MSVC_LANG) && !defined(__clang__)
95#define nssv_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG)
97#define nssv_CPLUSPLUS __cplusplus
101#define nssv_CPP98_OR_GREATER (nssv_CPLUSPLUS >= 199711L)
102#define nssv_CPP11_OR_GREATER (nssv_CPLUSPLUS >= 201103L)
103#define nssv_CPP11_OR_GREATER_ (nssv_CPLUSPLUS >= 201103L)
104#define nssv_CPP14_OR_GREATER (nssv_CPLUSPLUS >= 201402L)
105#define nssv_CPP17_OR_GREATER (nssv_CPLUSPLUS >= 201703L)
106#define nssv_CPP20_OR_GREATER (nssv_CPLUSPLUS >= 202002L)
107#define nssv_CPP23_OR_GREATER (nssv_CPLUSPLUS >= 202300L)
111#if nssv_CPP17_OR_GREATER && defined(__has_include)
112#if __has_include(<string_view> )
113#define nssv_HAVE_STD_STRING_VIEW 1
115#define nssv_HAVE_STD_STRING_VIEW 0
118#define nssv_HAVE_STD_STRING_VIEW 0
121#define nssv_USES_STD_STRING_VIEW \
122 ((nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_STD) || \
123 ((nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_DEFAULT) && nssv_HAVE_STD_STRING_VIEW))
125#define nssv_HAVE_STARTS_WITH (nssv_CPP20_OR_GREATER || !nssv_USES_STD_STRING_VIEW)
126#define nssv_HAVE_ENDS_WITH nssv_HAVE_STARTS_WITH
132#if nssv_USES_STD_STRING_VIEW
134#include <string_view>
138#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
144template <
class CharT,
class Traits,
class Allocator = std::allocator<CharT>>
145std::basic_string<CharT, Traits, Allocator> to_string(std::basic_string_view<CharT, Traits> v, Allocator
const& a = Allocator()) {
146 return std::basic_string<CharT, Traits, Allocator>(v.begin(), v.end(), a);
149template <
class CharT,
class Traits,
class Allocator>
150std::basic_string_view<CharT, Traits> to_string_view(std::basic_string<CharT, Traits, Allocator>
const& s) {
151 return std::basic_string_view<CharT, Traits>(s.data(), s.size());
156#if nssv_CONFIG_STD_SV_OPERATOR
158using namespace std::literals::string_view_literals;
162#if nssv_CONFIG_USR_SV_OPERATOR
164inline namespace literals {
165inline namespace string_view_literals {
167constexpr std::string_view
operator""_sv(
const char* str,
size_t len)
noexcept
169 return std::string_view{str, len};
172constexpr std::u16string_view
operator""_sv(
const char16_t* str,
size_t len)
noexcept
174 return std::u16string_view{str, len};
177constexpr std::u32string_view
operator""_sv(
const char32_t* str,
size_t len)
noexcept
179 return std::u32string_view{str, len};
182constexpr std::wstring_view
operator""_sv(
const wchar_t* str,
size_t len)
noexcept
184 return std::wstring_view{str, len};
198using std::basic_string_view;
199using std::string_view;
200using std::u16string_view;
201using std::u32string_view;
202using std::wstring_view;
206using std::operator==;
207using std::operator!=;
209using std::operator<=;
211using std::operator>=;
213using std::operator<<;
237#if defined(_MSC_VER) && !defined(__clang__)
238#define nssv_COMPILER_MSVC_VER (_MSC_VER)
239#define nssv_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * (5 + (_MSC_VER < 1900)))
241#define nssv_COMPILER_MSVC_VER 0
242#define nssv_COMPILER_MSVC_VERSION 0
245#define nssv_COMPILER_VERSION(major, minor, patch) (10 * (10 * (major) + (minor)) + (patch))
247#if defined(__apple_build_version__)
248#define nssv_COMPILER_APPLECLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
249#define nssv_COMPILER_CLANG_VERSION 0
250#elif defined(__clang__)
251#define nssv_COMPILER_APPLECLANG_VERSION 0
252#define nssv_COMPILER_CLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
254#define nssv_COMPILER_APPLECLANG_VERSION 0
255#define nssv_COMPILER_CLANG_VERSION 0
258#if defined(__GNUC__) && !defined(__clang__)
259#define nssv_COMPILER_GNUC_VERSION nssv_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
261#define nssv_COMPILER_GNUC_VERSION 0
265#define nssv_BETWEEN(v, lo, hi) ((lo) <= (v) && (v) < (hi))
270#define nssv_HAS_CPP0X _HAS_CPP0X
272#define nssv_HAS_CPP0X 0
277#if nssv_COMPILER_MSVC_VER >= 1900
278#undef nssv_CPP11_OR_GREATER
279#define nssv_CPP11_OR_GREATER 1
282#define nssv_CPP11_90 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1500)
283#define nssv_CPP11_100 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1600)
284#define nssv_CPP11_110 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1700)
285#define nssv_CPP11_120 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1800)
286#define nssv_CPP11_140 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1900)
287#define nssv_CPP11_141 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1910)
289#define nssv_CPP14_000 (nssv_CPP14_OR_GREATER)
290#define nssv_CPP17_000 (nssv_CPP17_OR_GREATER)
294#define nssv_HAVE_CONSTEXPR_11 nssv_CPP11_140
295#define nssv_HAVE_EXPLICIT_CONVERSION nssv_CPP11_140
296#define nssv_HAVE_INLINE_NAMESPACE nssv_CPP11_140
297#define nssv_HAVE_IS_DEFAULT nssv_CPP11_140
298#define nssv_HAVE_IS_DELETE nssv_CPP11_140
299#define nssv_HAVE_NOEXCEPT nssv_CPP11_140
300#define nssv_HAVE_NULLPTR nssv_CPP11_100
301#define nssv_HAVE_REF_QUALIFIER nssv_CPP11_140
302#define nssv_HAVE_UNICODE_LITERALS nssv_CPP11_140
303#define nssv_HAVE_USER_DEFINED_LITERALS nssv_CPP11_140
304#define nssv_HAVE_WCHAR16_T nssv_CPP11_100
305#define nssv_HAVE_WCHAR32_T nssv_CPP11_100
307#if !((nssv_CPP11_OR_GREATER && nssv_COMPILER_CLANG_VERSION) || nssv_BETWEEN(nssv_COMPILER_CLANG_VERSION, 300, 400))
308#define nssv_HAVE_STD_DEFINED_LITERALS nssv_CPP11_140
310#define nssv_HAVE_STD_DEFINED_LITERALS 0
315#define nssv_HAVE_CONSTEXPR_14 nssv_CPP14_000
319#define nssv_HAVE_NODISCARD nssv_CPP17_000
323#define nssv_HAVE_STD_HASH nssv_CPP11_120
340#define nssv_HAVE_BUILTIN_VER \
341 ((nssv_CPP17_000 && nssv_COMPILER_MSVC_VERSION >= 142) || nssv_COMPILER_GNUC_VERSION > 0 || nssv_COMPILER_CLANG_VERSION >= 400 || \
342 nssv_COMPILER_APPLECLANG_VERSION >= 900)
343#define nssv_HAVE_BUILTIN_CE (nssv_HAVE_BUILTIN_VER)
345#define nssv_HAVE_BUILTIN_MEMCMP ((nssv_HAVE_CONSTEXPR_14 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_14)
346#define nssv_HAVE_BUILTIN_STRLEN ((nssv_HAVE_CONSTEXPR_11 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_11)
349#define nssv_HAVE_BUILTIN(x) __has_builtin(x)
351#define nssv_HAVE_BUILTIN(x) 0
354#if nssv_HAVE_BUILTIN(__builtin_memcmp) || nssv_HAVE_BUILTIN_VER
355#define nssv_BUILTIN_MEMCMP __builtin_memcmp
357#define nssv_BUILTIN_MEMCMP memcmp
360#if nssv_HAVE_BUILTIN(__builtin_strlen) || nssv_HAVE_BUILTIN_VER
361#define nssv_BUILTIN_STRLEN __builtin_strlen
363#define nssv_BUILTIN_STRLEN strlen
368#if nssv_HAVE_CONSTEXPR_11
369#define nssv_constexpr constexpr
371#define nssv_constexpr
374#if nssv_HAVE_CONSTEXPR_14
375#define nssv_constexpr14 constexpr
377#define nssv_constexpr14
380#if nssv_HAVE_EXPLICIT_CONVERSION
381#define nssv_explicit explicit
386#if nssv_HAVE_INLINE_NAMESPACE
387#define nssv_inline_ns inline
389#define nssv_inline_ns
392#if nssv_HAVE_NOEXCEPT
393#define nssv_noexcept noexcept
407#define nssv_nullptr nullptr
409#define nssv_nullptr NULL
412#if nssv_HAVE_NODISCARD
413#define nssv_nodiscard [[nodiscard]]
415#define nssv_nodiscard
426#if !nssv_CONFIG_NO_STREAM_INSERTION
430#if !nssv_CONFIG_NO_EXCEPTIONS
434#if nssv_CPP11_OR_GREATER
435#include <type_traits>
440#if defined(__clang__)
441#pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
442#pragma clang diagnostic push
443#pragma clang diagnostic ignored "-Wuser-defined-literals"
444#elif nssv_COMPILER_GNUC_VERSION >= 480
445#pragma GCC diagnostic push
446#pragma GCC diagnostic ignored "-Wliteral-suffix"
449#if nssv_COMPILER_MSVC_VERSION >= 140
450#define nssv_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]]
451#define nssv_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress : code))
452#define nssv_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable : codes))
454#define nssv_SUPPRESS_MSGSL_WARNING(expr)
455#define nssv_SUPPRESS_MSVC_WARNING(code, descr)
456#define nssv_DISABLE_MSVC_WARNINGS(codes)
459#if defined(__clang__)
460#define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
461#elif nssv_COMPILER_GNUC_VERSION >= 480
462#define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
463#elif nssv_COMPILER_MSVC_VERSION >= 140
464#define nssv_RESTORE_WARNINGS() __pragma(warning(pop))
466#define nssv_RESTORE_WARNINGS()
476nssv_DISABLE_MSVC_WARNINGS(4455 26481 26472)
487 template <
class CharT,
class Traits = std::
char_traits<CharT>>
class basic_string_view;
494 template <
typename CharT>
inline nssv_constexpr14
int compare(CharT
const* s1, CharT
const* s2, std::size_t count) {
495 while(count-- != 0) {
506#if nssv_HAVE_BUILTIN_MEMCMP
510 inline nssv_constexpr14
int compare(
char const* s1,
char const* s2, std::size_t count) {
return nssv_BUILTIN_MEMCMP(s1, s2, count); }
514#if nssv_HAVE_BUILTIN_STRLEN
518 inline nssv_constexpr std::size_t length(
char const* s) {
return nssv_BUILTIN_STRLEN(s); }
522#if defined(__OPTIMIZE__)
527 template <
typename CharT>
inline nssv_constexpr std::size_t length(CharT* s, std::size_t result = 0) {
528 return *s ==
'\0' ? result : length(s + 1, result + 1);
535 template <
typename CharT>
inline nssv_constexpr14 std::size_t length(CharT* s) {
536 std::size_t result = 0;
537 while(*s++ !=
'\0') {
545#if nssv_CPP11_OR_GREATER && !nssv_CPP17_OR_GREATER
546#if defined(__OPTIMIZE__)
551 template <
class CharT,
class Traits = std::
char_traits<CharT>>
552 constexpr const CharT* search(basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle) {
553 return haystack.starts_with(needle) ? haystack.begin() : haystack.empty() ? haystack.end() : search(haystack.substr(1), needle);
560#if nssv_CONFIG_CONSTEXPR11_STD_SEARCH
562 template <
class CharT,
class Traits = std::
char_traits<CharT>>
563 constexpr const CharT* search(basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle) {
564 return std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end());
569 template <
class CharT,
class Traits = std::
char_traits<CharT>>
570 nssv_constexpr14
const CharT* search(basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle) {
571 while(needle.size() <= haystack.size()) {
572 if(haystack.starts_with(needle)) {
573 return haystack.cbegin();
575 haystack = basic_string_view<CharT, Traits>{haystack.begin() + 1, haystack.size() - 1U};
577 return haystack.cend();
590 template <
class CharT,
class Traits
592 class basic_string_view {
596 typedef Traits traits_type;
597 typedef CharT value_type;
599 typedef CharT* pointer;
600 typedef CharT
const* const_pointer;
601 typedef CharT& reference;
602 typedef CharT
const& const_reference;
604 typedef const_pointer iterator;
605 typedef const_pointer const_iterator;
606 typedef std::reverse_iterator<const_iterator> reverse_iterator;
607 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
609 typedef std::size_t size_type;
610 typedef std::ptrdiff_t difference_type;
614 nssv_constexpr basic_string_view() nssv_noexcept : data_(nssv_nullptr), size_(0) {}
616#if nssv_CPP11_OR_GREATER
617 nssv_constexpr basic_string_view(basic_string_view
const& other) nssv_noexcept =
default;
619 nssv_constexpr basic_string_view(basic_string_view
const& other) nssv_noexcept : data_(other.data_), size_(other.size_) {}
622 nssv_constexpr basic_string_view(CharT
const* s, size_type count) nssv_noexcept
626 nssv_constexpr basic_string_view(CharT
const* s) nssv_noexcept
628#if nssv_CPP17_OR_GREATER
630 size_(Traits::length(s))
631#elif nssv_CPP11_OR_GREATER
633 size_(detail::length(s))
636 size_(Traits::length(s))
642#if nssv_HAVE_IS_DELETE
643 nssv_constexpr basic_string_view(std::nullptr_t) nssv_noexcept =
delete;
646 nssv_constexpr basic_string_view(std::nullptr_t) nssv_noexcept;
654#if nssv_CPP11_OR_GREATER
655 nssv_constexpr14 basic_string_view& operator=(basic_string_view
const& other) nssv_noexcept =
default;
657 nssv_constexpr14 basic_string_view& operator=(basic_string_view
const& other) nssv_noexcept {
666 nssv_constexpr const_iterator begin() const nssv_noexcept {
return data_; }
667 nssv_constexpr const_iterator end() const nssv_noexcept {
return data_ + size_; }
669 nssv_constexpr const_iterator cbegin() const nssv_noexcept {
return begin(); }
670 nssv_constexpr const_iterator cend() const nssv_noexcept {
return end(); }
672 nssv_constexpr const_reverse_iterator rbegin() const nssv_noexcept {
return const_reverse_iterator(end()); }
673 nssv_constexpr const_reverse_iterator rend() const nssv_noexcept {
return const_reverse_iterator(begin()); }
675 nssv_constexpr const_reverse_iterator crbegin() const nssv_noexcept {
return rbegin(); }
676 nssv_constexpr const_reverse_iterator crend() const nssv_noexcept {
return rend(); }
680 nssv_constexpr size_type size() const nssv_noexcept {
return size_; }
681 nssv_constexpr size_type length() const nssv_noexcept {
return size_; }
682 nssv_constexpr size_type max_size() const nssv_noexcept {
return (std::numeric_limits<size_type>::max)(); }
685 nssv_nodiscard nssv_constexpr
bool empty() const nssv_noexcept {
return 0 == size_; }
689 nssv_constexpr const_reference operator[](size_type pos)
const {
return data_at(pos); }
691 nssv_constexpr14 const_reference at(size_type pos)
const {
692#if nssv_CONFIG_NO_EXCEPTIONS
693 assert(pos < size());
696 throw std::out_of_range(
"nonstd::string_view::at()");
702 nssv_constexpr const_reference front()
const {
return data_at(0); }
703 nssv_constexpr const_reference back()
const {
return data_at(size() - 1); }
705 nssv_constexpr const_pointer data() const nssv_noexcept {
return data_; }
709 nssv_constexpr14
void remove_prefix(size_type n) {
715 nssv_constexpr14
void remove_suffix(size_type n) {
720 nssv_constexpr14
void swap(basic_string_view& other) nssv_noexcept {
721 const basic_string_view tmp(other);
728 size_type copy(CharT* dest, size_type n, size_type pos = 0)
const {
729#if nssv_CONFIG_NO_EXCEPTIONS
730 assert(pos <= size());
733 throw std::out_of_range(
"nonstd::string_view::copy()");
736 const size_type rlen = (std::min)(n, size() - pos);
738 (void)Traits::copy(dest, data() + pos, rlen);
743 nssv_constexpr14 basic_string_view substr(size_type pos = 0, size_type n = npos)
const {
744#if nssv_CONFIG_NO_EXCEPTIONS
745 assert(pos <= size());
748 throw std::out_of_range(
"nonstd::string_view::substr()");
751 return basic_string_view(data() + pos, (std::min)(n, size() - pos));
756 nssv_constexpr14
int compare(basic_string_view other)
const nssv_noexcept
758#if nssv_CPP17_OR_GREATER
759 if(
const int result = Traits::compare(data(), other.data(), (std::min)(size(), other.size())))
761 if(
const int result = detail::compare(data(), other.data(), (std::min)(size(), other.size())))
767 return size() == other.size() ? 0 : size() < other.size() ? -1 : 1;
770 nssv_constexpr
int compare(size_type pos1, size_type n1, basic_string_view other)
const
772 return substr(pos1, n1).compare(other);
775 nssv_constexpr
int compare(size_type pos1, size_type n1, basic_string_view other, size_type pos2, size_type n2)
const
777 return substr(pos1, n1).compare(other.substr(pos2, n2));
780 nssv_constexpr
int compare(CharT
const* s)
const
782 return compare(basic_string_view(s));
785 nssv_constexpr
int compare(size_type pos1, size_type n1, CharT
const* s)
const
787 return substr(pos1, n1).compare(basic_string_view(s));
790 nssv_constexpr
int compare(size_type pos1, size_type n1, CharT
const* s, size_type n2)
const
792 return substr(pos1, n1).compare(basic_string_view(s, n2));
799 nssv_constexpr
bool starts_with(basic_string_view v)
const nssv_noexcept
801 return size() >= v.size() && compare(0, v.size(), v) == 0;
804 nssv_constexpr
bool starts_with(CharT c)
const nssv_noexcept
806 return starts_with(basic_string_view(&c, 1));
809 nssv_constexpr
bool starts_with(CharT
const* s)
const
811 return starts_with(basic_string_view(s));
816 nssv_constexpr
bool ends_with(basic_string_view v)
const nssv_noexcept
818 return size() >= v.size() && compare(size() - v.size(), npos, v) == 0;
821 nssv_constexpr
bool ends_with(CharT c)
const nssv_noexcept
823 return ends_with(basic_string_view(&c, 1));
826 nssv_constexpr
bool ends_with(CharT
const* s)
const
828 return ends_with(basic_string_view(s));
833 nssv_constexpr14 size_type find(basic_string_view v, size_type pos = 0) const nssv_noexcept
835 return assert(v.size() == 0 || v.data() != nssv_nullptr), pos >= size() ? npos
837#
if nssv_CPP11_OR_GREATER && !nssv_CPP17_OR_GREATER
838 detail::search(substr(pos), v)
840 std::search(cbegin() + pos, cend(), v.cbegin(),
841 v.cend(), Traits::eq)
846 nssv_constexpr size_type find(CharT c, size_type pos = 0) const nssv_noexcept
848 return find(basic_string_view(&c, 1), pos);
851 nssv_constexpr size_type find(CharT
const* s, size_type pos, size_type n)
const
853 return find(basic_string_view(s, n), pos);
856 nssv_constexpr size_type find(CharT
const* s, size_type pos = 0) const
858 return find(basic_string_view(s), pos);
863 nssv_constexpr14 size_type rfind(basic_string_view v, size_type pos = npos)
const nssv_noexcept
865 if(size() < v.size()) {
870 return (std::min)(size(), pos);
873 const_iterator last = cbegin() + (std::min)(size() - v.size(), pos) + v.size();
874 const_iterator result = std::find_end(cbegin(), last, v.cbegin(), v.cend(), Traits::eq);
876 return result != last ? size_type(result - cbegin()) : npos;
879 nssv_constexpr14 size_type rfind(CharT c, size_type pos = npos)
const nssv_noexcept
881 return rfind(basic_string_view(&c, 1), pos);
884 nssv_constexpr14 size_type rfind(CharT
const* s, size_type pos, size_type n)
const
886 return rfind(basic_string_view(s, n), pos);
889 nssv_constexpr14 size_type rfind(CharT
const* s, size_type pos = npos)
const
891 return rfind(basic_string_view(s), pos);
896 nssv_constexpr size_type find_first_of(basic_string_view v, size_type pos = 0) const nssv_noexcept
898 return pos >= size() ? npos : to_pos(std::find_first_of(cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq));
901 nssv_constexpr size_type find_first_of(CharT c, size_type pos = 0) const nssv_noexcept
903 return find_first_of(basic_string_view(&c, 1), pos);
906 nssv_constexpr size_type find_first_of(CharT
const* s, size_type pos, size_type n)
const
908 return find_first_of(basic_string_view(s, n), pos);
911 nssv_constexpr size_type find_first_of(CharT
const* s, size_type pos = 0) const
913 return find_first_of(basic_string_view(s), pos);
918 nssv_constexpr size_type find_last_of(basic_string_view v, size_type pos = npos)
const nssv_noexcept
920 return empty() ? npos
922 ? find_last_of(v, size() - 1)
923 : to_pos(std::find_first_of(const_reverse_iterator(cbegin() + pos + 1), crend(), v.cbegin(), v.cend(), Traits::eq));
926 nssv_constexpr size_type find_last_of(CharT c, size_type pos = npos)
const nssv_noexcept
928 return find_last_of(basic_string_view(&c, 1), pos);
931 nssv_constexpr size_type find_last_of(CharT
const* s, size_type pos, size_type count)
const
933 return find_last_of(basic_string_view(s, count), pos);
936 nssv_constexpr size_type find_last_of(CharT
const* s, size_type pos = npos)
const
938 return find_last_of(basic_string_view(s), pos);
943 nssv_constexpr size_type find_first_not_of(basic_string_view v, size_type pos = 0) const nssv_noexcept
945 return pos >= size() ? npos : to_pos(std::find_if(cbegin() + pos, cend(), not_in_view(v)));
948 nssv_constexpr size_type find_first_not_of(CharT c, size_type pos = 0) const nssv_noexcept
950 return find_first_not_of(basic_string_view(&c, 1), pos);
953 nssv_constexpr size_type find_first_not_of(CharT
const* s, size_type pos, size_type count)
const
955 return find_first_not_of(basic_string_view(s, count), pos);
958 nssv_constexpr size_type find_first_not_of(CharT
const* s, size_type pos = 0) const
960 return find_first_not_of(basic_string_view(s), pos);
965 nssv_constexpr size_type find_last_not_of(basic_string_view v, size_type pos = npos)
const nssv_noexcept
967 return empty() ? npos
968 : pos >= size() ? find_last_not_of(v, size() - 1)
969 : to_pos(std::find_if(const_reverse_iterator(cbegin() + pos + 1), crend(), not_in_view(v)));
972 nssv_constexpr size_type find_last_not_of(CharT c, size_type pos = npos)
const nssv_noexcept
974 return find_last_not_of(basic_string_view(&c, 1), pos);
977 nssv_constexpr size_type find_last_not_of(CharT
const* s, size_type pos, size_type count)
const
979 return find_last_not_of(basic_string_view(s, count), pos);
982 nssv_constexpr size_type find_last_not_of(CharT
const* s, size_type pos = npos)
const
984 return find_last_not_of(basic_string_view(s), pos);
989#if nssv_CPP17_OR_GREATER
990 static nssv_constexpr size_type npos = size_type(-1);
991#elif nssv_CPP11_OR_GREATER
992 enum : size_type { npos = size_type(-1) };
994 enum { npos = size_type(-1) };
999 const basic_string_view v;
1001 nssv_constexpr
explicit not_in_view(basic_string_view v_)
1004 nssv_constexpr
bool operator()(CharT c)
const {
return npos == v.find_first_of(c); }
1007 nssv_constexpr size_type to_pos(const_iterator it)
const {
return it == cend() ? npos : size_type(it - cbegin()); }
1009 nssv_constexpr size_type to_pos(const_reverse_iterator it)
const {
return it == crend() ? npos : size_type(crend() - it - 1); }
1011 nssv_constexpr const_reference data_at(size_type pos)
const {
1012#if nssv_BETWEEN(nssv_COMPILER_GNUC_VERSION, 1, 500)
1015 return assert(pos < size()), data_[pos];
1020 const_pointer data_;
1024#if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
1026 template <
class Allocator>
1027 basic_string_view(std::basic_string<CharT, Traits, Allocator>
const& s) nssv_noexcept : data_(s.data()), size_(s.size()) {}
1029#if nssv_HAVE_EXPLICIT_CONVERSION
1031 template <
class Allocator>
explicit operator std::basic_string<CharT, Traits, Allocator>()
const {
return to_string(Allocator()); }
1035#if nssv_CPP11_OR_GREATER
1037 template <
class Allocator = std::allocator<CharT>>
1038 std::basic_string<CharT, Traits, Allocator> to_string(Allocator
const& a = Allocator())
const {
1039 return std::basic_string<CharT, Traits, Allocator>(begin(), end(), a);
1044 std::basic_string<CharT, Traits> to_string()
const {
return std::basic_string<CharT, Traits>(begin(), end()); }
1046 template <
class Allocator> std::basic_string<CharT, Traits, Allocator> to_string(Allocator
const& a)
const {
1047 return std::basic_string<CharT, Traits, Allocator>(begin(), end(), a);
1062 template <
class CharT,
class Traits>
1063 nssv_constexpr
bool operator==(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1064 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
1067 template <
class CharT,
class Traits>
1068 nssv_constexpr
bool operator!=(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1069 return !(lhs == rhs);
1072 template <
class CharT,
class Traits>
1073 nssv_constexpr
bool operator<(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1074 return lhs.compare(rhs) < 0;
1077 template <
class CharT,
class Traits>
1078 nssv_constexpr
bool operator<=(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1079 return lhs.compare(rhs) <= 0;
1082 template <
class CharT,
class Traits>
1083 nssv_constexpr
bool operator>(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1084 return lhs.compare(rhs) > 0;
1087 template <
class CharT,
class Traits>
1088 nssv_constexpr
bool operator>=(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1089 return lhs.compare(rhs) >= 0;
1097#if !nssv_CPP11_OR_GREATER || nssv_BETWEEN(nssv_COMPILER_MSVC_VERSION, 100, 141)
1103 template <
class CharT,
class Traits>
1104 nssv_constexpr
bool operator==(basic_string_view<CharT, Traits> lhs, CharT
const* rhs) nssv_noexcept {
1105 return lhs.size() == detail::length(rhs) && lhs.compare(rhs) == 0;
1108 template <
class CharT,
class Traits>
1109 nssv_constexpr
bool operator==(CharT
const* lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1110 return detail::length(lhs) == rhs.size() && rhs.compare(lhs) == 0;
1113 template <
class CharT,
class Traits>
1114 nssv_constexpr
bool operator==(basic_string_view<CharT, Traits> lhs, std::basic_string<CharT, Traits> rhs) nssv_noexcept {
1115 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
1118 template <
class CharT,
class Traits>
1119 nssv_constexpr
bool operator==(std::basic_string<CharT, Traits> rhs, basic_string_view<CharT, Traits> lhs) nssv_noexcept {
1120 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
1125 template <
class CharT,
class Traits>
1126 nssv_constexpr
bool operator!=(basic_string_view<CharT, Traits> lhs, CharT
const* rhs) nssv_noexcept {
1127 return !(lhs == rhs);
1130 template <
class CharT,
class Traits>
1131 nssv_constexpr
bool operator!=(CharT
const* lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1132 return !(lhs == rhs);
1135 template <
class CharT,
class Traits>
1136 nssv_constexpr
bool operator!=(basic_string_view<CharT, Traits> lhs, std::basic_string<CharT, Traits> rhs) nssv_noexcept {
1137 return !(lhs == rhs);
1140 template <
class CharT,
class Traits>
1141 nssv_constexpr
bool operator!=(std::basic_string<CharT, Traits> rhs, basic_string_view<CharT, Traits> lhs) nssv_noexcept {
1142 return !(lhs == rhs);
1147 template <
class CharT,
class Traits>
1148 nssv_constexpr
bool operator<(basic_string_view<CharT, Traits> lhs, CharT
const* rhs) nssv_noexcept {
1149 return lhs.compare(rhs) < 0;
1152 template <
class CharT,
class Traits>
1153 nssv_constexpr
bool operator<(CharT
const* lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1154 return rhs.compare(lhs) > 0;
1157 template <
class CharT,
class Traits>
1158 nssv_constexpr
bool operator<(basic_string_view<CharT, Traits> lhs, std::basic_string<CharT, Traits> rhs) nssv_noexcept {
1159 return lhs.compare(rhs) < 0;
1162 template <
class CharT,
class Traits>
1163 nssv_constexpr
bool operator<(std::basic_string<CharT, Traits> rhs, basic_string_view<CharT, Traits> lhs) nssv_noexcept {
1164 return rhs.compare(lhs) > 0;
1169 template <
class CharT,
class Traits>
1170 nssv_constexpr
bool operator<=(basic_string_view<CharT, Traits> lhs, CharT
const* rhs) nssv_noexcept {
1171 return lhs.compare(rhs) <= 0;
1174 template <
class CharT,
class Traits>
1175 nssv_constexpr
bool operator<=(CharT
const* lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1176 return rhs.compare(lhs) >= 0;
1179 template <
class CharT,
class Traits>
1180 nssv_constexpr
bool operator<=(basic_string_view<CharT, Traits> lhs, std::basic_string<CharT, Traits> rhs) nssv_noexcept {
1181 return lhs.compare(rhs) <= 0;
1184 template <
class CharT,
class Traits>
1185 nssv_constexpr
bool operator<=(std::basic_string<CharT, Traits> rhs, basic_string_view<CharT, Traits> lhs) nssv_noexcept {
1186 return rhs.compare(lhs) >= 0;
1191 template <
class CharT,
class Traits>
1192 nssv_constexpr
bool operator>(basic_string_view<CharT, Traits> lhs, CharT
const* rhs) nssv_noexcept {
1193 return lhs.compare(rhs) > 0;
1196 template <
class CharT,
class Traits>
1197 nssv_constexpr
bool operator>(CharT
const* lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1198 return rhs.compare(lhs) < 0;
1201 template <
class CharT,
class Traits>
1202 nssv_constexpr
bool operator>(basic_string_view<CharT, Traits> lhs, std::basic_string<CharT, Traits> rhs) nssv_noexcept {
1203 return lhs.compare(rhs) > 0;
1206 template <
class CharT,
class Traits>
1207 nssv_constexpr
bool operator>(std::basic_string<CharT, Traits> rhs, basic_string_view<CharT, Traits> lhs) nssv_noexcept {
1208 return rhs.compare(lhs) < 0;
1213 template <
class CharT,
class Traits>
1214 nssv_constexpr
bool operator>=(basic_string_view<CharT, Traits> lhs, CharT
const* rhs) nssv_noexcept {
1215 return lhs.compare(rhs) >= 0;
1218 template <
class CharT,
class Traits>
1219 nssv_constexpr
bool operator>=(CharT
const* lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1220 return rhs.compare(lhs) <= 0;
1223 template <
class CharT,
class Traits>
1224 nssv_constexpr
bool operator>=(basic_string_view<CharT, Traits> lhs, std::basic_string<CharT, Traits> rhs) nssv_noexcept {
1225 return lhs.compare(rhs) >= 0;
1228 template <
class CharT,
class Traits>
1229 nssv_constexpr
bool operator>=(std::basic_string<CharT, Traits> rhs, basic_string_view<CharT, Traits> lhs) nssv_noexcept {
1230 return rhs.compare(lhs) <= 0;
1235#define nssv_BASIC_STRING_VIEW_I(T, U) typename std::decay<basic_string_view<T, U>>::type
1237#if defined(_MSC_VER)
1238#define nssv_MSVC_ORDER(x) , int = x
1240#define nssv_MSVC_ORDER(x)
1245 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1246 nssv_constexpr
bool operator==(basic_string_view<CharT, Traits> lhs, nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1247 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
1250 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1251 nssv_constexpr
bool operator==(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1252 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
1257 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1258 nssv_constexpr
bool operator!=(basic_string_view<CharT, Traits> lhs, nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1259 return !(lhs == rhs);
1262 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1263 nssv_constexpr
bool operator!=(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1264 return !(lhs == rhs);
1269 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1270 nssv_constexpr
bool operator<(basic_string_view<CharT, Traits> lhs, nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1271 return lhs.compare(rhs) < 0;
1274 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1275 nssv_constexpr
bool operator<(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1276 return lhs.compare(rhs) < 0;
1281 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1282 nssv_constexpr
bool operator<=(basic_string_view<CharT, Traits> lhs, nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1283 return lhs.compare(rhs) <= 0;
1286 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1287 nssv_constexpr
bool operator<=(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1288 return lhs.compare(rhs) <= 0;
1293 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1294 nssv_constexpr
bool operator>(basic_string_view<CharT, Traits> lhs, nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1295 return lhs.compare(rhs) > 0;
1298 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1299 nssv_constexpr
bool operator>(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1300 return lhs.compare(rhs) > 0;
1305 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1306 nssv_constexpr
bool operator>=(basic_string_view<CharT, Traits> lhs, nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1307 return lhs.compare(rhs) >= 0;
1310 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1311 nssv_constexpr
bool operator>=(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1312 return lhs.compare(rhs) >= 0;
1315#undef nssv_MSVC_ORDER
1316#undef nssv_BASIC_STRING_VIEW_I
1322#if !nssv_CONFIG_NO_STREAM_INSERTION
1326 template <
class Stream>
void write_padding(Stream& os, std::streamsize n) {
1327 for(std::streamsize i = 0; i < n; ++i)
1328 os.rdbuf()->sputc(os.fill());
1331 template <
class Stream,
class View> Stream& write_to_stream(Stream& os, View
const& sv) {
1332 typename Stream::sentry sentry(os);
1337 const std::streamsize length =
static_cast<std::streamsize
>(sv.length());
1340 const bool pad = (length < os.width());
1341 const bool left_pad = pad && (os.flags() & std::ios_base::adjustfield) == std::ios_base::right;
1344 write_padding(os, os.width() - length);
1347 os.rdbuf()->sputn(sv.begin(), length);
1349 if(pad && !left_pad)
1350 write_padding(os, os.width() - length);
1360 template <
class CharT,
class Traits>
1361 std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os, basic_string_view<CharT, Traits> sv) {
1362 return detail::write_to_stream(os, sv);
1369 typedef basic_string_view<char> string_view;
1370 typedef basic_string_view<wchar_t> wstring_view;
1371#if nssv_HAVE_WCHAR16_T
1372 typedef basic_string_view<char16_t> u16string_view;
1373 typedef basic_string_view<char32_t> u32string_view;
1383#if nssv_HAVE_USER_DEFINED_LITERALS
1386nssv_inline_ns
namespace literals {
1387 nssv_inline_ns
namespace string_view_literals {
1389#if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
1391 nssv_constexpr nonstd::sv_lite::string_view
operator""sv(
const char* str,
size_t len)nssv_noexcept
1393 return nonstd::sv_lite::string_view{str, len};
1396 nssv_constexpr nonstd::sv_lite::u16string_view
operator""sv(
const char16_t* str,
size_t len)nssv_noexcept
1398 return nonstd::sv_lite::u16string_view{str, len};
1401 nssv_constexpr nonstd::sv_lite::u32string_view
operator""sv(
const char32_t* str,
size_t len)nssv_noexcept
1403 return nonstd::sv_lite::u32string_view{str, len};
1406 nssv_constexpr nonstd::sv_lite::wstring_view
operator""sv(
const wchar_t* str,
size_t len)nssv_noexcept
1408 return nonstd::sv_lite::wstring_view{str, len};
1413#if nssv_CONFIG_USR_SV_OPERATOR
1415 nssv_constexpr nonstd::sv_lite::string_view
operator""_sv(
const char* str,
size_t len)nssv_noexcept
1417 return nonstd::sv_lite::string_view{str, len};
1420 nssv_constexpr nonstd::sv_lite::u16string_view
operator""_sv(
const char16_t* str,
size_t len)nssv_noexcept
1422 return nonstd::sv_lite::u16string_view{str, len};
1425 nssv_constexpr nonstd::sv_lite::u32string_view
operator""_sv(
const char32_t* str,
size_t len)nssv_noexcept
1427 return nonstd::sv_lite::u32string_view{str, len};
1430 nssv_constexpr nonstd::sv_lite::wstring_view
operator""_sv(
const wchar_t* str,
size_t len)nssv_noexcept
1432 return nonstd::sv_lite::wstring_view{str, len};
1446#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1453#if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140
1455template <
class CharT,
class Traits,
class Allocator = std::allocator<CharT>>
1456std::basic_string<CharT, Traits, Allocator> to_string(basic_string_view<CharT, Traits> v, Allocator
const& a = Allocator()) {
1457 return std::basic_string<CharT, Traits, Allocator>(v.begin(), v.end(), a);
1462template <
class CharT,
class Traits> std::basic_string<CharT, Traits> to_string(basic_string_view<CharT, Traits> v) {
1463 return std::basic_string<CharT, Traits>(v.begin(), v.end());
1466template <
class CharT,
class Traits,
class Allocator>
1467std::basic_string<CharT, Traits, Allocator> to_string(basic_string_view<CharT, Traits> v, Allocator
const& a) {
1468 return std::basic_string<CharT, Traits, Allocator>(v.begin(), v.end(), a);
1473template <
class CharT,
class Traits,
class Allocator>
1474basic_string_view<CharT, Traits> to_string_view(std::basic_string<CharT, Traits, Allocator>
const& s) {
1475 return basic_string_view<CharT, Traits>(s.data(), s.size());
1489using sv_lite::basic_string_view;
1490using sv_lite::string_view;
1491using sv_lite::wstring_view;
1493#if nssv_HAVE_WCHAR16_T
1494using sv_lite::u16string_view;
1496#if nssv_HAVE_WCHAR32_T
1497using sv_lite::u32string_view;
1502using sv_lite::operator==;
1503using sv_lite::operator!=;
1504using sv_lite::operator<;
1505using sv_lite::operator<=;
1506using sv_lite::operator>;
1507using sv_lite::operator>=;
1509#if !nssv_CONFIG_NO_STREAM_INSERTION
1510using sv_lite::operator<<;
1513#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1514using sv_lite::to_string;
1515using sv_lite::to_string_view;
1525#if nssv_HAVE_STD_HASH
1527#include <functional>
1531template <>
struct hash<nonstd::string_view> {
1533 std::size_t operator()(nonstd::string_view v)
const nssv_noexcept {
return std::hash<std::string>()(std::string(v.data(), v.size())); }
1536template <>
struct hash<nonstd::wstring_view> {
1538 std::size_t operator()(nonstd::wstring_view v)
const nssv_noexcept {
1539 return std::hash<std::wstring>()(std::wstring(v.data(), v.size()));
1543template <>
struct hash<nonstd::u16string_view> {
1545 std::size_t operator()(nonstd::u16string_view v)
const nssv_noexcept {
1546 return std::hash<std::u16string>()(std::u16string(v.data(), v.size()));
1550template <>
struct hash<nonstd::u32string_view> {
1552 std::size_t operator()(nonstd::u32string_view v)
const nssv_noexcept {
1553 return std::hash<std::u32string>()(std::u32string(v.data(), v.size()));
1561nssv_RESTORE_WARNINGS()
std::ostream & operator<<(std::ostream &stream, const std::vector< T > &vector)
a print function for a vector