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 7
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
75 #ifndef nssv_CONFIG_NO_EXCEPTIONS
79 #if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
80 #define nssv_CONFIG_NO_EXCEPTIONS 0
82 #define nssv_CONFIG_NO_EXCEPTIONS 1
89 #ifndef nssv_CPLUSPLUS
90 #if defined(_MSVC_LANG) && !defined(__clang__)
91 #define nssv_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG)
93 #define nssv_CPLUSPLUS __cplusplus
97 #define nssv_CPP98_OR_GREATER (nssv_CPLUSPLUS >= 199711L)
98 #define nssv_CPP11_OR_GREATER (nssv_CPLUSPLUS >= 201103L)
99 #define nssv_CPP11_OR_GREATER_ (nssv_CPLUSPLUS >= 201103L)
100 #define nssv_CPP14_OR_GREATER (nssv_CPLUSPLUS >= 201402L)
101 #define nssv_CPP17_OR_GREATER (nssv_CPLUSPLUS >= 201703L)
102 #define nssv_CPP20_OR_GREATER (nssv_CPLUSPLUS >= 202002L)
103 #define nssv_CPP23_OR_GREATER (nssv_CPLUSPLUS >= 202300L)
107 #if nssv_CPP17_OR_GREATER && defined(__has_include)
108 #if __has_include(<string_view> )
109 #define nssv_HAVE_STD_STRING_VIEW 1
111 #define nssv_HAVE_STD_STRING_VIEW 0
114 #define nssv_HAVE_STD_STRING_VIEW 0
117 #define nssv_USES_STD_STRING_VIEW \
118 ((nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_STD) || \
119 ((nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_DEFAULT) && nssv_HAVE_STD_STRING_VIEW))
121 #define nssv_HAVE_STARTS_WITH (nssv_CPP20_OR_GREATER || !nssv_USES_STD_STRING_VIEW)
122 #define nssv_HAVE_ENDS_WITH nssv_HAVE_STARTS_WITH
128 #if nssv_USES_STD_STRING_VIEW
130 #include <string_view>
134 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
138 template <
class CharT,
class Traits,
class Allocator = std::allocator<CharT>>
139 std::basic_string<CharT, Traits, Allocator> to_string(std::basic_string_view<CharT, Traits> v, Allocator
const& a = Allocator()) {
140 return std::basic_string<CharT, Traits, Allocator>(v.begin(), v.end(), a);
143 template <
class CharT,
class Traits,
class Allocator>
144 std::basic_string_view<CharT, Traits> to_string_view(std::basic_string<CharT, Traits, Allocator>
const& s) {
145 return std::basic_string_view<CharT, Traits>(s.data(), s.size());
150 #if nssv_CONFIG_STD_SV_OPERATOR
152 using namespace std::literals::string_view_literals;
156 #if nssv_CONFIG_USR_SV_OPERATOR
158 inline namespace literals {
159 inline namespace string_view_literals {
161 constexpr std::string_view
operator"" _sv(
const char* str,
size_t len) noexcept
163 return std::string_view{str, len};
166 constexpr std::u16string_view
operator"" _sv(
const char16_t* str,
size_t len) noexcept
168 return std::u16string_view{str, len};
171 constexpr std::u32string_view
operator"" _sv(
const char32_t* str,
size_t len) noexcept
173 return std::u32string_view{str, len};
176 constexpr std::wstring_view
operator"" _sv(
const wchar_t* str,
size_t len) noexcept
178 return std::wstring_view{str, len};
192 using std::basic_string_view;
193 using std::string_view;
194 using std::u16string_view;
195 using std::u32string_view;
196 using std::wstring_view;
200 using std::operator==;
201 using std::operator!=;
202 using std::operator<;
203 using std::operator<=;
204 using std::operator>;
205 using std::operator>=;
207 using std::operator<<;
231 #if defined(_MSC_VER) && !defined(__clang__)
232 #define nssv_COMPILER_MSVC_VER (_MSC_VER)
233 #define nssv_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * (5 + (_MSC_VER < 1900)))
235 #define nssv_COMPILER_MSVC_VER 0
236 #define nssv_COMPILER_MSVC_VERSION 0
239 #define nssv_COMPILER_VERSION(major, minor, patch) (10 * (10 * (major) + (minor)) + (patch))
241 #if defined(__apple_build_version__)
242 #define nssv_COMPILER_APPLECLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
243 #define nssv_COMPILER_CLANG_VERSION 0
244 #elif defined(__clang__)
245 #define nssv_COMPILER_APPLECLANG_VERSION 0
246 #define nssv_COMPILER_CLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
248 #define nssv_COMPILER_APPLECLANG_VERSION 0
249 #define nssv_COMPILER_CLANG_VERSION 0
252 #if defined(__GNUC__) && !defined(__clang__)
253 #define nssv_COMPILER_GNUC_VERSION nssv_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
255 #define nssv_COMPILER_GNUC_VERSION 0
259 #define nssv_BETWEEN(v, lo, hi) ((lo) <= (v) && (v) < (hi))
264 #define nssv_HAS_CPP0X _HAS_CPP0X
266 #define nssv_HAS_CPP0X 0
271 #if nssv_COMPILER_MSVC_VER >= 1900
272 #undef nssv_CPP11_OR_GREATER
273 #define nssv_CPP11_OR_GREATER 1
276 #define nssv_CPP11_90 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1500)
277 #define nssv_CPP11_100 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1600)
278 #define nssv_CPP11_110 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1700)
279 #define nssv_CPP11_120 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1800)
280 #define nssv_CPP11_140 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1900)
281 #define nssv_CPP11_141 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1910)
283 #define nssv_CPP14_000 (nssv_CPP14_OR_GREATER)
284 #define nssv_CPP17_000 (nssv_CPP17_OR_GREATER)
288 #define nssv_HAVE_CONSTEXPR_11 nssv_CPP11_140
289 #define nssv_HAVE_EXPLICIT_CONVERSION nssv_CPP11_140
290 #define nssv_HAVE_INLINE_NAMESPACE nssv_CPP11_140
291 #define nssv_HAVE_IS_DEFAULT nssv_CPP11_140
292 #define nssv_HAVE_IS_DELETE nssv_CPP11_140
293 #define nssv_HAVE_NOEXCEPT nssv_CPP11_140
294 #define nssv_HAVE_NULLPTR nssv_CPP11_100
295 #define nssv_HAVE_REF_QUALIFIER nssv_CPP11_140
296 #define nssv_HAVE_UNICODE_LITERALS nssv_CPP11_140
297 #define nssv_HAVE_USER_DEFINED_LITERALS nssv_CPP11_140
298 #define nssv_HAVE_WCHAR16_T nssv_CPP11_100
299 #define nssv_HAVE_WCHAR32_T nssv_CPP11_100
301 #if !((nssv_CPP11_OR_GREATER && nssv_COMPILER_CLANG_VERSION) || nssv_BETWEEN(nssv_COMPILER_CLANG_VERSION, 300, 400))
302 #define nssv_HAVE_STD_DEFINED_LITERALS nssv_CPP11_140
304 #define nssv_HAVE_STD_DEFINED_LITERALS 0
309 #define nssv_HAVE_CONSTEXPR_14 nssv_CPP14_000
313 #define nssv_HAVE_NODISCARD nssv_CPP17_000
317 #define nssv_HAVE_STD_HASH nssv_CPP11_120
334 #define nssv_HAVE_BUILTIN_VER \
335 ((nssv_CPP17_000 && nssv_COMPILER_MSVC_VERSION >= 142) || nssv_COMPILER_GNUC_VERSION > 0 || nssv_COMPILER_CLANG_VERSION >= 400 || \
336 nssv_COMPILER_APPLECLANG_VERSION >= 900)
337 #define nssv_HAVE_BUILTIN_CE (nssv_HAVE_BUILTIN_VER)
339 #define nssv_HAVE_BUILTIN_MEMCMP ((nssv_HAVE_CONSTEXPR_14 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_14)
340 #define nssv_HAVE_BUILTIN_STRLEN ((nssv_HAVE_CONSTEXPR_11 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_11)
343 #define nssv_HAVE_BUILTIN(x) __has_builtin(x)
345 #define nssv_HAVE_BUILTIN(x) 0
348 #if nssv_HAVE_BUILTIN(__builtin_memcmp) || nssv_HAVE_BUILTIN_VER
349 #define nssv_BUILTIN_MEMCMP __builtin_memcmp
351 #define nssv_BUILTIN_MEMCMP memcmp
354 #if nssv_HAVE_BUILTIN(__builtin_strlen) || nssv_HAVE_BUILTIN_VER
355 #define nssv_BUILTIN_STRLEN __builtin_strlen
357 #define nssv_BUILTIN_STRLEN strlen
362 #if nssv_HAVE_CONSTEXPR_11
363 #define nssv_constexpr constexpr
365 #define nssv_constexpr
368 #if nssv_HAVE_CONSTEXPR_14
369 #define nssv_constexpr14 constexpr
371 #define nssv_constexpr14
374 #if nssv_HAVE_EXPLICIT_CONVERSION
375 #define nssv_explicit explicit
377 #define nssv_explicit
380 #if nssv_HAVE_INLINE_NAMESPACE
381 #define nssv_inline_ns inline
383 #define nssv_inline_ns
386 #if nssv_HAVE_NOEXCEPT
387 #define nssv_noexcept noexcept
389 #define nssv_noexcept
400 #if nssv_HAVE_NULLPTR
401 #define nssv_nullptr nullptr
403 #define nssv_nullptr NULL
406 #if nssv_HAVE_NODISCARD
407 #define nssv_nodiscard [[nodiscard]]
409 #define nssv_nodiscard
420 #if !nssv_CONFIG_NO_STREAM_INSERTION
424 #if !nssv_CONFIG_NO_EXCEPTIONS
428 #if nssv_CPP11_OR_GREATER
429 #include <type_traits>
434 #if defined(__clang__)
435 #pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
436 #pragma clang diagnostic push
437 #pragma clang diagnostic ignored "-Wuser-defined-literals"
438 #elif nssv_COMPILER_GNUC_VERSION >= 480
439 #pragma GCC diagnostic push
440 #pragma GCC diagnostic ignored "-Wliteral-suffix"
443 #if nssv_COMPILER_MSVC_VERSION >= 140
444 #define nssv_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]]
445 #define nssv_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress : code))
446 #define nssv_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable : codes))
448 #define nssv_SUPPRESS_MSGSL_WARNING(expr)
449 #define nssv_SUPPRESS_MSVC_WARNING(code, descr)
450 #define nssv_DISABLE_MSVC_WARNINGS(codes)
453 #if defined(__clang__)
454 #define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
455 #elif nssv_COMPILER_GNUC_VERSION >= 480
456 #define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
457 #elif nssv_COMPILER_MSVC_VERSION >= 140
458 #define nssv_RESTORE_WARNINGS() __pragma(warning(pop))
460 #define nssv_RESTORE_WARNINGS()
470 nssv_DISABLE_MSVC_WARNINGS(4455 26481 26472)
481 template <
class CharT,
class Traits = std::
char_traits<CharT>>
class basic_string_view;
488 template <
typename CharT>
inline nssv_constexpr14
int compare(CharT
const* s1, CharT
const* s2, std::size_t count) {
489 while(count-- != 0) {
500 #if nssv_HAVE_BUILTIN_MEMCMP
504 inline nssv_constexpr14
int compare(
char const* s1,
char const* s2, std::size_t count) {
return nssv_BUILTIN_MEMCMP(s1, s2, count); }
508 #if nssv_HAVE_BUILTIN_STRLEN
512 inline nssv_constexpr std::size_t length(
char const* s) {
return nssv_BUILTIN_STRLEN(s); }
516 #if defined(__OPTIMIZE__)
521 template <
typename CharT>
inline nssv_constexpr std::size_t length(CharT* s, std::size_t result = 0) {
522 return *s ==
'\0' ? result : length(s + 1, result + 1);
529 template <
typename CharT>
inline nssv_constexpr14 std::size_t length(CharT* s) {
530 std::size_t result = 0;
531 while(*s++ !=
'\0') {
539 #if nssv_CPP11_OR_GREATER && !nssv_CPP17_OR_GREATER
540 #if defined(__OPTIMIZE__)
545 template <
class CharT,
class Traits = std::
char_traits<CharT>>
546 constexpr
const CharT* search(basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle) {
547 return haystack.starts_with(needle) ? haystack.begin() : haystack.empty() ? haystack.end() : search(haystack.substr(1), needle);
554 template <
class CharT,
class Traits = std::
char_traits<CharT>>
555 constexpr
const CharT* search(basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle) {
556 return std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end());
568 template <
class CharT,
class Traits
570 class basic_string_view {
574 typedef Traits traits_type;
575 typedef CharT value_type;
577 typedef CharT* pointer;
578 typedef CharT
const* const_pointer;
579 typedef CharT& reference;
580 typedef CharT
const& const_reference;
582 typedef const_pointer iterator;
583 typedef const_pointer const_iterator;
584 typedef std::reverse_iterator<const_iterator> reverse_iterator;
585 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
587 typedef std::size_t size_type;
588 typedef std::ptrdiff_t difference_type;
592 nssv_constexpr basic_string_view() nssv_noexcept : data_(nssv_nullptr), size_(0) {}
594 #if nssv_CPP11_OR_GREATER
595 nssv_constexpr basic_string_view(basic_string_view
const& other) nssv_noexcept =
default;
597 nssv_constexpr basic_string_view(basic_string_view
const& other) nssv_noexcept : data_(other.data_), size_(other.size_) {}
600 nssv_constexpr basic_string_view(CharT
const* s, size_type count) nssv_noexcept
604 nssv_constexpr basic_string_view(CharT
const* s) nssv_noexcept
606 #if nssv_CPP17_OR_GREATER
608 size_(Traits::length(s))
609 #elif nssv_CPP11_OR_GREATER
611 size_(detail::length(s))
614 size_(Traits::length(s))
619 #if nssv_HAVE_NULLPTR
620 #if nssv_HAVE_IS_DELETE
621 nssv_constexpr basic_string_view(std::nullptr_t) nssv_noexcept =
delete;
624 nssv_constexpr basic_string_view(std::nullptr_t) nssv_noexcept;
632 #if nssv_CPP11_OR_GREATER
633 nssv_constexpr14 basic_string_view& operator=(basic_string_view
const& other) nssv_noexcept =
default;
635 nssv_constexpr14 basic_string_view& operator=(basic_string_view
const& other) nssv_noexcept {
644 nssv_constexpr const_iterator begin() const nssv_noexcept {
return data_; }
645 nssv_constexpr const_iterator end() const nssv_noexcept {
return data_ + size_; }
647 nssv_constexpr const_iterator cbegin() const nssv_noexcept {
return begin(); }
648 nssv_constexpr const_iterator cend() const nssv_noexcept {
return end(); }
650 nssv_constexpr const_reverse_iterator rbegin() const nssv_noexcept {
return const_reverse_iterator(end()); }
651 nssv_constexpr const_reverse_iterator rend() const nssv_noexcept {
return const_reverse_iterator(begin()); }
653 nssv_constexpr const_reverse_iterator crbegin() const nssv_noexcept {
return rbegin(); }
654 nssv_constexpr const_reverse_iterator crend() const nssv_noexcept {
return rend(); }
658 nssv_constexpr size_type size() const nssv_noexcept {
return size_; }
659 nssv_constexpr size_type length() const nssv_noexcept {
return size_; }
660 nssv_constexpr size_type max_size() const nssv_noexcept {
return (std::numeric_limits<size_type>::max)(); }
663 nssv_nodiscard nssv_constexpr
bool empty() const nssv_noexcept {
return 0 == size_; }
667 nssv_constexpr const_reference operator[](size_type pos)
const {
return data_at(pos); }
669 nssv_constexpr14 const_reference at(size_type pos)
const {
670 #if nssv_CONFIG_NO_EXCEPTIONS
671 assert(pos < size());
674 throw std::out_of_range(
"nonstd::string_view::at()");
680 nssv_constexpr const_reference front()
const {
return data_at(0); }
681 nssv_constexpr const_reference back()
const {
return data_at(size() - 1); }
683 nssv_constexpr const_pointer data() const nssv_noexcept {
return data_; }
687 nssv_constexpr14
void remove_prefix(size_type n) {
693 nssv_constexpr14
void remove_suffix(size_type n) {
698 nssv_constexpr14
void swap(basic_string_view& other) nssv_noexcept {
699 const basic_string_view tmp(other);
706 size_type copy(CharT* dest, size_type n, size_type pos = 0)
const {
707 #if nssv_CONFIG_NO_EXCEPTIONS
708 assert(pos <= size());
711 throw std::out_of_range(
"nonstd::string_view::copy()");
714 const size_type rlen = (std::min)(n, size() - pos);
716 (void)Traits::copy(dest, data() + pos, rlen);
721 nssv_constexpr14 basic_string_view substr(size_type pos = 0, size_type n = npos)
const {
722 #if nssv_CONFIG_NO_EXCEPTIONS
723 assert(pos <= size());
726 throw std::out_of_range(
"nonstd::string_view::substr()");
729 return basic_string_view(data() + pos, (std::min)(n, size() - pos));
734 nssv_constexpr14
int compare(basic_string_view other)
const nssv_noexcept
736 #if nssv_CPP17_OR_GREATER
737 if(
const int result = Traits::compare(data(), other.data(), (std::min)(size(), other.size())))
739 if(
const int result = detail::compare(data(), other.data(), (std::min)(size(), other.size())))
745 return size() == other.size() ? 0 : size() < other.size() ? -1 : 1;
748 nssv_constexpr
int compare(size_type pos1, size_type n1, basic_string_view other)
const
750 return substr(pos1, n1).compare(other);
753 nssv_constexpr
int compare(size_type pos1, size_type n1, basic_string_view other, size_type pos2, size_type n2)
const
755 return substr(pos1, n1).compare(other.substr(pos2, n2));
758 nssv_constexpr
int compare(CharT
const* s)
const
760 return compare(basic_string_view(s));
763 nssv_constexpr
int compare(size_type pos1, size_type n1, CharT
const* s)
const
765 return substr(pos1, n1).compare(basic_string_view(s));
768 nssv_constexpr
int compare(size_type pos1, size_type n1, CharT
const* s, size_type n2)
const
770 return substr(pos1, n1).compare(basic_string_view(s, n2));
777 nssv_constexpr
bool starts_with(basic_string_view v)
const nssv_noexcept
779 return size() >= v.size() && compare(0, v.size(), v) == 0;
782 nssv_constexpr
bool starts_with(CharT c)
const nssv_noexcept
784 return starts_with(basic_string_view(&c, 1));
787 nssv_constexpr
bool starts_with(CharT
const* s)
const
789 return starts_with(basic_string_view(s));
794 nssv_constexpr
bool ends_with(basic_string_view v)
const nssv_noexcept
796 return size() >= v.size() && compare(size() - v.size(), npos, v) == 0;
799 nssv_constexpr
bool ends_with(CharT c)
const nssv_noexcept
801 return ends_with(basic_string_view(&c, 1));
804 nssv_constexpr
bool ends_with(CharT
const* s)
const
806 return ends_with(basic_string_view(s));
811 nssv_constexpr14 size_type find(basic_string_view v, size_type pos = 0) const nssv_noexcept
813 return assert(v.size() == 0 || v.data() != nssv_nullptr), pos >= size() ? npos
815 #
if nssv_CPP11_OR_GREATER && !nssv_CPP17_OR_GREATER
816 detail::search(substr(pos), v)
818 std::search(cbegin() + pos, cend(), v.cbegin(),
819 v.cend(), Traits::eq)
824 nssv_constexpr size_type find(CharT c, size_type pos = 0) const nssv_noexcept
826 return find(basic_string_view(&c, 1), pos);
829 nssv_constexpr size_type find(CharT
const* s, size_type pos, size_type n)
const
831 return find(basic_string_view(s, n), pos);
834 nssv_constexpr size_type find(CharT
const* s, size_type pos = 0) const
836 return find(basic_string_view(s), pos);
841 nssv_constexpr14 size_type rfind(basic_string_view v, size_type pos = npos)
const nssv_noexcept
843 if(size() < v.size()) {
848 return (std::min)(size(), pos);
851 const_iterator last = cbegin() + (std::min)(size() - v.size(), pos) + v.size();
852 const_iterator result = std::find_end(cbegin(), last, v.cbegin(), v.cend(), Traits::eq);
854 return result != last ? size_type(result - cbegin()) : npos;
857 nssv_constexpr14 size_type rfind(CharT c, size_type pos = npos)
const nssv_noexcept
859 return rfind(basic_string_view(&c, 1), pos);
862 nssv_constexpr14 size_type rfind(CharT
const* s, size_type pos, size_type n)
const
864 return rfind(basic_string_view(s, n), pos);
867 nssv_constexpr14 size_type rfind(CharT
const* s, size_type pos = npos)
const
869 return rfind(basic_string_view(s), pos);
874 nssv_constexpr size_type find_first_of(basic_string_view v, size_type pos = 0) const nssv_noexcept
876 return pos >= size() ? npos : to_pos(std::find_first_of(cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq));
879 nssv_constexpr size_type find_first_of(CharT c, size_type pos = 0) const nssv_noexcept
881 return find_first_of(basic_string_view(&c, 1), pos);
884 nssv_constexpr size_type find_first_of(CharT
const* s, size_type pos, size_type n)
const
886 return find_first_of(basic_string_view(s, n), pos);
889 nssv_constexpr size_type find_first_of(CharT
const* s, size_type pos = 0) const
891 return find_first_of(basic_string_view(s), pos);
896 nssv_constexpr size_type find_last_of(basic_string_view v, size_type pos = npos)
const nssv_noexcept
898 return empty() ? npos
900 ? find_last_of(v, size() - 1)
901 : to_pos(std::find_first_of(const_reverse_iterator(cbegin() + pos + 1), crend(), v.cbegin(), v.cend(), Traits::eq));
904 nssv_constexpr size_type find_last_of(CharT c, size_type pos = npos)
const nssv_noexcept
906 return find_last_of(basic_string_view(&c, 1), pos);
909 nssv_constexpr size_type find_last_of(CharT
const* s, size_type pos, size_type count)
const
911 return find_last_of(basic_string_view(s, count), pos);
914 nssv_constexpr size_type find_last_of(CharT
const* s, size_type pos = npos)
const
916 return find_last_of(basic_string_view(s), pos);
921 nssv_constexpr size_type find_first_not_of(basic_string_view v, size_type pos = 0) const nssv_noexcept
923 return pos >= size() ? npos : to_pos(std::find_if(cbegin() + pos, cend(), not_in_view(v)));
926 nssv_constexpr size_type find_first_not_of(CharT c, size_type pos = 0) const nssv_noexcept
928 return find_first_not_of(basic_string_view(&c, 1), pos);
931 nssv_constexpr size_type find_first_not_of(CharT
const* s, size_type pos, size_type count)
const
933 return find_first_not_of(basic_string_view(s, count), pos);
936 nssv_constexpr size_type find_first_not_of(CharT
const* s, size_type pos = 0) const
938 return find_first_not_of(basic_string_view(s), pos);
943 nssv_constexpr size_type find_last_not_of(basic_string_view v, size_type pos = npos)
const nssv_noexcept
945 return empty() ? npos
946 : pos >= size() ? find_last_not_of(v, size() - 1)
947 : to_pos(std::find_if(const_reverse_iterator(cbegin() + pos + 1), crend(), not_in_view(v)));
950 nssv_constexpr size_type find_last_not_of(CharT c, size_type pos = npos)
const nssv_noexcept
952 return find_last_not_of(basic_string_view(&c, 1), pos);
955 nssv_constexpr size_type find_last_not_of(CharT
const* s, size_type pos, size_type count)
const
957 return find_last_not_of(basic_string_view(s, count), pos);
960 nssv_constexpr size_type find_last_not_of(CharT
const* s, size_type pos = npos)
const
962 return find_last_not_of(basic_string_view(s), pos);
967 #if nssv_CPP17_OR_GREATER
968 static nssv_constexpr size_type npos = size_type(-1);
969 #elif nssv_CPP11_OR_GREATER
970 enum : size_type { npos = size_type(-1) };
972 enum { npos = size_type(-1) };
977 const basic_string_view v;
979 nssv_constexpr
explicit not_in_view(basic_string_view v_)
982 nssv_constexpr
bool operator()(CharT c)
const {
return npos == v.find_first_of(c); }
985 nssv_constexpr size_type to_pos(const_iterator it)
const {
return it == cend() ? npos : size_type(it - cbegin()); }
987 nssv_constexpr size_type to_pos(const_reverse_iterator it)
const {
return it == crend() ? npos : size_type(crend() - it - 1); }
989 nssv_constexpr const_reference data_at(size_type pos)
const {
990 #if nssv_BETWEEN(nssv_COMPILER_GNUC_VERSION, 1, 500)
993 return assert(pos < size()), data_[pos];
1002 #if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
1004 template <
class Allocator>
1005 basic_string_view(std::basic_string<CharT, Traits, Allocator>
const& s) nssv_noexcept : data_(s.data()), size_(s.size()) {}
1007 #if nssv_HAVE_EXPLICIT_CONVERSION
1009 template <
class Allocator>
explicit operator std::basic_string<CharT, Traits, Allocator>()
const {
return to_string(Allocator()); }
1013 #if nssv_CPP11_OR_GREATER
1015 template <
class Allocator = std::allocator<CharT>>
1016 std::basic_string<CharT, Traits, Allocator> to_string(Allocator
const& a = Allocator())
const {
1017 return std::basic_string<CharT, Traits, Allocator>(begin(), end(), a);
1022 std::basic_string<CharT, Traits> to_string()
const {
return std::basic_string<CharT, Traits>(begin(), end()); }
1024 template <
class Allocator> std::basic_string<CharT, Traits, Allocator> to_string(Allocator
const& a)
const {
1025 return std::basic_string<CharT, Traits, Allocator>(begin(), end(), a);
1040 template <
class CharT,
class Traits>
1041 nssv_constexpr
bool operator==(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1042 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
1045 template <
class CharT,
class Traits>
1046 nssv_constexpr
bool operator!=(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1047 return !(lhs == rhs);
1050 template <
class CharT,
class Traits>
1051 nssv_constexpr
bool operator<(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1052 return lhs.compare(rhs) < 0;
1055 template <
class CharT,
class Traits>
1056 nssv_constexpr
bool operator<=(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1057 return lhs.compare(rhs) <= 0;
1060 template <
class CharT,
class Traits>
1061 nssv_constexpr
bool operator>(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1062 return lhs.compare(rhs) > 0;
1065 template <
class CharT,
class Traits>
1066 nssv_constexpr
bool operator>=(basic_string_view<CharT, Traits> lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1067 return lhs.compare(rhs) >= 0;
1075 #if !nssv_CPP11_OR_GREATER || nssv_BETWEEN(nssv_COMPILER_MSVC_VERSION, 100, 141)
1081 template <
class CharT,
class Traits>
1082 nssv_constexpr
bool operator==(basic_string_view<CharT, Traits> lhs, CharT
const* rhs) nssv_noexcept {
1083 return lhs.size() == detail::length(rhs) && lhs.compare(rhs) == 0;
1086 template <
class CharT,
class Traits>
1087 nssv_constexpr
bool operator==(CharT
const* lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1088 return detail::length(lhs) == rhs.size() && rhs.compare(lhs) == 0;
1091 template <
class CharT,
class Traits>
1092 nssv_constexpr
bool operator==(basic_string_view<CharT, Traits> lhs, std::basic_string<CharT, Traits> rhs) nssv_noexcept {
1093 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
1096 template <
class CharT,
class Traits>
1097 nssv_constexpr
bool operator==(std::basic_string<CharT, Traits> rhs, basic_string_view<CharT, Traits> lhs) nssv_noexcept {
1098 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
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 == rhs);
1108 template <
class CharT,
class Traits>
1109 nssv_constexpr
bool operator!=(CharT
const* lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1110 return !(lhs == rhs);
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 == rhs);
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 == rhs);
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.compare(rhs) < 0;
1130 template <
class CharT,
class Traits>
1131 nssv_constexpr
bool operator<(CharT
const* lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1132 return rhs.compare(lhs) > 0;
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.compare(rhs) < 0;
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 rhs.compare(lhs) > 0;
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 #define nssv_BASIC_STRING_VIEW_I(T, U) typename std::decay<basic_string_view<T, U>>::type
1215 #if defined(_MSC_VER)
1216 #define nssv_MSVC_ORDER(x) , int = x
1218 #define nssv_MSVC_ORDER(x)
1223 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1224 nssv_constexpr
bool operator==(basic_string_view<CharT, Traits> lhs, nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1225 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
1228 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1229 nssv_constexpr
bool operator==(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1230 return lhs.size() == rhs.size() && lhs.compare(rhs) == 0;
1235 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1236 nssv_constexpr
bool operator!=(basic_string_view<CharT, Traits> lhs, nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1237 return !(lhs == rhs);
1240 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1241 nssv_constexpr
bool operator!=(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1242 return !(lhs == rhs);
1247 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1248 nssv_constexpr
bool operator<(basic_string_view<CharT, Traits> lhs, nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1249 return lhs.compare(rhs) < 0;
1252 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1253 nssv_constexpr
bool operator<(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1254 return lhs.compare(rhs) < 0;
1259 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1260 nssv_constexpr
bool operator<=(basic_string_view<CharT, Traits> lhs, nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1261 return lhs.compare(rhs) <= 0;
1264 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1265 nssv_constexpr
bool operator<=(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1266 return lhs.compare(rhs) <= 0;
1271 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1272 nssv_constexpr
bool operator>(basic_string_view<CharT, Traits> lhs, nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1273 return lhs.compare(rhs) > 0;
1276 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1277 nssv_constexpr
bool operator>(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1278 return lhs.compare(rhs) > 0;
1283 template <
class CharT,
class Traits nssv_MSVC_ORDER(1)>
1284 nssv_constexpr
bool operator>=(basic_string_view<CharT, Traits> lhs, nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs) nssv_noexcept {
1285 return lhs.compare(rhs) >= 0;
1288 template <
class CharT,
class Traits nssv_MSVC_ORDER(2)>
1289 nssv_constexpr
bool operator>=(nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, basic_string_view<CharT, Traits> rhs) nssv_noexcept {
1290 return lhs.compare(rhs) >= 0;
1293 #undef nssv_MSVC_ORDER
1294 #undef nssv_BASIC_STRING_VIEW_I
1300 #if !nssv_CONFIG_NO_STREAM_INSERTION
1304 template <
class Stream>
void write_padding(Stream& os, std::streamsize n) {
1305 for(std::streamsize i = 0; i < n; ++i)
1306 os.rdbuf()->sputc(os.fill());
1309 template <
class Stream,
class View> Stream& write_to_stream(Stream& os, View
const& sv) {
1310 typename Stream::sentry sentry(os);
1315 const std::streamsize length =
static_cast<std::streamsize
>(sv.length());
1318 const bool pad = (length < os.width());
1319 const bool left_pad = pad && (os.flags() & std::ios_base::adjustfield) == std::ios_base::right;
1322 write_padding(os, os.width() - length);
1325 os.rdbuf()->sputn(sv.begin(), length);
1327 if(pad && !left_pad)
1328 write_padding(os, os.width() - length);
1338 template <
class CharT,
class Traits>
1339 std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os, basic_string_view<CharT, Traits> sv) {
1340 return detail::write_to_stream(os, sv);
1347 typedef basic_string_view<char> string_view;
1348 typedef basic_string_view<wchar_t> wstring_view;
1349 #if nssv_HAVE_WCHAR16_T
1350 typedef basic_string_view<char16_t> u16string_view;
1351 typedef basic_string_view<char32_t> u32string_view;
1361 #if nssv_HAVE_USER_DEFINED_LITERALS
1364 nssv_inline_ns
namespace literals {
1365 nssv_inline_ns
namespace string_view_literals {
1367 #if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
1369 nssv_constexpr nonstd::sv_lite::string_view
operator"" sv(
const char* str,
size_t len) nssv_noexcept
1371 return nonstd::sv_lite::string_view{str, len};
1374 nssv_constexpr nonstd::sv_lite::u16string_view
operator"" sv(
const char16_t* str,
size_t len) nssv_noexcept
1376 return nonstd::sv_lite::u16string_view{str, len};
1379 nssv_constexpr nonstd::sv_lite::u32string_view
operator"" sv(
const char32_t* str,
size_t len) nssv_noexcept
1381 return nonstd::sv_lite::u32string_view{str, len};
1384 nssv_constexpr nonstd::sv_lite::wstring_view
operator"" sv(
const wchar_t* str,
size_t len) nssv_noexcept
1386 return nonstd::sv_lite::wstring_view{str, len};
1391 #if nssv_CONFIG_USR_SV_OPERATOR
1393 nssv_constexpr nonstd::sv_lite::string_view
operator"" _sv(
const char* str,
size_t len) nssv_noexcept
1395 return nonstd::sv_lite::string_view{str, len};
1398 nssv_constexpr nonstd::sv_lite::u16string_view
operator"" _sv(
const char16_t* str,
size_t len) nssv_noexcept
1400 return nonstd::sv_lite::u16string_view{str, len};
1403 nssv_constexpr nonstd::sv_lite::u32string_view
operator"" _sv(
const char32_t* str,
size_t len) nssv_noexcept
1405 return nonstd::sv_lite::u32string_view{str, len};
1408 nssv_constexpr nonstd::sv_lite::wstring_view
operator"" _sv(
const wchar_t* str,
size_t len) nssv_noexcept
1410 return nonstd::sv_lite::wstring_view{str, len};
1424 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1431 #if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140
1433 template <
class CharT,
class Traits,
class Allocator = std::allocator<CharT>>
1434 std::basic_string<CharT, Traits, Allocator> to_string(basic_string_view<CharT, Traits> v, Allocator
const& a = Allocator()) {
1435 return std::basic_string<CharT, Traits, Allocator>(v.begin(), v.end(), a);
1440 template <
class CharT,
class Traits> std::basic_string<CharT, Traits> to_string(basic_string_view<CharT, Traits> v) {
1441 return std::basic_string<CharT, Traits>(v.begin(), v.end());
1444 template <
class CharT,
class Traits,
class Allocator>
1445 std::basic_string<CharT, Traits, Allocator> to_string(basic_string_view<CharT, Traits> v, Allocator
const& a) {
1446 return std::basic_string<CharT, Traits, Allocator>(v.begin(), v.end(), a);
1451 template <
class CharT,
class Traits,
class Allocator>
1452 basic_string_view<CharT, Traits> to_string_view(std::basic_string<CharT, Traits, Allocator>
const& s) {
1453 return basic_string_view<CharT, Traits>(s.data(), s.size());
1467 using sv_lite::basic_string_view;
1468 using sv_lite::string_view;
1469 using sv_lite::wstring_view;
1471 #if nssv_HAVE_WCHAR16_T
1472 using sv_lite::u16string_view;
1474 #if nssv_HAVE_WCHAR32_T
1475 using sv_lite::u32string_view;
1480 using sv_lite::operator==;
1481 using sv_lite::operator!=;
1482 using sv_lite::operator<;
1483 using sv_lite::operator<=;
1484 using sv_lite::operator>;
1485 using sv_lite::operator>=;
1487 #if !nssv_CONFIG_NO_STREAM_INSERTION
1488 using sv_lite::operator<<;
1491 #if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
1492 using sv_lite::to_string;
1493 using sv_lite::to_string_view;
1503 #if nssv_HAVE_STD_HASH
1505 #include <functional>
1509 template <>
struct hash<nonstd::string_view> {
1511 std::size_t operator()(nonstd::string_view v)
const nssv_noexcept {
return std::hash<std::string>()(std::string(v.data(), v.size())); }
1514 template <>
struct hash<nonstd::wstring_view> {
1516 std::size_t operator()(nonstd::wstring_view v)
const nssv_noexcept {
1517 return std::hash<std::wstring>()(std::wstring(v.data(), v.size()));
1521 template <>
struct hash<nonstd::u16string_view> {
1523 std::size_t operator()(nonstd::u16string_view v)
const nssv_noexcept {
1524 return std::hash<std::u16string>()(std::u16string(v.data(), v.size()));
1528 template <>
struct hash<nonstd::u32string_view> {
1530 std::size_t operator()(nonstd::u32string_view v)
const nssv_noexcept {
1531 return std::hash<std::u32string>()(std::u32string(v.data(), v.size()));
1539 nssv_RESTORE_WARNINGS()
std::ostream & operator<<(std::ostream &stream, const std::vector< T > &vector)
a print function for a vector