diff options
Diffstat (limited to 'third_party/libcxx/include/c++/v1/string_view')
| -rw-r--r-- | third_party/libcxx/include/c++/v1/string_view | 984 |
1 files changed, 984 insertions, 0 deletions
diff --git a/third_party/libcxx/include/c++/v1/string_view b/third_party/libcxx/include/c++/v1/string_view new file mode 100644 index 0000000..5dd04a9 --- /dev/null +++ b/third_party/libcxx/include/c++/v1/string_view @@ -0,0 +1,984 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_STRING_VIEW +#define _LIBCPP_STRING_VIEW + +// clang-format off + +/* + + string_view synopsis + +#include <compare> + +namespace std { + + // 7.2, Class template basic_string_view + template<class charT, class traits = char_traits<charT>> + class basic_string_view; + + template<class charT, class traits> + inline constexpr bool ranges::enable_view<basic_string_view<charT, traits>> = true; + + template<class charT, class traits> + inline constexpr bool ranges::enable_borrowed_range<basic_string_view<charT, traits>> = true; // C++20 + + // 7.9, basic_string_view non-member comparison functions + template<class charT, class traits> + constexpr bool operator==(basic_string_view<charT, traits> x, + basic_string_view<charT, traits> y) noexcept; + template<class charT, class traits> // Removed in C++20 + constexpr bool operator!=(basic_string_view<charT, traits> x, + basic_string_view<charT, traits> y) noexcept; + template<class charT, class traits> // Removed in C++20 + constexpr bool operator< (basic_string_view<charT, traits> x, + basic_string_view<charT, traits> y) noexcept; + template<class charT, class traits> // Removed in C++20 + constexpr bool operator> (basic_string_view<charT, traits> x, + basic_string_view<charT, traits> y) noexcept; + template<class charT, class traits> // Removed in C++20 + constexpr bool operator<=(basic_string_view<charT, traits> x, + basic_string_view<charT, traits> y) noexcept; + template<class charT, class traits> // Removed in C++20 + constexpr bool operator>=(basic_string_view<charT, traits> x, + basic_string_view<charT, traits> y) noexcept; + template<class charT, class traits> // Since C++20 + constexpr see below operator<=>(basic_string_view<charT, traits> x, + basic_string_view<charT, traits> y) noexcept; + + // see below, sufficient additional overloads of comparison functions + + // 7.10, Inserters and extractors + template<class charT, class traits> + basic_ostream<charT, traits>& + operator<<(basic_ostream<charT, traits>& os, + basic_string_view<charT, traits> str); + + // basic_string_view typedef names + typedef basic_string_view<char> string_view; + typedef basic_string_view<char8_t> u8string_view; // C++20 + typedef basic_string_view<char16_t> u16string_view; + typedef basic_string_view<char32_t> u32string_view; + typedef basic_string_view<wchar_t> wstring_view; + + template<class charT, class traits = char_traits<charT>> + class basic_string_view { + public: + // types + typedef traits traits_type; + typedef charT value_type; + typedef charT* pointer; + typedef const charT* const_pointer; + typedef charT& reference; + typedef const charT& const_reference; + typedef implementation-defined const_iterator; + typedef const_iterator iterator; + typedef reverse_iterator<const_iterator> const_reverse_iterator; + typedef const_reverse_iterator reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + static constexpr size_type npos = size_type(-1); + + // 7.3, basic_string_view constructors and assignment operators + constexpr basic_string_view() noexcept; + constexpr basic_string_view(const basic_string_view&) noexcept = default; + basic_string_view& operator=(const basic_string_view&) noexcept = default; + template<class Allocator> + constexpr basic_string_view(const charT* str); + basic_string_view(nullptr_t) = delete; // C++23 + constexpr basic_string_view(const charT* str, size_type len); + template <class It, class End> + constexpr basic_string_view(It begin, End end); // C++20 + template <class Range> + constexpr basic_string_view(Range&& r); // C++23 + + // 7.4, basic_string_view iterator support + constexpr const_iterator begin() const noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + const_reverse_iterator rbegin() const noexcept; + const_reverse_iterator rend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + // 7.5, basic_string_view capacity + constexpr size_type size() const noexcept; + constexpr size_type length() const noexcept; + constexpr size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + + // 7.6, basic_string_view element access + constexpr const_reference operator[](size_type pos) const; + constexpr const_reference at(size_type pos) const; + constexpr const_reference front() const; + constexpr const_reference back() const; + constexpr const_pointer data() const noexcept; + + // 7.7, basic_string_view modifiers + constexpr void remove_prefix(size_type n); + constexpr void remove_suffix(size_type n); + constexpr void swap(basic_string_view& s) noexcept; + + size_type copy(charT* s, size_type n, size_type pos = 0) const; // constexpr in C++20 + + constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const; + constexpr basic_string_view subview(size_type pos = 0, + size_type n = npos) const; // freestanding-deleted, since C++26 + constexpr int compare(basic_string_view s) const noexcept; + constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const; + constexpr int compare(size_type pos1, size_type n1, + basic_string_view s, size_type pos2, size_type n2) const; + constexpr int compare(const charT* s) const; + constexpr int compare(size_type pos1, size_type n1, const charT* s) const; + constexpr int compare(size_type pos1, size_type n1, + const charT* s, size_type n2) const; + constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept; + constexpr size_type find(charT c, size_type pos = 0) const noexcept; + constexpr size_type find(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension + constexpr size_type find(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension + constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept; + constexpr size_type rfind(charT c, size_type pos = npos) const noexcept; + constexpr size_type rfind(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension + constexpr size_type rfind(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension + constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept; + constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept; + constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension + constexpr size_type find_first_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension + constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept; + constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept; + constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension + constexpr size_type find_last_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension + constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept; + constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept; + constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension + constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension + constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept; + constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept; + constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension + constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension + + constexpr bool starts_with(basic_string_view s) const noexcept; // C++20 + constexpr bool starts_with(charT c) const noexcept; // C++20 + constexpr bool starts_with(const charT* s) const; // C++20 + constexpr bool ends_with(basic_string_view s) const noexcept; // C++20 + constexpr bool ends_with(charT c) const noexcept; // C++20 + constexpr bool ends_with(const charT* s) const; // C++20 + + constexpr bool contains(basic_string_view s) const noexcept; // C++23 + constexpr bool contains(charT c) const noexcept; // C++23 + constexpr bool contains(const charT* s) const; // C++23 + + private: + const_pointer data_; // exposition only + size_type size_; // exposition only + }; + + // basic_string_view deduction guides + template<class It, class End> + basic_string_view(It, End) -> basic_string_view<iter_value_t<It>>; // C++20 + template<class Range> + basic_string_view(Range&&) -> basic_string_view<ranges::range_value_t<Range>>; // C++23 + + // 7.11, Hash support + template <class T> struct hash; + template <> struct hash<string_view>; + template <> struct hash<u8string_view>; // C++20 + template <> struct hash<u16string_view>; + template <> struct hash<u32string_view>; + template <> struct hash<wstring_view>; + + constexpr basic_string_view<char> operator""sv(const char *str, size_t len) noexcept; + constexpr basic_string_view<wchar_t> operator""sv(const wchar_t *str, size_t len) noexcept; + constexpr basic_string_view<char8_t> operator""sv(const char8_t *str, size_t len) noexcept; // C++20 + constexpr basic_string_view<char16_t> operator""sv(const char16_t *str, size_t len) noexcept; + constexpr basic_string_view<char32_t> operator""sv(const char32_t *str, size_t len) noexcept; + +} // namespace std + +*/ + +// clang-format on + +#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) +# include <__cxx03/string_view> +#else +# include <__algorithm/min.h> +# include <__assert> +# include <__config> +# include <__cstddef/nullptr_t.h> +# include <__cstddef/ptrdiff_t.h> +# include <__cstddef/size_t.h> +# include <__functional/hash.h> +# include <__functional/unary_function.h> +# include <__fwd/ostream.h> +# include <__fwd/string.h> +# include <__fwd/string_view.h> +# include <__iterator/bounded_iter.h> +# include <__iterator/concepts.h> +# include <__iterator/iterator_traits.h> +# include <__iterator/reverse_iterator.h> +# include <__iterator/wrap_iter.h> +# include <__memory/pointer_traits.h> +# include <__ranges/concepts.h> +# include <__ranges/data.h> +# include <__ranges/enable_borrowed_range.h> +# include <__ranges/enable_view.h> +# include <__ranges/size.h> +# include <__string/char_traits.h> +# include <__type_traits/is_array.h> +# include <__type_traits/is_convertible.h> +# include <__type_traits/is_same.h> +# include <__type_traits/is_standard_layout.h> +# include <__type_traits/is_trivially_constructible.h> +# include <__type_traits/is_trivially_copyable.h> +# include <__type_traits/remove_cvref.h> +# include <__type_traits/remove_reference.h> +# include <__type_traits/type_identity.h> +# include <iosfwd> +# include <limits> +# include <stdexcept> +# include <version> + +// standard-mandated includes + +// [iterator.range] +# include <__iterator/access.h> +# include <__iterator/data.h> +# include <__iterator/empty.h> +# include <__iterator/reverse_access.h> +# include <__iterator/size.h> + +// [string.view.synop] +# include <compare> + +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +_LIBCPP_PUSH_MACROS +# include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// TODO: This is a workaround for some vendors to carry a downstream diff to accept `nullptr` in +// string_view constructors. This can be refactored when this exact form isn't needed anymore. +template <class _Traits> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR inline size_t +__char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT { + // This needs to be a single statement for C++11 constexpr + return _LIBCPP_ASSERT_NON_NULL( + __s != nullptr, "null pointer passed to non-null argument of char_traits<...>::length"), + _Traits::length(__s); +} + +template <class _CharT, class _Traits> +class basic_string_view { +public: + // types + using traits_type = _Traits; + using value_type = _CharT; + using pointer = _CharT*; + using const_pointer = const _CharT*; + using reference = _CharT&; + using const_reference = const _CharT&; +# if defined(_LIBCPP_ABI_BOUNDED_ITERATORS) + using const_iterator = __bounded_iter<const_pointer>; +# elif defined(_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW) + using const_iterator = __wrap_iter<const_pointer>; +# else + using const_iterator = const_pointer; +# endif + using iterator = const_iterator; + using const_reverse_iterator = std::reverse_iterator<const_iterator>; + using reverse_iterator = const_reverse_iterator; + using size_type = size_t; + using difference_type = ptrdiff_t; + static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1); + + static_assert(!is_array<value_type>::value, "Character type of basic_string_view must not be an array"); + static_assert(is_standard_layout<value_type>::value, "Character type of basic_string_view must be standard-layout"); + static_assert(is_trivially_default_constructible<value_type>::value, + "Character type of basic_string_view must be trivially default constructible"); + static_assert(is_trivially_copyable<value_type>::value, + "Character type of basic_string_view must be trivially copyable"); + static_assert(is_same<_CharT, typename traits_type::char_type>::value, + "traits_type::char_type must be the same type as CharT"); + + // [string.view.cons], construct/copy + _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view() _NOEXCEPT : __data_(nullptr), __size_(0) {} + + _LIBCPP_HIDE_FROM_ABI basic_string_view(const basic_string_view&) _NOEXCEPT = default; + + _LIBCPP_HIDE_FROM_ABI basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default; + + _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT + _LIBCPP_DIAGNOSE_NULLPTR_IF(__len != 0 && __s == nullptr, " if len is not zero") + : __data_(__s), __size_(__len) { +# if !defined(_LIBCPP_CXX03_LANG) && (!defined(_LIBCPP_COMPILER_GCC) || _LIBCPP_STD_VER >= 14) + // Allocations must fit in `ptrdiff_t` for pointer arithmetic to work. If `__len` exceeds it, the input + // range could not have been valid. Most likely the caller underflowed some arithmetic and inadvertently + // passed in a negative length. + _LIBCPP_ASSERT_VALID_INPUT_RANGE( + __len <= static_cast<size_type>(numeric_limits<difference_type>::max()), + "string_view::string_view(_CharT *, size_t): length does not fit in difference_type"); + _LIBCPP_ASSERT_NON_NULL( + __len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr"); +# endif + } + +# if _LIBCPP_STD_VER >= 20 + template <contiguous_iterator _It, sized_sentinel_for<_It> _End> + requires(is_same_v<iter_value_t<_It>, _CharT> && !is_convertible_v<_End, size_type>) + constexpr _LIBCPP_HIDE_FROM_ABI basic_string_view(_It __begin, _End __end) + : __data_(std::to_address(__begin)), __size_(__end - __begin) { + _LIBCPP_ASSERT_VALID_INPUT_RANGE( + (__end - __begin) >= 0, "std::string_view::string_view(iterator, sentinel) received invalid range"); + } +# endif // _LIBCPP_STD_VER >= 20 + +# if _LIBCPP_STD_VER >= 23 + template <class _Range> + requires(!is_same_v<remove_cvref_t<_Range>, basic_string_view> && ranges::contiguous_range<_Range> && + ranges::sized_range<_Range> && is_same_v<ranges::range_value_t<_Range>, _CharT> && + !is_convertible_v<_Range, const _CharT*> && + (!requires(remove_cvref_t<_Range>& __d) { __d.operator std::basic_string_view<_CharT, _Traits>(); })) + constexpr explicit _LIBCPP_HIDE_FROM_ABI basic_string_view(_Range&& __r) + : __data_(ranges::data(__r)), __size_(ranges::size(__r)) {} +# endif // _LIBCPP_STD_VER >= 23 + + _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) + : __data_(__s), __size_(std::__char_traits_length_checked<_Traits>(__s)) {} + +# if _LIBCPP_STD_VER >= 23 + basic_string_view(nullptr_t) = delete; +# endif + + // [string.view.iterators], iterators + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return cbegin(); } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return cend(); } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS + return std::__make_bounded_iter(data(), data(), data() + size()); +# else + return const_iterator(__data_); +# endif + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { +# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS + return std::__make_bounded_iter(data() + size(), data(), data() + size()); +# else + return const_iterator(__data_ + __size_); +# endif + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator + rbegin() const _NOEXCEPT { + return const_reverse_iterator(cend()); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { + return const_reverse_iterator(cbegin()); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator + crbegin() const _NOEXCEPT { + return const_reverse_iterator(cend()); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { + return const_reverse_iterator(cbegin()); + } + + // [string.view.capacity], capacity + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type length() const _NOEXCEPT { return __size_; } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { + return numeric_limits<size_type>::max() / sizeof(value_type); + } + + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return __size_ == 0; } + + // [string.view.access], element access + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference + operator[](size_type __pos) const _NOEXCEPT { + return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos < size(), "string_view[] index out of bounds"), __data_[__pos]; + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __pos) const { + return __pos >= size() ? (__throw_out_of_range("string_view::at"), __data_[0]) : __data_[__pos]; + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT { + return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::front(): string is empty"), __data_[0]; + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT { + return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::back(): string is empty"), __data_[__size_ - 1]; + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_pointer data() const _NOEXCEPT { return __data_; } + + // [string.view.modifiers], modifiers: + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI void remove_prefix(size_type __n) _NOEXCEPT { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n <= size(), "remove_prefix() can't remove more than size()"); + __data_ += __n; + __size_ -= __n; + } + + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI void remove_suffix(size_type __n) _NOEXCEPT { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n <= size(), "remove_suffix() can't remove more than size()"); + __size_ -= __n; + } + + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI void swap(basic_string_view& __other) _NOEXCEPT { + const value_type* __p = __data_; + __data_ = __other.__data_; + __other.__data_ = __p; + + size_type __sz = __size_; + __size_ = __other.__size_; + __other.__size_ = __sz; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const { + if (__pos > size()) + std::__throw_out_of_range("string_view::copy"); + size_type __rlen = std::min(__n, size() - __pos); + _Traits::copy(__s, data() + __pos, __rlen); + return __rlen; + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view + substr(size_type __pos = 0, size_type __n = npos) const { + // Use the `__assume_valid` form of the constructor to avoid an unnecessary check. Any substring of a view is a + // valid view. In particular, `size()` is known to be smaller than `numeric_limits<difference_type>::max()`, so the + // new size is also smaller. See also https://llvm.org/PR91634. + return __pos > size() ? (__throw_out_of_range("string_view::substr"), basic_string_view()) + : basic_string_view(__assume_valid(), data() + __pos, std::min(__n, size() - __pos)); + } + +# if _LIBCPP_STD_VER >= 26 + [[nodiscard]] + _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view subview(size_type __pos = 0, size_type __n = npos) const { + return substr(__pos, __n); + } +# endif + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 int compare(basic_string_view __sv) const _NOEXCEPT { + size_type __rlen = std::min(size(), __sv.size()); + int __retval = _Traits::compare(data(), __sv.data(), __rlen); + if (__retval == 0) // first __rlen chars matched + __retval = size() == __sv.size() ? 0 : (size() < __sv.size() ? -1 : 1); + return __retval; + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int + compare(size_type __pos1, size_type __n1, basic_string_view __sv) const { + return substr(__pos1, __n1).compare(__sv); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int + compare(size_type __pos1, size_type __n1, basic_string_view __sv, size_type __pos2, size_type __n2) const { + return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int + compare(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) const _NOEXCEPT { + return compare(basic_string_view(__s)); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int + compare(size_type __pos1, size_type __n1, const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) const { + return substr(__pos1, __n1).compare(basic_string_view(__s)); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int + compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const + _LIBCPP_DIAGNOSE_NULLPTR_IF(__n2 != 0 && __s == nullptr, " if n2 is not zero") { + return substr(__pos1, __n1).compare(basic_string_view(__s, __n2)); + } + + // find + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT { + return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size()); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find(_CharT __c, size_type __pos = 0) const _NOEXCEPT { + return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT + _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { + _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find(): received nullptr"); + return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT { + _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find(): received nullptr"); + return std::__str_find<value_type, size_type, traits_type, npos>( + data(), size(), __s, __pos, traits_type::length(__s)); + } + + // rfind + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT { + return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size()); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT { + return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT + _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { + _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr"); + return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + rfind(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT { + _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::rfind(): received nullptr"); + return std::__str_rfind<value_type, size_type, traits_type, npos>( + data(), size(), __s, __pos, traits_type::length(__s)); + } + + // find_first_of + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT { + return std::__str_find_first_of<value_type, size_type, traits_type, npos>( + data(), size(), __s.data(), __pos, __s.size()); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT { + return find(__c, __pos); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT + _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { + _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr"); + return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_first_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT { + _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_of(): received nullptr"); + return std::__str_find_first_of<value_type, size_type, traits_type, npos>( + data(), size(), __s, __pos, traits_type::length(__s)); + } + + // find_last_of + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_last_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT { + return std::__str_find_last_of<value_type, size_type, traits_type, npos>( + data(), size(), __s.data(), __pos, __s.size()); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT { + return rfind(__c, __pos); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT + _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { + _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr"); + return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_last_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT { + _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_of(): received nullptr"); + return std::__str_find_last_of<value_type, size_type, traits_type, npos>( + data(), size(), __s, __pos, traits_type::length(__s)); + } + + // find_first_not_of + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_first_not_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT { + return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( + data(), size(), __s.data(), __pos, __s.size()); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT { + return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT + _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { + _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr"); + return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_first_not_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT { + _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_not_of(): received nullptr"); + return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>( + data(), size(), __s, __pos, traits_type::length(__s)); + } + + // find_last_not_of + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_last_not_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT { + return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( + data(), size(), __s.data(), __pos, __s.size()); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_last_not_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT { + return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT + _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") { + _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr"); + return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n); + } + + [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type + find_last_not_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT { + _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_not_of(): received nullptr"); + return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>( + data(), size(), __s, __pos, traits_type::length(__s)); + } + +# if _LIBCPP_STD_VER >= 20 + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(basic_string_view __s) const noexcept { + return size() >= __s.size() && compare(0, __s.size(), __s) == 0; + } + + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept { + return !empty() && _Traits::eq(front(), __c); + } + + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool + starts_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept { + return starts_with(basic_string_view(__s)); + } + + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(basic_string_view __s) const noexcept { + return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0; + } + + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept { + return !empty() && _Traits::eq(back(), __c); + } + + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool + ends_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept { + return ends_with(basic_string_view(__s)); + } +# endif + +# if _LIBCPP_STD_VER >= 23 + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(basic_string_view __sv) const noexcept { + return find(__sv) != npos; + } + + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { + return find(__c) != npos; + } + + [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const { + return find(__s) != npos; + } +# endif + +private: + struct __assume_valid {}; + + // This is the same as the pointer and length constructor, but without the additional hardening checks. It is intended + // for use within the class, when the class invariants already guarantee the resulting object is valid. The compiler + // usually cannot eliminate the redundant checks because it does not know class invariants. + _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI + basic_string_view(__assume_valid, const _CharT* __s, size_type __len) _NOEXCEPT + : __data_(__s), + __size_(__len) {} + + const value_type* __data_; + size_type __size_; + + template <class, class, class> + friend class basic_string; +}; +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_string_view); + +# if _LIBCPP_STD_VER >= 20 +template <class _CharT, class _Traits> +inline constexpr bool ranges::enable_view<basic_string_view<_CharT, _Traits>> = true; + +template <class _CharT, class _Traits> +inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true; +# endif // _LIBCPP_STD_VER >= 20 + +// [string.view.deduct] + +# if _LIBCPP_STD_VER >= 20 +template <contiguous_iterator _It, sized_sentinel_for<_It> _End> +basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>; +# endif // _LIBCPP_STD_VER >= 20 + +# if _LIBCPP_STD_VER >= 23 +template <ranges::contiguous_range _Range> +basic_string_view(_Range) -> basic_string_view<ranges::range_value_t<_Range>>; +# endif + +// [string.view.comparison] + +// The dummy default template parameters are used to work around a MSVC issue with mangling, see VSO-409326 for details. +// This applies to the other sufficient overloads below for the other comparison operators. +template <class _CharT, class _Traits, int = 1> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator==(basic_string_view<_CharT, _Traits> __lhs, + __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT { + if (__lhs.size() != __rhs.size()) + return false; + return __lhs.compare(__rhs) == 0; +} + +# if _LIBCPP_STD_VER >= 20 + +template <class _CharT, class _Traits> +_LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(basic_string_view<_CharT, _Traits> __lhs, + type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) noexcept { + if constexpr (requires { typename _Traits::comparison_category; }) { + // [string.view]/4 + static_assert( + __comparison_category<typename _Traits::comparison_category>, "return type is not a comparison category type"); + return static_cast<typename _Traits::comparison_category>(__lhs.compare(__rhs) <=> 0); + } else { + return static_cast<weak_ordering>(__lhs.compare(__rhs) <=> 0); + } +} + +# else + +// operator == + +template <class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator==(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT { + if (__lhs.size() != __rhs.size()) + return false; + return __lhs.compare(__rhs) == 0; +} + +template <class _CharT, class _Traits, int = 2> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator==(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT { + return __lhs == __rhs; +} + +// operator != +template <class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT { + return !(__lhs == __rhs); +} + +template <class _CharT, class _Traits, int = 1> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator!=(basic_string_view<_CharT, _Traits> __lhs, + __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT { + return !(__lhs == __rhs); +} + +template <class _CharT, class _Traits, int = 2> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator!=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT { + return !(__lhs == __rhs); +} + +// operator < +template <class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT { + return __lhs.compare(__rhs) < 0; +} + +template <class _CharT, class _Traits, int = 1> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator<(basic_string_view<_CharT, _Traits> __lhs, + __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT { + return __lhs.compare(__rhs) < 0; +} + +template <class _CharT, class _Traits, int = 2> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator<(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT { + return __lhs.compare(__rhs) < 0; +} + +// operator > +template <class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator>(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT { + return __lhs.compare(__rhs) > 0; +} + +template <class _CharT, class _Traits, int = 1> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator>(basic_string_view<_CharT, _Traits> __lhs, + __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT { + return __lhs.compare(__rhs) > 0; +} + +template <class _CharT, class _Traits, int = 2> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator>(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT { + return __lhs.compare(__rhs) > 0; +} + +// operator <= +template <class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT { + return __lhs.compare(__rhs) <= 0; +} + +template <class _CharT, class _Traits, int = 1> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator<=(basic_string_view<_CharT, _Traits> __lhs, + __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT { + return __lhs.compare(__rhs) <= 0; +} + +template <class _CharT, class _Traits, int = 2> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator<=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT { + return __lhs.compare(__rhs) <= 0; +} + +// operator >= +template <class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT { + return __lhs.compare(__rhs) >= 0; +} + +template <class _CharT, class _Traits, int = 1> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator>=(basic_string_view<_CharT, _Traits> __lhs, + __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT { + return __lhs.compare(__rhs) >= 0; +} + +template <class _CharT, class _Traits, int = 2> +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool +operator>=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT { + return __lhs.compare(__rhs) >= 0; +} + +# endif // _LIBCPP_STD_VER >= 20 + +template <class _CharT, class _Traits> +_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __str); + +// [string.view.hash] +template <class _CharT> +struct __string_view_hash : public __unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t> { + [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t + operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT { + return std::__do_string_hash(__val.data(), __val.data() + __val.size()); + } +}; + +template <> +struct hash<basic_string_view<char, char_traits<char> > > : __string_view_hash<char> {}; + +# if _LIBCPP_HAS_CHAR8_T +template <> +struct hash<basic_string_view<char8_t, char_traits<char8_t> > > : __string_view_hash<char8_t> {}; +# endif + +template <> +struct hash<basic_string_view<char16_t, char_traits<char16_t> > > : __string_view_hash<char16_t> {}; + +template <> +struct hash<basic_string_view<char32_t, char_traits<char32_t> > > : __string_view_hash<char32_t> {}; + +# if _LIBCPP_HAS_WIDE_CHARACTERS +template <> +struct hash<basic_string_view<wchar_t, char_traits<wchar_t> > > : __string_view_hash<wchar_t> {}; +# endif + +# if _LIBCPP_STD_VER >= 14 +inline namespace literals { +inline namespace string_view_literals { +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char> +operator""sv(const char* __str, size_t __len) noexcept { + return basic_string_view<char>(__str, __len); +} + +# if _LIBCPP_HAS_WIDE_CHARACTERS +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<wchar_t> +operator""sv(const wchar_t* __str, size_t __len) noexcept { + return basic_string_view<wchar_t>(__str, __len); +} +# endif + +# if _LIBCPP_HAS_CHAR8_T +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char8_t> +operator""sv(const char8_t* __str, size_t __len) noexcept { + return basic_string_view<char8_t>(__str, __len); +} +# endif + +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char16_t> +operator""sv(const char16_t* __str, size_t __len) noexcept { + return basic_string_view<char16_t>(__str, __len); +} + +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char32_t> +operator""sv(const char32_t* __str, size_t __len) noexcept { + return basic_string_view<char32_t>(__str, __len); +} +} // namespace string_view_literals +} // namespace literals +# endif +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 +# include <algorithm> +# include <concepts> +# include <cstdlib> +# include <iterator> +# include <optional> +# include <type_traits> +# endif +#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) + +#endif // _LIBCPP_STRING_VIEW |
