[rtsan] Remove mkfifoat interceptor (#116997)
[llvm-project.git] / libcxx / include / __cxx03 / string_view
blob8b21ecb3d9a8befaa98305cf80a2a1a253760e88
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_STRING_VIEW
11 #define _LIBCPP_STRING_VIEW
13 // clang-format off
17     string_view synopsis
19 #include <__cxx03/compare>
21 namespace std {
23     // 7.2, Class template basic_string_view
24     template<class charT, class traits = char_traits<charT>>
25         class basic_string_view;
27     template<class charT, class traits>
28     inline constexpr bool ranges::enable_view<basic_string_view<charT, traits>> = true;
30     template<class charT, class traits>
31     inline constexpr bool ranges::enable_borrowed_range<basic_string_view<charT, traits>> = true;  // C++20
33     // 7.9, basic_string_view non-member comparison functions
34     template<class charT, class traits>
35     constexpr bool operator==(basic_string_view<charT, traits> x,
36                               basic_string_view<charT, traits> y) noexcept;
37     template<class charT, class traits>                                                            // Removed in C++20
38     constexpr bool operator!=(basic_string_view<charT, traits> x,
39                               basic_string_view<charT, traits> y) noexcept;
40     template<class charT, class traits>                                                            // Removed in C++20
41     constexpr bool operator< (basic_string_view<charT, traits> x,
42                                  basic_string_view<charT, traits> y) noexcept;
43     template<class charT, class traits>                                                            // Removed in C++20
44     constexpr bool operator> (basic_string_view<charT, traits> x,
45                               basic_string_view<charT, traits> y) noexcept;
46     template<class charT, class traits>                                                            // Removed in C++20
47     constexpr bool operator<=(basic_string_view<charT, traits> x,
48                                  basic_string_view<charT, traits> y) noexcept;
49     template<class charT, class traits>                                                            // Removed in C++20
50     constexpr bool operator>=(basic_string_view<charT, traits> x,
51                               basic_string_view<charT, traits> y) noexcept;
52     template<class charT, class traits>                                                            // Since C++20
53     constexpr see below operator<=>(basic_string_view<charT, traits> x,
54                                     basic_string_view<charT, traits> y) noexcept;
56     // see below, sufficient additional overloads of comparison functions
58     // 7.10, Inserters and extractors
59     template<class charT, class traits>
60       basic_ostream<charT, traits>&
61         operator<<(basic_ostream<charT, traits>& os,
62                    basic_string_view<charT, traits> str);
64     // basic_string_view typedef names
65     typedef basic_string_view<char> string_view;
66     typedef basic_string_view<char8_t> u8string_view; // C++20
67     typedef basic_string_view<char16_t> u16string_view;
68     typedef basic_string_view<char32_t> u32string_view;
69     typedef basic_string_view<wchar_t> wstring_view;
71     template<class charT, class traits = char_traits<charT>>
72     class basic_string_view {
73       public:
74       // types
75       typedef traits traits_type;
76       typedef charT value_type;
77       typedef charT* pointer;
78       typedef const charT* const_pointer;
79       typedef charT& reference;
80       typedef const charT& const_reference;
81       typedef implementation-defined const_iterator;
82       typedef const_iterator iterator;
83       typedef reverse_iterator<const_iterator> const_reverse_iterator;
84       typedef const_reverse_iterator reverse_iterator;
85       typedef size_t size_type;
86       typedef ptrdiff_t difference_type;
87       static constexpr size_type npos = size_type(-1);
89       // 7.3, basic_string_view constructors and assignment operators
90       constexpr basic_string_view() noexcept;
91       constexpr basic_string_view(const basic_string_view&) noexcept = default;
92       basic_string_view& operator=(const basic_string_view&) noexcept = default;
93       template<class Allocator>
94       constexpr basic_string_view(const charT* str);
95       basic_string_view(nullptr_t) = delete; // C++23
96       constexpr basic_string_view(const charT* str, size_type len);
97       template <class It, class End>
98       constexpr basic_string_view(It begin, End end); // C++20
99       template <class Range>
100       constexpr basic_string_view(Range&& r); // C++23
102       // 7.4, basic_string_view iterator support
103       constexpr const_iterator begin() const noexcept;
104       constexpr const_iterator end() const noexcept;
105       constexpr const_iterator cbegin() const noexcept;
106       constexpr const_iterator cend() const noexcept;
107       const_reverse_iterator rbegin() const noexcept;
108       const_reverse_iterator rend() const noexcept;
109       const_reverse_iterator crbegin() const noexcept;
110       const_reverse_iterator crend() const noexcept;
112       // 7.5, basic_string_view capacity
113       constexpr size_type size() const noexcept;
114       constexpr size_type length() const noexcept;
115       constexpr size_type max_size() const noexcept;
116       constexpr bool empty() const noexcept;
118       // 7.6, basic_string_view element access
119       constexpr const_reference operator[](size_type pos) const;
120       constexpr const_reference at(size_type pos) const;
121       constexpr const_reference front() const;
122       constexpr const_reference back() const;
123       constexpr const_pointer data() const noexcept;
125       // 7.7, basic_string_view modifiers
126       constexpr void remove_prefix(size_type n);
127       constexpr void remove_suffix(size_type n);
128       constexpr void swap(basic_string_view& s) noexcept;
130       size_type copy(charT* s, size_type n, size_type pos = 0) const;  // constexpr in C++20
132       constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
133       constexpr int compare(basic_string_view s) const noexcept;
134       constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;
135       constexpr int compare(size_type pos1, size_type n1,
136                             basic_string_view s, size_type pos2, size_type n2) const;
137       constexpr int compare(const charT* s) const;
138       constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
139       constexpr int compare(size_type pos1, size_type n1,
140                             const charT* s, size_type n2) const;
141       constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;
142       constexpr size_type find(charT c, size_type pos = 0) const noexcept;
143       constexpr size_type find(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
144       constexpr size_type find(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension
145       constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;
146       constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;
147       constexpr size_type rfind(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
148       constexpr size_type rfind(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension
149       constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;
150       constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;
151       constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
152       constexpr size_type find_first_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension
153       constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;
154       constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;
155       constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
156       constexpr size_type find_last_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension
157       constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;
158       constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;
159       constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
160       constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension
161       constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept;
162       constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;
163       constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
164       constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension
166       constexpr bool starts_with(basic_string_view s) const noexcept; // C++20
167       constexpr bool starts_with(charT c) const noexcept;             // C++20
168       constexpr bool starts_with(const charT* s) const;               // C++20
169       constexpr bool ends_with(basic_string_view s) const noexcept;   // C++20
170       constexpr bool ends_with(charT c) const noexcept;               // C++20
171       constexpr bool ends_with(const charT* s) const;                 // C++20
173       constexpr bool contains(basic_string_view s) const noexcept; // C++23
174       constexpr bool contains(charT c) const noexcept;             // C++23
175       constexpr bool contains(const charT* s) const;               // C++23
177      private:
178       const_pointer data_;  // exposition only
179       size_type     size_;  // exposition only
180     };
182   // basic_string_view deduction guides
183   template<class It, class End>
184     basic_string_view(It, End) -> basic_string_view<iter_value_t<It>>; // C++20
185   template<class Range>
186     basic_string_view(Range&&) -> basic_string_view<ranges::range_value_t<Range>>; // C++23
188   // 7.11, Hash support
189   template <class T> struct hash;
190   template <> struct hash<string_view>;
191   template <> struct hash<u8string_view>; // C++20
192   template <> struct hash<u16string_view>;
193   template <> struct hash<u32string_view>;
194   template <> struct hash<wstring_view>;
196   constexpr basic_string_view<char>     operator""sv(const char *str,     size_t len) noexcept;
197   constexpr basic_string_view<wchar_t>  operator""sv(const wchar_t *str,  size_t len) noexcept;
198   constexpr basic_string_view<char8_t>  operator""sv(const char8_t *str,  size_t len) noexcept; // C++20
199   constexpr basic_string_view<char16_t> operator""sv(const char16_t *str, size_t len) noexcept;
200   constexpr basic_string_view<char32_t> operator""sv(const char32_t *str, size_t len) noexcept;
202 }  // namespace std
206 // clang-format on
208 #include <__cxx03/__algorithm/min.h>
209 #include <__cxx03/__assert>
210 #include <__cxx03/__config>
211 #include <__cxx03/__functional/hash.h>
212 #include <__cxx03/__functional/unary_function.h>
213 #include <__cxx03/__fwd/ostream.h>
214 #include <__cxx03/__fwd/string_view.h>
215 #include <__cxx03/__iterator/bounded_iter.h>
216 #include <__cxx03/__iterator/concepts.h>
217 #include <__cxx03/__iterator/iterator_traits.h>
218 #include <__cxx03/__iterator/reverse_iterator.h>
219 #include <__cxx03/__iterator/wrap_iter.h>
220 #include <__cxx03/__memory/pointer_traits.h>
221 #include <__cxx03/__ranges/concepts.h>
222 #include <__cxx03/__ranges/data.h>
223 #include <__cxx03/__ranges/enable_borrowed_range.h>
224 #include <__cxx03/__ranges/enable_view.h>
225 #include <__cxx03/__ranges/size.h>
226 #include <__cxx03/__string/char_traits.h>
227 #include <__cxx03/__type_traits/is_array.h>
228 #include <__cxx03/__type_traits/is_convertible.h>
229 #include <__cxx03/__type_traits/is_same.h>
230 #include <__cxx03/__type_traits/is_standard_layout.h>
231 #include <__cxx03/__type_traits/is_trivial.h>
232 #include <__cxx03/__type_traits/remove_cvref.h>
233 #include <__cxx03/__type_traits/remove_reference.h>
234 #include <__cxx03/__type_traits/type_identity.h>
235 #include <__cxx03/cstddef>
236 #include <__cxx03/iosfwd>
237 #include <__cxx03/limits>
238 #include <__cxx03/stdexcept>
239 #include <__cxx03/version>
241 // standard-mandated includes
243 // [iterator.range]
244 #include <__cxx03/__iterator/access.h>
245 #include <__cxx03/__iterator/data.h>
246 #include <__cxx03/__iterator/empty.h>
247 #include <__cxx03/__iterator/reverse_access.h>
248 #include <__cxx03/__iterator/size.h>
250 // [string.view.synop]
251 #include <__cxx03/compare>
253 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
254 #  pragma GCC system_header
255 #endif
257 _LIBCPP_PUSH_MACROS
258 #include <__cxx03/__undef_macros>
260 _LIBCPP_BEGIN_NAMESPACE_STD
262 // TODO: This is a workaround for some vendors to carry a downstream diff to accept `nullptr` in
263 //       string_view constructors. This can be refactored when this exact form isn't needed anymore.
264 template <class _Traits>
265 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR inline size_t
266 __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT {
267   // This needs to be a single statement for C++11 constexpr
268   return _LIBCPP_ASSERT_NON_NULL(
269              __s != nullptr, "null pointer passed to non-null argument of char_traits<...>::length"),
270          _Traits::length(__s);
273 template <class _CharT, class _Traits>
274 class basic_string_view {
275 public:
276   // types
277   using traits_type     = _Traits;
278   using value_type      = _CharT;
279   using pointer         = _CharT*;
280   using const_pointer   = const _CharT*;
281   using reference       = _CharT&;
282   using const_reference = const _CharT&;
283 #if defined(_LIBCPP_ABI_BOUNDED_ITERATORS)
284   using const_iterator = __bounded_iter<const_pointer>;
285 #elif defined(_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW)
286   using const_iterator = __wrap_iter<const_pointer>;
287 #else
288   using const_iterator = const_pointer;
289 #endif
290   using iterator                                = const_iterator;
291   using const_reverse_iterator                  = std::reverse_iterator<const_iterator>;
292   using reverse_iterator                        = const_reverse_iterator;
293   using size_type                               = size_t;
294   using difference_type                         = ptrdiff_t;
295   static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1);
297   static_assert(!is_array<value_type>::value, "Character type of basic_string_view must not be an array");
298   static_assert(is_standard_layout<value_type>::value, "Character type of basic_string_view must be standard-layout");
299   static_assert(is_trivial<value_type>::value, "Character type of basic_string_view must be trivial");
300   static_assert(is_same<_CharT, typename traits_type::char_type>::value,
301                 "traits_type::char_type must be the same type as CharT");
303   // [string.view.cons], construct/copy
304   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view() _NOEXCEPT : __data_(nullptr), __size_(0) {}
306   _LIBCPP_HIDE_FROM_ABI basic_string_view(const basic_string_view&) _NOEXCEPT = default;
308   _LIBCPP_HIDE_FROM_ABI basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
310   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT
311       : __data_(__s),
312         __size_(__len) {
313 #if _LIBCPP_STD_VER >= 14
314     // Allocations must fit in `ptrdiff_t` for pointer arithmetic to work. If `__len` exceeds it, the input
315     // range could not have been valid. Most likely the caller underflowed some arithmetic and inadvertently
316     // passed in a negative length.
317     _LIBCPP_ASSERT_VALID_INPUT_RANGE(
318         __len <= static_cast<size_type>(numeric_limits<difference_type>::max()),
319         "string_view::string_view(_CharT *, size_t): length does not fit in difference_type");
320     _LIBCPP_ASSERT_NON_NULL(
321         __len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr");
322 #endif
323   }
325 #if _LIBCPP_STD_VER >= 20
326   template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
327     requires(is_same_v<iter_value_t<_It>, _CharT> && !is_convertible_v<_End, size_type>)
328   constexpr _LIBCPP_HIDE_FROM_ABI basic_string_view(_It __begin, _End __end)
329       : __data_(std::to_address(__begin)), __size_(__end - __begin) {
330     _LIBCPP_ASSERT_VALID_INPUT_RANGE(
331         (__end - __begin) >= 0, "std::string_view::string_view(iterator, sentinel) received invalid range");
332   }
333 #endif // _LIBCPP_STD_VER >= 20
335 #if _LIBCPP_STD_VER >= 23
336   template <class _Range>
337     requires(!is_same_v<remove_cvref_t<_Range>, basic_string_view> && ranges::contiguous_range<_Range> &&
338              ranges::sized_range<_Range> && is_same_v<ranges::range_value_t<_Range>, _CharT> &&
339              !is_convertible_v<_Range, const _CharT*> &&
340              (!requires(remove_cvref_t<_Range>& __d) { __d.operator std::basic_string_view<_CharT, _Traits>(); }))
341   constexpr explicit _LIBCPP_HIDE_FROM_ABI basic_string_view(_Range&& __r)
342       : __data_(ranges::data(__r)), __size_(ranges::size(__r)) {}
343 #endif // _LIBCPP_STD_VER >= 23
345   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* __s)
346       : __data_(__s), __size_(std::__char_traits_length_checked<_Traits>(__s)) {}
348 #if _LIBCPP_STD_VER >= 23
349   basic_string_view(nullptr_t) = delete;
350 #endif
352   // [string.view.iterators], iterators
353   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return cbegin(); }
355   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return cend(); }
357   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {
358 #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
359     return std::__make_bounded_iter(data(), data(), data() + size());
360 #else
361     return const_iterator(__data_);
362 #endif
363   }
365   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {
366 #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS
367     return std::__make_bounded_iter(data() + size(), data(), data() + size());
368 #else
369     return const_iterator(__data_ + __size_);
370 #endif
371   }
373   _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT {
374     return const_reverse_iterator(cend());
375   }
377   _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {
378     return const_reverse_iterator(cbegin());
379   }
381   _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT {
382     return const_reverse_iterator(cend());
383   }
385   _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT {
386     return const_reverse_iterator(cbegin());
387   }
389   // [string.view.capacity], capacity
390   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; }
392   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type length() const _NOEXCEPT { return __size_; }
394   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {
395     return numeric_limits<size_type>::max() / sizeof(value_type);
396   }
398   _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return __size_ == 0; }
400   // [string.view.access], element access
401   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference operator[](size_type __pos) const _NOEXCEPT {
402     return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos < size(), "string_view[] index out of bounds"), __data_[__pos];
403   }
405   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __pos) const {
406     return __pos >= size() ? (__throw_out_of_range("string_view::at"), __data_[0]) : __data_[__pos];
407   }
409   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT {
410     return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::front(): string is empty"), __data_[0];
411   }
413   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {
414     return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::back(): string is empty"), __data_[__size_ - 1];
415   }
417   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_pointer data() const _NOEXCEPT { return __data_; }
419   // [string.view.modifiers], modifiers:
420   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI void remove_prefix(size_type __n) _NOEXCEPT {
421     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n <= size(), "remove_prefix() can't remove more than size()");
422     __data_ += __n;
423     __size_ -= __n;
424   }
426   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI void remove_suffix(size_type __n) _NOEXCEPT {
427     _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n <= size(), "remove_suffix() can't remove more than size()");
428     __size_ -= __n;
429   }
431   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI void swap(basic_string_view& __other) _NOEXCEPT {
432     const value_type* __p = __data_;
433     __data_               = __other.__data_;
434     __other.__data_       = __p;
436     size_type __sz  = __size_;
437     __size_         = __other.__size_;
438     __other.__size_ = __sz;
439   }
441   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
442   copy(_CharT* __s, size_type __n, size_type __pos = 0) const {
443     if (__pos > size())
444       __throw_out_of_range("string_view::copy");
445     size_type __rlen = std::min(__n, size() - __pos);
446     _Traits::copy(__s, data() + __pos, __rlen);
447     return __rlen;
448   }
450   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view substr(size_type __pos = 0, size_type __n = npos) const {
451     return __pos > size() ? (__throw_out_of_range("string_view::substr"), basic_string_view())
452                           : basic_string_view(data() + __pos, std::min(__n, size() - __pos));
453   }
455   _LIBCPP_CONSTEXPR_SINCE_CXX14 int compare(basic_string_view __sv) const _NOEXCEPT {
456     size_type __rlen = std::min(size(), __sv.size());
457     int __retval     = _Traits::compare(data(), __sv.data(), __rlen);
458     if (__retval == 0) // first __rlen chars matched
459       __retval = size() == __sv.size() ? 0 : (size() < __sv.size() ? -1 : 1);
460     return __retval;
461   }
463   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
464   compare(size_type __pos1, size_type __n1, basic_string_view __sv) const {
465     return substr(__pos1, __n1).compare(__sv);
466   }
468   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
469   compare(size_type __pos1, size_type __n1, basic_string_view __sv, size_type __pos2, size_type __n2) const {
470     return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
471   }
473   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int compare(const _CharT* __s) const _NOEXCEPT {
474     return compare(basic_string_view(__s));
475   }
477   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
478   compare(size_type __pos1, size_type __n1, const _CharT* __s) const {
479     return substr(__pos1, __n1).compare(basic_string_view(__s));
480   }
482   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int
483   compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const {
484     return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
485   }
487   // find
488   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
489   find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {
490     _LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
491     return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size());
492   }
494   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT {
495     return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
496   }
498   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
499   find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
500     _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
501     return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
502   }
504   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
505   find(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT {
506     _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find(): received nullptr");
507     return std::__str_find<value_type, size_type, traits_type, npos>(
508         data(), size(), __s, __pos, traits_type::length(__s));
509   }
511   // rfind
512   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
513   rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {
514     _LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
515     return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size());
516   }
518   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
519   rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT {
520     return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
521   }
523   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
524   rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
525     _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
526     return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
527   }
529   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
530   rfind(const _CharT* __s, size_type __pos = npos) const _NOEXCEPT {
531     _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::rfind(): received nullptr");
532     return std::__str_rfind<value_type, size_type, traits_type, npos>(
533         data(), size(), __s, __pos, traits_type::length(__s));
534   }
536   // find_first_of
537   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
538   find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {
539     _LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
540     return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
541         data(), size(), __s.data(), __pos, __s.size());
542   }
544   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
545   find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT {
546     return find(__c, __pos);
547   }
549   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
550   find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
551     _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
552     return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
553   }
555   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
556   find_first_of(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT {
557     _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_of(): received nullptr");
558     return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
559         data(), size(), __s, __pos, traits_type::length(__s));
560   }
562   // find_last_of
563   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
564   find_last_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {
565     _LIBCPP_ASSERT_NON_NULL(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
566     return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
567         data(), size(), __s.data(), __pos, __s.size());
568   }
570   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
571   find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT {
572     return rfind(__c, __pos);
573   }
575   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
576   find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
577     _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
578     return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
579   }
581   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
582   find_last_of(const _CharT* __s, size_type __pos = npos) const _NOEXCEPT {
583     _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_of(): received nullptr");
584     return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
585         data(), size(), __s, __pos, traits_type::length(__s));
586   }
588   // find_first_not_of
589   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
590   find_first_not_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {
591     _LIBCPP_ASSERT_NON_NULL(
592         __s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
593     return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
594         data(), size(), __s.data(), __pos, __s.size());
595   }
597   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
598   find_first_not_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT {
599     return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
600   }
602   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
603   find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
604     _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
605     return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
606   }
608   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
609   find_first_not_of(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT {
610     _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
611     return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
612         data(), size(), __s, __pos, traits_type::length(__s));
613   }
615   // find_last_not_of
616   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
617   find_last_not_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {
618     _LIBCPP_ASSERT_NON_NULL(
619         __s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
620     return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
621         data(), size(), __s.data(), __pos, __s.size());
622   }
624   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
625   find_last_not_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT {
626     return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);
627   }
629   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
630   find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT {
631     _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
632     return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);
633   }
635   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type
636   find_last_not_of(const _CharT* __s, size_type __pos = npos) const _NOEXCEPT {
637     _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
638     return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
639         data(), size(), __s, __pos, traits_type::length(__s));
640   }
642 #if _LIBCPP_STD_VER >= 20
643   constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(basic_string_view __s) const noexcept {
644     return size() >= __s.size() && compare(0, __s.size(), __s) == 0;
645   }
647   constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept {
648     return !empty() && _Traits::eq(front(), __c);
649   }
651   constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(const value_type* __s) const noexcept {
652     return starts_with(basic_string_view(__s));
653   }
655   constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(basic_string_view __s) const noexcept {
656     return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0;
657   }
659   constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept {
660     return !empty() && _Traits::eq(back(), __c);
661   }
663   constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(const value_type* __s) const noexcept {
664     return ends_with(basic_string_view(__s));
665   }
666 #endif
668 #if _LIBCPP_STD_VER >= 23
669   constexpr _LIBCPP_HIDE_FROM_ABI bool contains(basic_string_view __sv) const noexcept { return find(__sv) != npos; }
671   constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept { return find(__c) != npos; }
673   constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* __s) const { return find(__s) != npos; }
674 #endif
676 private:
677   const value_type* __data_;
678   size_type __size_;
680 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_string_view);
682 #if _LIBCPP_STD_VER >= 20
683 template <class _CharT, class _Traits>
684 inline constexpr bool ranges::enable_view<basic_string_view<_CharT, _Traits>> = true;
686 template <class _CharT, class _Traits>
687 inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true;
688 #endif // _LIBCPP_STD_VER >= 20
690 // [string.view.deduct]
692 #if _LIBCPP_STD_VER >= 20
693 template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
694 basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>;
695 #endif // _LIBCPP_STD_VER >= 20
697 #if _LIBCPP_STD_VER >= 23
698 template <ranges::contiguous_range _Range>
699 basic_string_view(_Range) -> basic_string_view<ranges::range_value_t<_Range>>;
700 #endif
702 // [string.view.comparison]
704 #if _LIBCPP_STD_VER >= 20
706 template <class _CharT, class _Traits>
707 _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(basic_string_view<_CharT, _Traits> __lhs,
708                                                 type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) noexcept {
709   if (__lhs.size() != __rhs.size())
710     return false;
711   return __lhs.compare(__rhs) == 0;
714 template <class _CharT, class _Traits>
715 _LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(basic_string_view<_CharT, _Traits> __lhs,
716                                                  type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) noexcept {
717   if constexpr (requires { typename _Traits::comparison_category; }) {
718     // [string.view]/4
719     static_assert(
720         __comparison_category<typename _Traits::comparison_category>, "return type is not a comparison category type");
721     return static_cast<typename _Traits::comparison_category>(__lhs.compare(__rhs) <=> 0);
722   } else {
723     return static_cast<weak_ordering>(__lhs.compare(__rhs) <=> 0);
724   }
727 #else
729 // operator ==
731 template <class _CharT, class _Traits>
732 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
733 operator==(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
734   if (__lhs.size() != __rhs.size())
735     return false;
736   return __lhs.compare(__rhs) == 0;
739 // The dummy default template parameters are used to work around a MSVC issue with mangling, see VSO-409326 for details.
740 // This applies to the other sufficient overloads below for the other comparison operators.
741 template <class _CharT, class _Traits, int = 1>
742 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
743 operator==(basic_string_view<_CharT, _Traits> __lhs,
744            __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {
745   if (__lhs.size() != __rhs.size())
746     return false;
747   return __lhs.compare(__rhs) == 0;
750 template <class _CharT, class _Traits, int = 2>
751 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
752 operator==(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
753            basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
754   if (__lhs.size() != __rhs.size())
755     return false;
756   return __lhs.compare(__rhs) == 0;
759 // operator !=
760 template <class _CharT, class _Traits>
761 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
762 operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
763   if (__lhs.size() != __rhs.size())
764     return true;
765   return __lhs.compare(__rhs) != 0;
768 template <class _CharT, class _Traits, int = 1>
769 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
770 operator!=(basic_string_view<_CharT, _Traits> __lhs,
771            __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {
772   if (__lhs.size() != __rhs.size())
773     return true;
774   return __lhs.compare(__rhs) != 0;
777 template <class _CharT, class _Traits, int = 2>
778 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
779 operator!=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
780            basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
781   if (__lhs.size() != __rhs.size())
782     return true;
783   return __lhs.compare(__rhs) != 0;
786 // operator <
787 template <class _CharT, class _Traits>
788 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
789 operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
790   return __lhs.compare(__rhs) < 0;
793 template <class _CharT, class _Traits, int = 1>
794 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
795 operator<(basic_string_view<_CharT, _Traits> __lhs,
796           __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {
797   return __lhs.compare(__rhs) < 0;
800 template <class _CharT, class _Traits, int = 2>
801 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
802 operator<(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
803           basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
804   return __lhs.compare(__rhs) < 0;
807 // operator >
808 template <class _CharT, class _Traits>
809 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
810 operator>(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
811   return __lhs.compare(__rhs) > 0;
814 template <class _CharT, class _Traits, int = 1>
815 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
816 operator>(basic_string_view<_CharT, _Traits> __lhs,
817           __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {
818   return __lhs.compare(__rhs) > 0;
821 template <class _CharT, class _Traits, int = 2>
822 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
823 operator>(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
824           basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
825   return __lhs.compare(__rhs) > 0;
828 // operator <=
829 template <class _CharT, class _Traits>
830 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
831 operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
832   return __lhs.compare(__rhs) <= 0;
835 template <class _CharT, class _Traits, int = 1>
836 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
837 operator<=(basic_string_view<_CharT, _Traits> __lhs,
838            __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {
839   return __lhs.compare(__rhs) <= 0;
842 template <class _CharT, class _Traits, int = 2>
843 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
844 operator<=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
845            basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
846   return __lhs.compare(__rhs) <= 0;
849 // operator >=
850 template <class _CharT, class _Traits>
851 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
852 operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
853   return __lhs.compare(__rhs) >= 0;
856 template <class _CharT, class _Traits, int = 1>
857 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
858 operator>=(basic_string_view<_CharT, _Traits> __lhs,
859            __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {
860   return __lhs.compare(__rhs) >= 0;
863 template <class _CharT, class _Traits, int = 2>
864 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool
865 operator>=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,
866            basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {
867   return __lhs.compare(__rhs) >= 0;
870 #endif //  _LIBCPP_STD_VER >= 20
872 template <class _CharT, class _Traits>
873 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
874 operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __str);
876 // [string.view.hash]
877 template <class _CharT>
878 struct __string_view_hash : public __unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t> {
879   _LIBCPP_HIDE_FROM_ABI size_t operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT {
880     return std::__do_string_hash(__val.data(), __val.data() + __val.size());
881   }
884 template <>
885 struct hash<basic_string_view<char, char_traits<char> > > : __string_view_hash<char> {};
887 #ifndef _LIBCPP_HAS_NO_CHAR8_T
888 template <>
889 struct hash<basic_string_view<char8_t, char_traits<char8_t> > > : __string_view_hash<char8_t> {};
890 #endif
892 template <>
893 struct hash<basic_string_view<char16_t, char_traits<char16_t> > > : __string_view_hash<char16_t> {};
895 template <>
896 struct hash<basic_string_view<char32_t, char_traits<char32_t> > > : __string_view_hash<char32_t> {};
898 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
899 template <>
900 struct hash<basic_string_view<wchar_t, char_traits<wchar_t> > > : __string_view_hash<wchar_t> {};
901 #endif
903 #if _LIBCPP_STD_VER >= 14
904 inline namespace literals {
905 inline namespace string_view_literals {
906 inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char> operator""sv(const char* __str, size_t __len) noexcept {
907   return basic_string_view<char>(__str, __len);
910 #  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
911 inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<wchar_t>
912 operator""sv(const wchar_t* __str, size_t __len) noexcept {
913   return basic_string_view<wchar_t>(__str, __len);
915 #  endif
917 #  ifndef _LIBCPP_HAS_NO_CHAR8_T
918 inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char8_t>
919 operator""sv(const char8_t* __str, size_t __len) noexcept {
920   return basic_string_view<char8_t>(__str, __len);
922 #  endif
924 inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char16_t>
925 operator""sv(const char16_t* __str, size_t __len) noexcept {
926   return basic_string_view<char16_t>(__str, __len);
929 inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char32_t>
930 operator""sv(const char32_t* __str, size_t __len) noexcept {
931   return basic_string_view<char32_t>(__str, __len);
933 } // namespace string_view_literals
934 } // namespace literals
935 #endif
936 _LIBCPP_END_NAMESPACE_STD
938 _LIBCPP_POP_MACROS
940 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
941 #  include <__cxx03/algorithm>
942 #  include <__cxx03/concepts>
943 #  include <__cxx03/cstdlib>
944 #  include <__cxx03/iterator>
945 #  include <__cxx03/type_traits>
946 #endif
948 #endif // _LIBCPP_STRING_VIEW