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 4
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( \
20 string_view_lite_PATCH)
22#define nssv_STRINGIFY(x) nssv_STRINGIFY_(x)
23#define nssv_STRINGIFY_(x) #x
27#define nssv_STRING_VIEW_DEFAULT 0
28#define nssv_STRING_VIEW_NONSTD 1
29#define nssv_STRING_VIEW_STD 2
31#if !defined(nssv_CONFIG_SELECT_STRING_VIEW)
32#define nssv_CONFIG_SELECT_STRING_VIEW (nssv_HAVE_STD_STRING_VIEW ? nssv_STRING_VIEW_STD : nssv_STRING_VIEW_NONSTD)
35#if defined(nssv_CONFIG_SELECT_STD_STRING_VIEW) || defined(nssv_CONFIG_SELECT_NONSTD_STRING_VIEW)
36#error nssv_CONFIG_SELECT_STD_STRING_VIEW and nssv_CONFIG_SELECT_NONSTD_STRING_VIEW are deprecated and removed, please use nssv_CONFIG_SELECT_STRING_VIEW=nssv_STRING_VIEW_...
39#ifndef nssv_CONFIG_STD_SV_OPERATOR
40#define nssv_CONFIG_STD_SV_OPERATOR 0
43#ifndef nssv_CONFIG_USR_SV_OPERATOR
44#define nssv_CONFIG_USR_SV_OPERATOR 1
47#ifdef nssv_CONFIG_CONVERSION_STD_STRING
48#define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS nssv_CONFIG_CONVERSION_STD_STRING
49#define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS nssv_CONFIG_CONVERSION_STD_STRING
52#ifndef nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
53#define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS 1
56#ifndef nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
57#define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS 1
62#ifndef nssv_CONFIG_NO_EXCEPTIONS
63#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
64#define nssv_CONFIG_NO_EXCEPTIONS 0
66#define nssv_CONFIG_NO_EXCEPTIONS 1
74#if defined(_MSVC_LANG) && !defined(__clang__)
75#define nssv_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG)
77#define nssv_CPLUSPLUS __cplusplus
81#define nssv_CPP98_OR_GREATER (nssv_CPLUSPLUS >= 199711L)
82#define nssv_CPP11_OR_GREATER (nssv_CPLUSPLUS >= 201103L)
83#define nssv_CPP11_OR_GREATER_ (nssv_CPLUSPLUS >= 201103L)
84#define nssv_CPP14_OR_GREATER (nssv_CPLUSPLUS >= 201402L)
85#define nssv_CPP17_OR_GREATER (nssv_CPLUSPLUS >= 201703L)
86#define nssv_CPP20_OR_GREATER (nssv_CPLUSPLUS >= 202000L)
90#if nssv_CPP17_OR_GREATER && defined(__has_include)
91#if __has_include(<string_view> )
92#define nssv_HAVE_STD_STRING_VIEW 1
94#define nssv_HAVE_STD_STRING_VIEW 0
97#define nssv_HAVE_STD_STRING_VIEW 0
100#define nssv_USES_STD_STRING_VIEW \
101 ((nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_STD) || \
102 ((nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_DEFAULT) && nssv_HAVE_STD_STRING_VIEW))
104#define nssv_HAVE_STARTS_WITH (nssv_CPP20_OR_GREATER || !nssv_USES_STD_STRING_VIEW)
105#define nssv_HAVE_ENDS_WITH nssv_HAVE_STARTS_WITH
111#if nssv_USES_STD_STRING_VIEW
113#include <string_view>
117#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
121template <
class CharT,
class Traits,
class Allocator = std::allocator<CharT>>
122std::basic_string<CharT, Traits, Allocator> to_string(std::basic_string_view<CharT, Traits> v,
123 Allocator
const &a = Allocator()) {
124 return std::basic_string<CharT, Traits, Allocator>(v.begin(), v.end(), a);
127template <
class CharT,
class Traits,
class Allocator>
128std::basic_string_view<CharT, Traits> to_string_view(std::basic_string<CharT, Traits, Allocator>
const &s) {
129 return std::basic_string_view<CharT, Traits>(s.data(), s.size());
134#if nssv_CONFIG_STD_SV_OPERATOR
136using namespace std::literals::string_view_literals;
140#if nssv_CONFIG_USR_SV_OPERATOR
142inline namespace literals {
143inline namespace string_view_literals {
145constexpr std::string_view
operator"" _sv(
const char *str,
size_t len)
noexcept
147 return std::string_view {str, len};
150constexpr std::u16string_view
operator"" _sv(
const char16_t *str,
size_t len)
noexcept
152 return std::u16string_view {str, len};
155constexpr std::u32string_view
operator"" _sv(
const char32_t *str,
size_t len)
noexcept
157 return std::u32string_view {str, len};
160constexpr std::wstring_view
operator"" _sv(
const wchar_t *str,
size_t len)
noexcept
162 return std::wstring_view {str, len};
176using std::basic_string_view;
177using std::string_view;
178using std::u16string_view;
179using std::u32string_view;
180using std::wstring_view;
184using std::operator==;
185using std::operator!=;
187using std::operator<=;
189using std::operator>=;
191using std::operator<<;
214#if defined(_MSC_VER) && !defined(__clang__)
215#define nssv_COMPILER_MSVC_VER (_MSC_VER)
216#define nssv_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * (5 + (_MSC_VER < 1900)))
218#define nssv_COMPILER_MSVC_VER 0
219#define nssv_COMPILER_MSVC_VERSION 0
222#define nssv_COMPILER_VERSION(major, minor, patch) (10 * (10 * (major) + (minor)) + (patch))
224#if defined(__clang__)
225#define nssv_COMPILER_CLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
227#define nssv_COMPILER_CLANG_VERSION 0
230#if defined(__GNUC__) && !defined(__clang__)
231#define nssv_COMPILER_GNUC_VERSION nssv_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
233#define nssv_COMPILER_GNUC_VERSION 0
237#define nssv_BETWEEN(v, lo, hi) ((lo) <= (v) && (v) < (hi))
242#define nssv_HAS_CPP0X _HAS_CPP0X
244#define nssv_HAS_CPP0X 0
249#if nssv_COMPILER_MSVC_VER >= 1900
250#undef nssv_CPP11_OR_GREATER
251#define nssv_CPP11_OR_GREATER 1
254#define nssv_CPP11_90 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1500)
255#define nssv_CPP11_100 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1600)
256#define nssv_CPP11_110 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1700)
257#define nssv_CPP11_120 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1800)
258#define nssv_CPP11_140 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1900)
259#define nssv_CPP11_141 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1910)
261#define nssv_CPP14_000 (nssv_CPP14_OR_GREATER)
262#define nssv_CPP17_000 (nssv_CPP17_OR_GREATER)
266#define nssv_HAVE_CONSTEXPR_11 nssv_CPP11_140
267#define nssv_HAVE_EXPLICIT_CONVERSION nssv_CPP11_140
268#define nssv_HAVE_INLINE_NAMESPACE nssv_CPP11_140
269#define nssv_HAVE_NOEXCEPT nssv_CPP11_140
270#define nssv_HAVE_NULLPTR nssv_CPP11_100
271#define nssv_HAVE_REF_QUALIFIER nssv_CPP11_140
272#define nssv_HAVE_UNICODE_LITERALS nssv_CPP11_140
273#define nssv_HAVE_USER_DEFINED_LITERALS nssv_CPP11_140
274#define nssv_HAVE_WCHAR16_T nssv_CPP11_100
275#define nssv_HAVE_WCHAR32_T nssv_CPP11_100
277#if !((nssv_CPP11_OR_GREATER && nssv_COMPILER_CLANG_VERSION) || nssv_BETWEEN(nssv_COMPILER_CLANG_VERSION, 300, 400))
278#define nssv_HAVE_STD_DEFINED_LITERALS nssv_CPP11_140
280#define nssv_HAVE_STD_DEFINED_LITERALS 0
285#define nssv_HAVE_CONSTEXPR_14 nssv_CPP14_000
289#define nssv_HAVE_NODISCARD nssv_CPP17_000
293#define nssv_HAVE_STD_HASH nssv_CPP11_120
297#if nssv_HAVE_CONSTEXPR_11
298#define nssv_constexpr constexpr
300#define nssv_constexpr
303#if nssv_HAVE_CONSTEXPR_14
304#define nssv_constexpr14 constexpr
306#define nssv_constexpr14
309#if nssv_HAVE_EXPLICIT_CONVERSION
310#define nssv_explicit explicit
315#if nssv_HAVE_INLINE_NAMESPACE
316#define nssv_inline_ns inline
318#define nssv_inline_ns
321#if nssv_HAVE_NOEXCEPT
322#define nssv_noexcept noexcept
336#define nssv_nullptr nullptr
338#define nssv_nullptr NULL
341#if nssv_HAVE_NODISCARD
342#define nssv_nodiscard [[nodiscard]]
344#define nssv_nodiscard
356#if !nssv_CONFIG_NO_EXCEPTIONS
360#if nssv_CPP11_OR_GREATER
361#include <type_traits>
366#if defined(__clang__)
367#pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
368#pragma clang diagnostic push
369#pragma clang diagnostic ignored "-Wuser-defined-literals"
370#elif defined(__GNUC__)
371#pragma GCC diagnostic push
372#pragma GCC diagnostic ignored "-Wliteral-suffix"
375#if nssv_COMPILER_MSVC_VERSION >= 140
376#define nssv_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]]
377#define nssv_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress : code))
378#define nssv_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable : codes))
380#define nssv_SUPPRESS_MSGSL_WARNING(expr)
381#define nssv_SUPPRESS_MSVC_WARNING(code, descr)
382#define nssv_DISABLE_MSVC_WARNINGS(codes)
385#if defined(__clang__)
386#define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
387#elif defined(__GNUC__)
388#define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
389#elif nssv_COMPILER_MSVC_VERSION >= 140
390#define nssv_RESTORE_WARNINGS() __pragma(warning(pop))
392#define nssv_RESTORE_WARNINGS()
402nssv_DISABLE_MSVC_WARNINGS(4455 26481 26472)
409#if nssv_CPP11_OR_GREATER
415 template <
typename CharT>
inline constexpr std::size_t length(CharT *s, std::size_t result = 0) {
416 return *s ==
'\0' ? result : length(s + 1, result + 1);
423 template <
class CharT,
class Traits = std::
char_traits<CharT>>
class basic_string_view;
429 template <
class CharT,
class Traits
431 class basic_string_view {
435 typedef Traits traits_type;
436 typedef CharT value_type;
438 typedef CharT *pointer;
439 typedef CharT
const *const_pointer;
440 typedef CharT &reference;
441 typedef CharT
const &const_reference;
443 typedef const_pointer iterator;
444 typedef const_pointer const_iterator;
445 typedef std::reverse_iterator<const_iterator> reverse_iterator;
446 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
448 typedef std::size_t size_type;
449 typedef std::ptrdiff_t difference_type;
453 nssv_constexpr basic_string_view() nssv_noexcept : data_(nssv_nullptr), size_(0) {}
455#if nssv_CPP11_OR_GREATER
456 nssv_constexpr basic_string_view(basic_string_view
const &other) nssv_noexcept =
default;
458 nssv_constexpr basic_string_view(basic_string_view
const &other) nssv_noexcept : data_(other.data_),
459 size_(other.size_) {}
462 nssv_constexpr basic_string_view(CharT
const *s, size_type count) nssv_noexcept
466 nssv_constexpr basic_string_view(CharT
const *s) nssv_noexcept
468#if nssv_CPP17_OR_GREATER
470 size_(Traits::length(s))
471#elif nssv_CPP11_OR_GREATER
473 size_(detail::length(s))
476 size_(Traits::length(s))
483#if nssv_CPP11_OR_GREATER
484 nssv_constexpr14 basic_string_view &operator=(basic_string_view
const &other) nssv_noexcept =
default;
486 nssv_constexpr14 basic_string_view &operator=(basic_string_view
const &other) nssv_noexcept {
495 nssv_constexpr const_iterator begin() const nssv_noexcept {
return data_; }
496 nssv_constexpr const_iterator end() const nssv_noexcept {
return data_ + size_; }
498 nssv_constexpr const_iterator cbegin() const nssv_noexcept {
return begin(); }
499 nssv_constexpr const_iterator cend() const nssv_noexcept {
return end(); }
501 nssv_constexpr const_reverse_iterator rbegin() const nssv_noexcept {
return const_reverse_iterator(end()); }
502 nssv_constexpr const_reverse_iterator rend() const nssv_noexcept {
return const_reverse_iterator(begin()); }
504 nssv_constexpr const_reverse_iterator crbegin() const nssv_noexcept {
return rbegin(); }
505 nssv_constexpr const_reverse_iterator crend() const nssv_noexcept {
return rend(); }
509 nssv_constexpr size_type size() const nssv_noexcept {
return size_; }
510 nssv_constexpr size_type length() const nssv_noexcept {
return size_; }
511 nssv_constexpr size_type max_size() const nssv_noexcept {
return (std::numeric_limits<size_type>::max)(); }
514 nssv_nodiscard nssv_constexpr
bool empty() const nssv_noexcept {
return 0 == size_; }
518 nssv_constexpr const_reference operator[](size_type pos)
const {
return data_at(pos); }
520 nssv_constexpr14 const_reference at(size_type pos)
const {
521#if nssv_CONFIG_NO_EXCEPTIONS
522 assert(pos < size());
525 throw std::out_of_range(
"nonstd::string_view::at()");
531 nssv_constexpr const_reference front()
const {
return data_at(0); }
532 nssv_constexpr const_reference back()
const {
return data_at(size() - 1); }
534 nssv_constexpr const_pointer data() const nssv_noexcept {
return data_; }
538 nssv_constexpr14
void remove_prefix(size_type n) {
544 nssv_constexpr14
void remove_suffix(size_type n) {
549 nssv_constexpr14
void swap(basic_string_view &other) nssv_noexcept {
551 swap(data_, other.data_);
552 swap(size_, other.size_);
557 size_type copy(CharT *dest, size_type n, size_type pos = 0)
const {
558#if nssv_CONFIG_NO_EXCEPTIONS
559 assert(pos <= size());
562 throw std::out_of_range(
"nonstd::string_view::copy()");
565 const size_type rlen = (std::min)(n, size() - pos);
567 (void)Traits::copy(dest, data() + pos, rlen);
572 nssv_constexpr14 basic_string_view substr(size_type pos = 0, size_type n = npos)
const {
573#if nssv_CONFIG_NO_EXCEPTIONS
574 assert(pos <= size());
577 throw std::out_of_range(
"nonstd::string_view::substr()");
580 return basic_string_view(data() + pos, (std::min)(n, size() - pos));
585 nssv_constexpr14
int compare(basic_string_view other)
const nssv_noexcept
587 if (
const int result = Traits::compare(data(), other.data(), (std::min)(size(), other.size()))) {
591 return size() == other.size() ? 0 : size() < other.size() ? -1 : 1;
594 nssv_constexpr
int compare(size_type pos1, size_type n1, basic_string_view other)
const
596 return substr(pos1, n1).compare(other);
599 nssv_constexpr
int compare(size_type pos1, size_type n1, basic_string_view other, size_type pos2,
602 return substr(pos1, n1).compare(other.substr(pos2, n2));
605 nssv_constexpr
int compare(CharT
const *s)
const
607 return compare(basic_string_view(s));
610 nssv_constexpr
int compare(size_type pos1, size_type n1, CharT
const *s)
const
612 return substr(pos1, n1).compare(basic_string_view(s));
615 nssv_constexpr
int compare(size_type pos1, size_type n1, CharT
const *s, size_type n2)
const
617 return substr(pos1, n1).compare(basic_string_view(s, n2));
624 nssv_constexpr
bool starts_with(basic_string_view v)
const nssv_noexcept
626 return size() >= v.size() && compare(0, v.size(), v) == 0;
629 nssv_constexpr
bool starts_with(CharT c)
const nssv_noexcept
631 return starts_with(basic_string_view(&c, 1));
634 nssv_constexpr
bool starts_with(CharT
const *s)
const
636 return starts_with(basic_string_view(s));
641 nssv_constexpr
bool ends_with(basic_string_view v)
const nssv_noexcept
643 return size() >= v.size() && compare(size() - v.size(), npos, v) == 0;
646 nssv_constexpr
bool ends_with(CharT c)
const nssv_noexcept
648 return ends_with(basic_string_view(&c, 1));
651 nssv_constexpr
bool ends_with(CharT
const *s)
const
653 return ends_with(basic_string_view(s));
658 nssv_constexpr14 size_type find(basic_string_view v, size_type pos = 0) const nssv_noexcept
660 return assert(v.size() == 0 || v.data() != nssv_nullptr),
661 pos >= size() ? npos : to_pos(std::search(cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq));
664 nssv_constexpr14 size_type find(CharT c, size_type pos = 0) const nssv_noexcept
666 return find(basic_string_view(&c, 1), pos);
669 nssv_constexpr14 size_type find(CharT
const *s, size_type pos, size_type n)
const
671 return find(basic_string_view(s, n), pos);
674 nssv_constexpr14 size_type find(CharT
const *s, size_type pos = 0) const
676 return find(basic_string_view(s), pos);
681 nssv_constexpr14 size_type rfind(basic_string_view v, size_type pos = npos)
const nssv_noexcept
683 if (size() < v.size()) {
688 return (std::min)(size(), pos);
691 const_iterator last = cbegin() + (std::min)(size() - v.size(), pos) + v.size();
692 const_iterator result = std::find_end(cbegin(), last, v.cbegin(), v.cend(), Traits::eq);
694 return result != last ? size_type(result - cbegin()) : npos;
697 nssv_constexpr14 size_type rfind(CharT c, size_type pos = npos)
const nssv_noexcept
699 return rfind(basic_string_view(&c, 1), pos);
702 nssv_constexpr14 size_type rfind(CharT
const *s, size_type pos, size_type n)
const
704 return rfind(basic_string_view(s, n), pos);
707 nssv_constexpr14 size_type rfind(CharT
const *s, size_type pos = npos)
const
709 return rfind(basic_string_view(s), pos);
714 nssv_constexpr size_type find_first_of(basic_string_view v, size_type pos = 0) const nssv_noexcept
716 return pos >= size() ? npos
717 : to_pos(std::find_first_of(cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq));
720 nssv_constexpr size_type find_first_of(CharT c, size_type pos = 0) const nssv_noexcept
722 return find_first_of(basic_string_view(&c, 1), pos);
725 nssv_constexpr size_type find_first_of(CharT
const *s, size_type pos, size_type n)
const
727 return find_first_of(basic_string_view(s, n), pos);
730 nssv_constexpr size_type find_first_of(CharT
const *s, size_type pos = 0) const
732 return find_first_of(basic_string_view(s), pos);
737 nssv_constexpr size_type find_last_of(basic_string_view v, size_type pos = npos)
const nssv_noexcept
739 return empty() ? npos
740 : pos >= size() ? find_last_of(v, size() - 1)
741 : to_pos(std::find_first_of(const_reverse_iterator(cbegin() + pos + 1), crend(),
742 v.cbegin(), v.cend(), Traits::eq));
745 nssv_constexpr size_type find_last_of(CharT c, size_type pos = npos)
const nssv_noexcept
747 return find_last_of(basic_string_view(&c, 1), pos);
750 nssv_constexpr size_type find_last_of(CharT
const *s, size_type pos, size_type count)
const
752 return find_last_of(basic_string_view(s, count), pos);
755 nssv_constexpr size_type find_last_of(CharT
const *s, size_type pos = npos)
const
757 return find_last_of(basic_string_view(s), pos);
762 nssv_constexpr size_type find_first_not_of(basic_string_view v, size_type pos = 0) const nssv_noexcept
764 return pos >= size() ? npos : to_pos(std::find_if(cbegin() + pos, cend(), not_in_view(v)));
767 nssv_constexpr size_type find_first_not_of(CharT c, size_type pos = 0) const nssv_noexcept
769 return find_first_not_of(basic_string_view(&c, 1), pos);
772 nssv_constexpr size_type find_first_not_of(CharT
const *s, size_type pos, size_type count)
const
774 return find_first_not_of(basic_string_view(s, count), pos);
777 nssv_constexpr size_type find_first_not_of(CharT
const *s, size_type pos = 0) const
779 return find_first_not_of(basic_string_view(s), pos);
784 nssv_constexpr size_type find_last_not_of(basic_string_view v, size_type pos = npos)
const nssv_noexcept
786 return empty() ? npos
788 ? find_last_not_of(v, size() - 1)
789 : to_pos(std::find_if(const_reverse_iterator(cbegin() + pos + 1), crend(), not_in_view(v)));
792 nssv_constexpr size_type find_last_not_of(CharT c, size_type pos = npos)
const nssv_noexcept
794 return find_last_not_of(basic_string_view(&c, 1), pos);
797 nssv_constexpr size_type find_last_not_of(CharT
const *s, size_type pos, size_type count)
const
799 return find_last_not_of(basic_string_view(s, count), pos);
802 nssv_constexpr size_type find_last_not_of(CharT
const *s, size_type pos = npos)
const
804 return find_last_not_of(basic_string_view(s), pos);
809#if nssv_CPP17_OR_GREATER
810 static nssv_constexpr size_type npos = size_type(-1);
811#elif nssv_CPP11_OR_GREATER
812 enum : size_type { npos = size_type(-1) };
814 enum { npos = size_type(-1) };
819 const basic_string_view v;
821 nssv_constexpr
explicit not_in_view(basic_string_view v) : v(v) {}
823 nssv_constexpr
bool operator()(CharT c)
const {
return npos == v.find_first_of(c); }
826 nssv_constexpr size_type to_pos(const_iterator it)
const {
return it == cend() ? npos : size_type(it - cbegin()); }
828 nssv_constexpr size_type to_pos(const_reverse_iterator it)
const {
829 return it == crend() ? npos : size_type(crend() - it - 1);
832 nssv_constexpr const_reference data_at(size_type pos)
const {
833#if nssv_BETWEEN(nssv_COMPILER_GNUC_VERSION, 1, 500)
836 return assert(pos < size()), data_[pos];
845#if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
847 template <
class Allocator>
848 basic_string_view(std::basic_string<CharT, Traits, Allocator>
const &s) nssv_noexcept : data_(s.data()),
851#if nssv_HAVE_EXPLICIT_CONVERSION
853 template <
class Allocator>
explicit operator std::basic_string<CharT, Traits, Allocator>()
const {
854 return to_string(Allocator());
859#if nssv_CPP11_OR_GREATER
861 template <
class Allocator = std::allocator<CharT>>
862 std::basic_string<CharT, Traits, Allocator> to_string(Allocator
const &a = Allocator())
const {
863 return std::basic_string<CharT, Traits, Allocator>(begin(), end(), a);
868 std::basic_string<CharT, Traits> to_string()
const {
return std::basic_string<CharT, Traits>(begin(), end()); }
870 template <
class Allocator> std::basic_string<CharT, Traits, Allocator> to_string(Allocator
const &a)
const {
871 return std::basic_string<CharT, Traits, Allocator>(begin(), end(), a);
886 template <
class CharT,
class Traits>
887 nssv_constexpr
bool operator==(basic_string_view<CharT, Traits> lhs,
888 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
889 return lhs.compare(rhs) == 0;
892 template <
class CharT,
class Traits>
893 nssv_constexpr
bool operator!=(basic_string_view<CharT, Traits> lhs,
894 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
895 return lhs.compare(rhs) != 0;
898 template <
class CharT,
class Traits>
899 nssv_constexpr
bool operator<(basic_string_view<CharT, Traits> lhs,
900 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
901 return lhs.compare(rhs) < 0;
904 template <
class CharT,
class Traits>
905 nssv_constexpr
bool operator<=(basic_string_view<CharT, Traits> lhs,
906 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
907 return lhs.compare(rhs) <= 0;
910 template <
class CharT,
class Traits>
911 nssv_constexpr
bool operator>(basic_string_view<CharT, Traits> lhs,
912 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
913 return lhs.compare(rhs) > 0;
916 template <
class CharT,
class Traits>
917 nssv_constexpr
bool operator>=(basic_string_view<CharT, Traits> lhs,
918 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
919 return lhs.compare(rhs) >= 0;
927#if !nssv_CPP11_OR_GREATER || nssv_BETWEEN(nssv_COMPILER_MSVC_VERSION, 100, 141)
933 template <
class CharT,
class Traits>
934 nssv_constexpr
bool operator==(basic_string_view<CharT, Traits> lhs,
char const *rhs) nssv_noexcept {
935 return lhs.compare(rhs) == 0;
938 template <
class CharT,
class Traits>
939 nssv_constexpr
bool operator==(
char const *lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
940 return rhs.compare(lhs) == 0;
943 template <
class CharT,
class Traits>
944 nssv_constexpr
bool operator==(basic_string_view<CharT, Traits> lhs,
945 std::basic_string<CharT, Traits> rhs) nssv_noexcept {
946 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
949 template <
class CharT,
class Traits>
950 nssv_constexpr
bool operator==(std::basic_string<CharT, Traits> rhs,
951 basic_string_view<CharT, Traits> lhs) nssv_noexcept {
952 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
957 template <
class CharT,
class Traits>
958 nssv_constexpr
bool operator!=(basic_string_view<CharT, Traits> lhs,
char const *rhs) nssv_noexcept {
959 return lhs.compare(rhs) != 0;
962 template <
class CharT,
class Traits>
963 nssv_constexpr
bool operator!=(
char const *lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
964 return rhs.compare(lhs) != 0;
967 template <
class CharT,
class Traits>
968 nssv_constexpr
bool operator!=(basic_string_view<CharT, Traits> lhs,
969 std::basic_string<CharT, Traits> rhs) nssv_noexcept {
970 return lhs.size() != rhs.size() && lhs.compare(rhs) != 0;
973 template <
class CharT,
class Traits>
974 nssv_constexpr
bool operator!=(std::basic_string<CharT, Traits> rhs,
975 basic_string_view<CharT, Traits> lhs) nssv_noexcept {
976 return lhs.size() != rhs.size() || rhs.compare(lhs) != 0;
981 template <
class CharT,
class Traits>
982 nssv_constexpr
bool operator<(basic_string_view<CharT, Traits> lhs,
char const *rhs) nssv_noexcept {
983 return lhs.compare(rhs) < 0;
986 template <
class CharT,
class Traits>
987 nssv_constexpr
bool operator<(
char const *lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
988 return rhs.compare(lhs) > 0;
991 template <
class CharT,
class Traits>
992 nssv_constexpr
bool operator<(basic_string_view<CharT, Traits> lhs,
993 std::basic_string<CharT, Traits> rhs) nssv_noexcept {
994 return lhs.compare(rhs) < 0;
997 template <
class CharT,
class Traits>
998 nssv_constexpr
bool operator<(std::basic_string<CharT, Traits> rhs,
999 basic_string_view<CharT, Traits> lhs) nssv_noexcept {
1000 return rhs.compare(lhs) > 0;
1005 template <
class CharT,
class Traits>
1006 nssv_constexpr
bool operator<=(basic_string_view<CharT, Traits> lhs,
char const *rhs) nssv_noexcept {
1007 return lhs.compare(rhs) <= 0;
1010 template <
class CharT,
class Traits>
1011 nssv_constexpr
bool operator<=(
char const *lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1012 return rhs.compare(lhs) >= 0;
1015 template <
class CharT,
class Traits>
1016 nssv_constexpr
bool operator<=(basic_string_view<CharT, Traits> lhs,
1017 std::basic_string<CharT, Traits> rhs) nssv_noexcept {
1018 return lhs.compare(rhs) <= 0;
1021 template <
class CharT,
class Traits>
1022 nssv_constexpr
bool operator<=(std::basic_string<CharT, Traits> rhs,
1023 basic_string_view<CharT, Traits> lhs) nssv_noexcept {
1024 return rhs.compare(lhs) >= 0;
1029 template <
class CharT,
class Traits>
1030 nssv_constexpr
bool operator>(basic_string_view<CharT, Traits> lhs,
char const *rhs) nssv_noexcept {
1031 return lhs.compare(rhs) > 0;
1034 template <
class CharT,
class Traits>
1035 nssv_constexpr
bool operator>(
char const *lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1036 return rhs.compare(lhs) < 0;
1039 template <
class CharT,
class Traits>
1040 nssv_constexpr
bool operator>(basic_string_view<CharT, Traits> lhs,
1041 std::basic_string<CharT, Traits> rhs) nssv_noexcept {
1042 return lhs.compare(rhs) > 0;
1045 template <
class CharT,
class Traits>
1046 nssv_constexpr
bool operator>(std::basic_string<CharT, Traits> rhs,
1047 basic_string_view<CharT, Traits> lhs) nssv_noexcept {
1048 return rhs.compare(lhs) < 0;
1053 template <
class CharT,
class Traits>
1054 nssv_constexpr
bool operator>=(basic_string_view<CharT, Traits> lhs,
char const *rhs) nssv_noexcept {
1055 return lhs.compare(rhs) >= 0;
1058 template <
class CharT,
class Traits>
1059 nssv_constexpr
bool operator>=(
char const *lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1060 return rhs.compare(lhs) <= 0;
1063 template <
class CharT,
class Traits>
1064 nssv_constexpr
bool operator>=(basic_string_view<CharT, Traits> lhs,
1065 std::basic_string<CharT, Traits> rhs) nssv_noexcept {
1066 return lhs.compare(rhs) >= 0;
1069 template <
class CharT,
class Traits>
1070 nssv_constexpr
bool operator>=(std::basic_string<CharT, Traits> rhs,
1071 basic_string_view<CharT, Traits> lhs) nssv_noexcept {
1072 return rhs.compare(lhs) <= 0;
1077#define nssv_BASIC_STRING_VIEW_I(T, U) typename std::decay<basic_string_view<T, U>>::type
1079#if nssv_BETWEEN(nssv_COMPILER_MSVC_VERSION, 140, 150)
1080#define nssv_MSVC_ORDER(x) , int = x
1082#define nssv_MSVC_ORDER(x)
1087 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1088 nssv_constexpr
bool operator==(basic_string_view<CharT, Traits> lhs,
1089 nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1090 return lhs.compare(rhs) == 0;
1093 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1094 nssv_constexpr
bool operator==(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
1095 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1096 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
1101 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1102 nssv_constexpr
bool operator!=(basic_string_view<CharT, Traits> lhs,
1103 nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1104 return lhs.size() != rhs.size() || lhs.compare(rhs) != 0;
1107 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1108 nssv_constexpr
bool operator!=(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
1109 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1110 return lhs.compare(rhs) != 0;
1115 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1116 nssv_constexpr
bool operator<(basic_string_view<CharT, Traits> lhs,
1117 nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1118 return lhs.compare(rhs) < 0;
1121 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1122 nssv_constexpr
bool operator<(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
1123 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1124 return lhs.compare(rhs) < 0;
1129 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1130 nssv_constexpr
bool operator<=(basic_string_view<CharT, Traits> lhs,
1131 nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1132 return lhs.compare(rhs) <= 0;
1135 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1136 nssv_constexpr
bool operator<=(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
1137 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1138 return lhs.compare(rhs) <= 0;
1143 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1144 nssv_constexpr
bool operator>(basic_string_view<CharT, Traits> lhs,
1145 nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1146 return lhs.compare(rhs) > 0;
1149 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1150 nssv_constexpr
bool operator>(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
1151 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1152 return lhs.compare(rhs) > 0;
1157 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1158 nssv_constexpr
bool operator>=(basic_string_view<CharT, Traits> lhs,
1159 nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1160 return lhs.compare(rhs) >= 0;
1163 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1164 nssv_constexpr
bool operator>=(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
1165 basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1166 return lhs.compare(rhs) >= 0;
1169#undef nssv_MSVC_ORDER
1170#undef nssv_BASIC_STRING_VIEW_I
1178 template <
class Stream>
void write_padding(Stream &os, std::streamsize n) {
1179 for (std::streamsize i = 0; i < n; ++i)
1180 os.rdbuf()->sputc(os.fill());
1183 template <
class Stream,
class View> Stream &write_to_stream(Stream &os, View
const &sv) {
1184 typename Stream::sentry sentry(os);
1189 const std::streamsize length =
static_cast<std::streamsize
>(sv.length());
1192 const bool pad = (length < os.width());
1193 const bool left_pad = pad && (os.flags() & std::ios_base::adjustfield) == std::ios_base::right;
1196 write_padding(os, os.width() - length);
1199 os.rdbuf()->sputn(sv.begin(), length);
1201 if (pad && !left_pad)
1202 write_padding(os, os.width() - length);
1212 template <
class CharT,
class Traits>
1213 std::basic_ostream<CharT, Traits> &operator<<(std::basic_ostream<CharT, Traits> &os,
1214 basic_string_view<CharT, Traits> sv) {
1215 return detail::write_to_stream(os, sv);
1220 typedef basic_string_view<char> string_view;
1221 typedef basic_string_view<wchar_t> wstring_view;
1222#if nssv_HAVE_WCHAR16_T
1223 typedef basic_string_view<char16_t> u16string_view;
1224 typedef basic_string_view<char32_t> u32string_view;
1234#if nssv_HAVE_USER_DEFINED_LITERALS
1237nssv_inline_ns
namespace literals {
1238 nssv_inline_ns
namespace string_view_literals {
1240#if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
1242 nssv_constexpr nonstd::sv_lite::string_view
operator"" sv(
const char *str,
size_t len) nssv_noexcept
1244 return nonstd::sv_lite::string_view {str, len};
1247 nssv_constexpr nonstd::sv_lite::u16string_view
operator"" sv(
const char16_t *str,
size_t len) nssv_noexcept
1249 return nonstd::sv_lite::u16string_view {str, len};
1252 nssv_constexpr nonstd::sv_lite::u32string_view
operator"" sv(
const char32_t *str,
size_t len) nssv_noexcept
1254 return nonstd::sv_lite::u32string_view {str, len};
1257 nssv_constexpr nonstd::sv_lite::wstring_view
operator"" sv(
const wchar_t *str,
size_t len) nssv_noexcept
1259 return nonstd::sv_lite::wstring_view {str, len};
1264#if nssv_CONFIG_USR_SV_OPERATOR
1266 nssv_constexpr nonstd::sv_lite::string_view
operator"" _sv(
const char *str,
size_t len) nssv_noexcept
1268 return nonstd::sv_lite::string_view {str, len};
1271 nssv_constexpr nonstd::sv_lite::u16string_view
operator"" _sv(
const char16_t *str,
size_t len) nssv_noexcept
1273 return nonstd::sv_lite::u16string_view {str, len};
1276 nssv_constexpr nonstd::sv_lite::u32string_view
operator"" _sv(
const char32_t *str,
size_t len) nssv_noexcept
1278 return nonstd::sv_lite::u32string_view {str, len};
1281 nssv_constexpr nonstd::sv_lite::wstring_view
operator"" _sv(
const wchar_t *str,
size_t len) nssv_noexcept
1283 return nonstd::sv_lite::wstring_view {str, len};
1297#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1304#if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140
1306template <
class CharT,
class Traits,
class Allocator = std::allocator<CharT>>
1307std::basic_string<CharT, Traits, Allocator> to_string(basic_string_view<CharT, Traits> v,
1308 Allocator
const &a = Allocator()) {
1309 return std::basic_string<CharT, Traits, Allocator>(v.begin(), v.end(), a);
1314template <
class CharT,
class Traits> std::basic_string<CharT, Traits> to_string(basic_string_view<CharT, Traits> v) {
1315 return std::basic_string<CharT, Traits>(v.begin(), v.end());
1318template <
class CharT,
class Traits,
class Allocator>
1319std::basic_string<CharT, Traits, Allocator> to_string(basic_string_view<CharT, Traits> v, Allocator
const &a) {
1320 return std::basic_string<CharT, Traits, Allocator>(v.begin(), v.end(), a);
1325template <
class CharT,
class Traits,
class Allocator>
1326basic_string_view<CharT, Traits> to_string_view(std::basic_string<CharT, Traits, Allocator>
const &s) {
1327 return basic_string_view<CharT, Traits>(s.data(), s.size());
1341using sv_lite::basic_string_view;
1342using sv_lite::string_view;
1343using sv_lite::wstring_view;
1345#if nssv_HAVE_WCHAR16_T
1346using sv_lite::u16string_view;
1348#if nssv_HAVE_WCHAR32_T
1349using sv_lite::u32string_view;
1354using sv_lite::operator==;
1355using sv_lite::operator!=;
1356using sv_lite::operator<;
1357using sv_lite::operator<=;
1358using sv_lite::operator>;
1359using sv_lite::operator>=;
1361using sv_lite::operator<<;
1363#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1364using sv_lite::to_string;
1365using sv_lite::to_string_view;
1375#if nssv_HAVE_STD_HASH
1377#include <functional>
1381template <>
struct hash<nonstd::string_view> {
1383 std::size_t operator()(nonstd::string_view v)
const nssv_noexcept {
1384 return std::hash<std::string>()(std::string(v.data(), v.size()));
1388template <>
struct hash<nonstd::wstring_view> {
1390 std::size_t operator()(nonstd::wstring_view v)
const nssv_noexcept {
1391 return std::hash<std::wstring>()(std::wstring(v.data(), v.size()));
1395template <>
struct hash<nonstd::u16string_view> {
1397 std::size_t operator()(nonstd::u16string_view v)
const nssv_noexcept {
1398 return std::hash<std::u16string>()(std::u16string(v.data(), v.size()));
1402template <>
struct hash<nonstd::u32string_view> {
1404 std::size_t operator()(nonstd::u32string_view v)
const nssv_noexcept {
1405 return std::hash<std::u32string>()(std::u32string(v.data(), v.size()));
1413nssv_RESTORE_WARNINGS()