brintos

brintos / llvm-project-archived public Read only

0
0
Text · 44.1 KiB · 5dd04a9 Raw
985 lines · plain
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-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP_STRING_VIEW11#define _LIBCPP_STRING_VIEW12 13// clang-format off14 15/*16 17    string_view synopsis18 19#include <compare>20 21namespace std {22 23    // 7.2, Class template basic_string_view24    template<class charT, class traits = char_traits<charT>>25        class basic_string_view;26 27    template<class charT, class traits>28    inline constexpr bool ranges::enable_view<basic_string_view<charT, traits>> = true;29 30    template<class charT, class traits>31    inline constexpr bool ranges::enable_borrowed_range<basic_string_view<charT, traits>> = true;  // C++2032 33    // 7.9, basic_string_view non-member comparison functions34    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++2038    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++2041    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++2044    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++2047    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++2050    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++2053    constexpr see below operator<=>(basic_string_view<charT, traits> x,54                                    basic_string_view<charT, traits> y) noexcept;55 56    // see below, sufficient additional overloads of comparison functions57 58    // 7.10, Inserters and extractors59    template<class charT, class traits>60      basic_ostream<charT, traits>&61        operator<<(basic_ostream<charT, traits>& os,62                   basic_string_view<charT, traits> str);63 64    // basic_string_view typedef names65    typedef basic_string_view<char> string_view;66    typedef basic_string_view<char8_t> u8string_view; // C++2067    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;70 71    template<class charT, class traits = char_traits<charT>>72    class basic_string_view {73      public:74      // types75      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);88 89      // 7.3, basic_string_view constructors and assignment operators90      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++2396      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++2099      template <class Range>100      constexpr basic_string_view(Range&& r); // C++23101 102      // 7.4, basic_string_view iterator support103      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;111 112      // 7.5, basic_string_view capacity113      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;117 118      // 7.6, basic_string_view element access119      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;124 125      // 7.7, basic_string_view modifiers126      constexpr void remove_prefix(size_type n);127      constexpr void remove_suffix(size_type n);128      constexpr void swap(basic_string_view& s) noexcept;129 130      size_type copy(charT* s, size_type n, size_type pos = 0) const;  // constexpr in C++20131 132      constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;133      constexpr basic_string_view subview(size_type pos = 0,134                                          size_type n = npos) const;      // freestanding-deleted, since C++26135      constexpr int compare(basic_string_view s) const noexcept;136      constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;137      constexpr int compare(size_type pos1, size_type n1,138                            basic_string_view s, size_type pos2, size_type n2) const;139      constexpr int compare(const charT* s) const;140      constexpr int compare(size_type pos1, size_type n1, const charT* s) const;141      constexpr int compare(size_type pos1, size_type n1,142                            const charT* s, size_type n2) const;143      constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;144      constexpr size_type find(charT c, size_type pos = 0) const noexcept;145      constexpr size_type find(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension146      constexpr size_type find(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension147      constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;148      constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;149      constexpr size_type rfind(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension150      constexpr size_type rfind(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension151      constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;152      constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;153      constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension154      constexpr size_type find_first_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension155      constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;156      constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;157      constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension158      constexpr size_type find_last_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension159      constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;160      constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;161      constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension162      constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension163      constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept;164      constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;165      constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension166      constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension167 168      constexpr bool starts_with(basic_string_view s) const noexcept; // C++20169      constexpr bool starts_with(charT c) const noexcept;             // C++20170      constexpr bool starts_with(const charT* s) const;               // C++20171      constexpr bool ends_with(basic_string_view s) const noexcept;   // C++20172      constexpr bool ends_with(charT c) const noexcept;               // C++20173      constexpr bool ends_with(const charT* s) const;                 // C++20174 175      constexpr bool contains(basic_string_view s) const noexcept; // C++23176      constexpr bool contains(charT c) const noexcept;             // C++23177      constexpr bool contains(const charT* s) const;               // C++23178 179     private:180      const_pointer data_;  // exposition only181      size_type     size_;  // exposition only182    };183 184  // basic_string_view deduction guides185  template<class It, class End>186    basic_string_view(It, End) -> basic_string_view<iter_value_t<It>>; // C++20187  template<class Range>188    basic_string_view(Range&&) -> basic_string_view<ranges::range_value_t<Range>>; // C++23189 190  // 7.11, Hash support191  template <class T> struct hash;192  template <> struct hash<string_view>;193  template <> struct hash<u8string_view>; // C++20194  template <> struct hash<u16string_view>;195  template <> struct hash<u32string_view>;196  template <> struct hash<wstring_view>;197 198  constexpr basic_string_view<char>     operator""sv(const char *str,     size_t len) noexcept;199  constexpr basic_string_view<wchar_t>  operator""sv(const wchar_t *str,  size_t len) noexcept;200  constexpr basic_string_view<char8_t>  operator""sv(const char8_t *str,  size_t len) noexcept; // C++20201  constexpr basic_string_view<char16_t> operator""sv(const char16_t *str, size_t len) noexcept;202  constexpr basic_string_view<char32_t> operator""sv(const char32_t *str, size_t len) noexcept;203 204}  // namespace std205 206*/207 208// clang-format on209 210#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)211#  include <__cxx03/string_view>212#else213#  include <__algorithm/min.h>214#  include <__assert>215#  include <__config>216#  include <__cstddef/nullptr_t.h>217#  include <__cstddef/ptrdiff_t.h>218#  include <__cstddef/size_t.h>219#  include <__functional/hash.h>220#  include <__functional/unary_function.h>221#  include <__fwd/ostream.h>222#  include <__fwd/string.h>223#  include <__fwd/string_view.h>224#  include <__iterator/bounded_iter.h>225#  include <__iterator/concepts.h>226#  include <__iterator/iterator_traits.h>227#  include <__iterator/reverse_iterator.h>228#  include <__iterator/wrap_iter.h>229#  include <__memory/pointer_traits.h>230#  include <__ranges/concepts.h>231#  include <__ranges/data.h>232#  include <__ranges/enable_borrowed_range.h>233#  include <__ranges/enable_view.h>234#  include <__ranges/size.h>235#  include <__string/char_traits.h>236#  include <__type_traits/is_array.h>237#  include <__type_traits/is_convertible.h>238#  include <__type_traits/is_same.h>239#  include <__type_traits/is_standard_layout.h>240#  include <__type_traits/is_trivially_constructible.h>241#  include <__type_traits/is_trivially_copyable.h>242#  include <__type_traits/remove_cvref.h>243#  include <__type_traits/remove_reference.h>244#  include <__type_traits/type_identity.h>245#  include <iosfwd>246#  include <limits>247#  include <stdexcept>248#  include <version>249 250// standard-mandated includes251 252// [iterator.range]253#  include <__iterator/access.h>254#  include <__iterator/data.h>255#  include <__iterator/empty.h>256#  include <__iterator/reverse_access.h>257#  include <__iterator/size.h>258 259// [string.view.synop]260#  include <compare>261 262#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)263#    pragma GCC system_header264#  endif265 266_LIBCPP_PUSH_MACROS267#  include <__undef_macros>268 269_LIBCPP_BEGIN_NAMESPACE_STD270 271// TODO: This is a workaround for some vendors to carry a downstream diff to accept `nullptr` in272//       string_view constructors. This can be refactored when this exact form isn't needed anymore.273template <class _Traits>274_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR inline size_t275__char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT {276  // This needs to be a single statement for C++11 constexpr277  return _LIBCPP_ASSERT_NON_NULL(278             __s != nullptr, "null pointer passed to non-null argument of char_traits<...>::length"),279         _Traits::length(__s);280}281 282template <class _CharT, class _Traits>283class basic_string_view {284public:285  // types286  using traits_type     = _Traits;287  using value_type      = _CharT;288  using pointer         = _CharT*;289  using const_pointer   = const _CharT*;290  using reference       = _CharT&;291  using const_reference = const _CharT&;292#  if defined(_LIBCPP_ABI_BOUNDED_ITERATORS)293  using const_iterator = __bounded_iter<const_pointer>;294#  elif defined(_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW)295  using const_iterator = __wrap_iter<const_pointer>;296#  else297  using const_iterator = const_pointer;298#  endif299  using iterator                                = const_iterator;300  using const_reverse_iterator                  = std::reverse_iterator<const_iterator>;301  using reverse_iterator                        = const_reverse_iterator;302  using size_type                               = size_t;303  using difference_type                         = ptrdiff_t;304  static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1);305 306  static_assert(!is_array<value_type>::value, "Character type of basic_string_view must not be an array");307  static_assert(is_standard_layout<value_type>::value, "Character type of basic_string_view must be standard-layout");308  static_assert(is_trivially_default_constructible<value_type>::value,309                "Character type of basic_string_view must be trivially default constructible");310  static_assert(is_trivially_copyable<value_type>::value,311                "Character type of basic_string_view must be trivially copyable");312  static_assert(is_same<_CharT, typename traits_type::char_type>::value,313                "traits_type::char_type must be the same type as CharT");314 315  // [string.view.cons], construct/copy316  _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view() _NOEXCEPT : __data_(nullptr), __size_(0) {}317 318  _LIBCPP_HIDE_FROM_ABI basic_string_view(const basic_string_view&) _NOEXCEPT = default;319 320  _LIBCPP_HIDE_FROM_ABI basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;321 322  _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT323      _LIBCPP_DIAGNOSE_NULLPTR_IF(__len != 0 && __s == nullptr, " if len is not zero")324      : __data_(__s), __size_(__len) {325#  if !defined(_LIBCPP_CXX03_LANG) && (!defined(_LIBCPP_COMPILER_GCC) || _LIBCPP_STD_VER >= 14)326    // Allocations must fit in `ptrdiff_t` for pointer arithmetic to work. If `__len` exceeds it, the input327    // range could not have been valid. Most likely the caller underflowed some arithmetic and inadvertently328    // passed in a negative length.329    _LIBCPP_ASSERT_VALID_INPUT_RANGE(330        __len <= static_cast<size_type>(numeric_limits<difference_type>::max()),331        "string_view::string_view(_CharT *, size_t): length does not fit in difference_type");332    _LIBCPP_ASSERT_NON_NULL(333        __len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr");334#  endif335  }336 337#  if _LIBCPP_STD_VER >= 20338  template <contiguous_iterator _It, sized_sentinel_for<_It> _End>339    requires(is_same_v<iter_value_t<_It>, _CharT> && !is_convertible_v<_End, size_type>)340  constexpr _LIBCPP_HIDE_FROM_ABI basic_string_view(_It __begin, _End __end)341      : __data_(std::to_address(__begin)), __size_(__end - __begin) {342    _LIBCPP_ASSERT_VALID_INPUT_RANGE(343        (__end - __begin) >= 0, "std::string_view::string_view(iterator, sentinel) received invalid range");344  }345#  endif // _LIBCPP_STD_VER >= 20346 347#  if _LIBCPP_STD_VER >= 23348  template <class _Range>349    requires(!is_same_v<remove_cvref_t<_Range>, basic_string_view> && ranges::contiguous_range<_Range> &&350             ranges::sized_range<_Range> && is_same_v<ranges::range_value_t<_Range>, _CharT> &&351             !is_convertible_v<_Range, const _CharT*> &&352             (!requires(remove_cvref_t<_Range>& __d) { __d.operator std::basic_string_view<_CharT, _Traits>(); }))353  constexpr explicit _LIBCPP_HIDE_FROM_ABI basic_string_view(_Range&& __r)354      : __data_(ranges::data(__r)), __size_(ranges::size(__r)) {}355#  endif // _LIBCPP_STD_VER >= 23356 357  _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s)358      : __data_(__s), __size_(std::__char_traits_length_checked<_Traits>(__s)) {}359 360#  if _LIBCPP_STD_VER >= 23361  basic_string_view(nullptr_t) = delete;362#  endif363 364  // [string.view.iterators], iterators365  [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return cbegin(); }366 367  [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return cend(); }368 369  [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT {370#  ifdef _LIBCPP_ABI_BOUNDED_ITERATORS371    return std::__make_bounded_iter(data(), data(), data() + size());372#  else373    return const_iterator(__data_);374#  endif375  }376 377  [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT {378#  ifdef _LIBCPP_ABI_BOUNDED_ITERATORS379    return std::__make_bounded_iter(data() + size(), data(), data() + size());380#  else381    return const_iterator(__data_ + __size_);382#  endif383  }384 385  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator386  rbegin() const _NOEXCEPT {387    return const_reverse_iterator(cend());388  }389 390  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT {391    return const_reverse_iterator(cbegin());392  }393 394  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator395  crbegin() const _NOEXCEPT {396    return const_reverse_iterator(cend());397  }398 399  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT {400    return const_reverse_iterator(cbegin());401  }402 403  // [string.view.capacity], capacity404  [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __size_; }405 406  [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type length() const _NOEXCEPT { return __size_; }407 408  [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT {409    return numeric_limits<size_type>::max() / sizeof(value_type);410  }411 412  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return __size_ == 0; }413 414  // [string.view.access], element access415  [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference416  operator[](size_type __pos) const _NOEXCEPT {417    return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos < size(), "string_view[] index out of bounds"), __data_[__pos];418  }419 420  [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __pos) const {421    return __pos >= size() ? (__throw_out_of_range("string_view::at"), __data_[0]) : __data_[__pos];422  }423 424  [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT {425    return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::front(): string is empty"), __data_[0];426  }427 428  [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT {429    return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::back(): string is empty"), __data_[__size_ - 1];430  }431 432  [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI const_pointer data() const _NOEXCEPT { return __data_; }433 434  // [string.view.modifiers], modifiers:435  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI void remove_prefix(size_type __n) _NOEXCEPT {436    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n <= size(), "remove_prefix() can't remove more than size()");437    __data_ += __n;438    __size_ -= __n;439  }440 441  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI void remove_suffix(size_type __n) _NOEXCEPT {442    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n <= size(), "remove_suffix() can't remove more than size()");443    __size_ -= __n;444  }445 446  _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI void swap(basic_string_view& __other) _NOEXCEPT {447    const value_type* __p = __data_;448    __data_               = __other.__data_;449    __other.__data_       = __p;450 451    size_type __sz  = __size_;452    __size_         = __other.__size_;453    __other.__size_ = __sz;454  }455 456  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type457  copy(_CharT* __s, size_type __n, size_type __pos = 0) const {458    if (__pos > size())459      std::__throw_out_of_range("string_view::copy");460    size_type __rlen = std::min(__n, size() - __pos);461    _Traits::copy(__s, data() + __pos, __rlen);462    return __rlen;463  }464 465  [[__nodiscard__]] _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI basic_string_view466  substr(size_type __pos = 0, size_type __n = npos) const {467    // Use the `__assume_valid` form of the constructor to avoid an unnecessary check. Any substring of a view is a468    // valid view. In particular, `size()` is known to be smaller than `numeric_limits<difference_type>::max()`, so the469    // new size is also smaller. See also https://llvm.org/PR91634.470    return __pos > size() ? (__throw_out_of_range("string_view::substr"), basic_string_view())471                          : basic_string_view(__assume_valid(), data() + __pos, std::min(__n, size() - __pos));472  }473 474#  if _LIBCPP_STD_VER >= 26475  [[nodiscard]]476  _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view subview(size_type __pos = 0, size_type __n = npos) const {477    return substr(__pos, __n);478  }479#  endif480 481  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 int compare(basic_string_view __sv) const _NOEXCEPT {482    size_type __rlen = std::min(size(), __sv.size());483    int __retval     = _Traits::compare(data(), __sv.data(), __rlen);484    if (__retval == 0) // first __rlen chars matched485      __retval = size() == __sv.size() ? 0 : (size() < __sv.size() ? -1 : 1);486    return __retval;487  }488 489  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int490  compare(size_type __pos1, size_type __n1, basic_string_view __sv) const {491    return substr(__pos1, __n1).compare(__sv);492  }493 494  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int495  compare(size_type __pos1, size_type __n1, basic_string_view __sv, size_type __pos2, size_type __n2) const {496    return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));497  }498 499  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int500  compare(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) const _NOEXCEPT {501    return compare(basic_string_view(__s));502  }503 504  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int505  compare(size_type __pos1, size_type __n1, const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s) const {506    return substr(__pos1, __n1).compare(basic_string_view(__s));507  }508 509  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI int510  compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const511      _LIBCPP_DIAGNOSE_NULLPTR_IF(__n2 != 0 && __s == nullptr, " if n2 is not zero") {512    return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));513  }514 515  // find516  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type517  find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {518    return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size());519  }520 521  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type522  find(_CharT __c, size_type __pos = 0) const _NOEXCEPT {523    return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);524  }525 526  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type527  find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT528      _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {529    _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");530    return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);531  }532 533  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type534  find(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {535    _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find(): received nullptr");536    return std::__str_find<value_type, size_type, traits_type, npos>(537        data(), size(), __s, __pos, traits_type::length(__s));538  }539 540  // rfind541  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type542  rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {543    return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s.data(), __pos, __s.size());544  }545 546  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type547  rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT {548    return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);549  }550 551  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type552  rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT553      _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {554    _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");555    return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);556  }557 558  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type559  rfind(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {560    _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::rfind(): received nullptr");561    return std::__str_rfind<value_type, size_type, traits_type, npos>(562        data(), size(), __s, __pos, traits_type::length(__s));563  }564 565  // find_first_of566  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type567  find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {568    return std::__str_find_first_of<value_type, size_type, traits_type, npos>(569        data(), size(), __s.data(), __pos, __s.size());570  }571 572  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type573  find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT {574    return find(__c, __pos);575  }576 577  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type578  find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT579      _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {580    _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");581    return std::__str_find_first_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);582  }583 584  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type585  find_first_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {586    _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_of(): received nullptr");587    return std::__str_find_first_of<value_type, size_type, traits_type, npos>(588        data(), size(), __s, __pos, traits_type::length(__s));589  }590 591  // find_last_of592  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type593  find_last_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {594    return std::__str_find_last_of<value_type, size_type, traits_type, npos>(595        data(), size(), __s.data(), __pos, __s.size());596  }597 598  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type599  find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT {600    return rfind(__c, __pos);601  }602 603  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type604  find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT605      _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {606    _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");607    return std::__str_find_last_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);608  }609 610  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type611  find_last_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {612    _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_of(): received nullptr");613    return std::__str_find_last_of<value_type, size_type, traits_type, npos>(614        data(), size(), __s, __pos, traits_type::length(__s));615  }616 617  // find_first_not_of618  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type619  find_first_not_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT {620    return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(621        data(), size(), __s.data(), __pos, __s.size());622  }623 624  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type625  find_first_not_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT {626    return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);627  }628 629  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type630  find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT631      _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {632    _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");633    return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);634  }635 636  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type637  find_first_not_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = 0) const _NOEXCEPT {638    _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_first_not_of(): received nullptr");639    return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(640        data(), size(), __s, __pos, traits_type::length(__s));641  }642 643  // find_last_not_of644  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type645  find_last_not_of(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT {646    return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(647        data(), size(), __s.data(), __pos, __s.size());648  }649 650  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type651  find_last_not_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT {652    return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __c, __pos);653  }654 655  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type656  find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT657      _LIBCPP_DIAGNOSE_NULLPTR_IF(__n != 0 && __s == nullptr, " if n is not zero") {658    _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");659    return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(data(), size(), __s, __pos, __n);660  }661 662  [[__nodiscard__]] _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI size_type663  find_last_not_of(const _CharT* _LIBCPP_DIAGNOSE_NULLPTR __s, size_type __pos = npos) const _NOEXCEPT {664    _LIBCPP_ASSERT_NON_NULL(__s != nullptr, "string_view::find_last_not_of(): received nullptr");665    return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(666        data(), size(), __s, __pos, traits_type::length(__s));667  }668 669#  if _LIBCPP_STD_VER >= 20670  [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(basic_string_view __s) const noexcept {671    return size() >= __s.size() && compare(0, __s.size(), __s) == 0;672  }673 674  [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool starts_with(value_type __c) const noexcept {675    return !empty() && _Traits::eq(front(), __c);676  }677 678  [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool679  starts_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {680    return starts_with(basic_string_view(__s));681  }682 683  [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(basic_string_view __s) const noexcept {684    return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0;685  }686 687  [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool ends_with(value_type __c) const noexcept {688    return !empty() && _Traits::eq(back(), __c);689  }690 691  [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool692  ends_with(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const noexcept {693    return ends_with(basic_string_view(__s));694  }695#  endif696 697#  if _LIBCPP_STD_VER >= 23698  [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(basic_string_view __sv) const noexcept {699    return find(__sv) != npos;700  }701 702  [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(value_type __c) const noexcept {703    return find(__c) != npos;704  }705 706  [[nodiscard]] constexpr _LIBCPP_HIDE_FROM_ABI bool contains(const value_type* _LIBCPP_DIAGNOSE_NULLPTR __s) const {707    return find(__s) != npos;708  }709#  endif710 711private:712  struct __assume_valid {};713 714  // This is the same as the pointer and length constructor, but without the additional hardening checks. It is intended715  // for use within the class, when the class invariants already guarantee the resulting object is valid. The compiler716  // usually cannot eliminate the redundant checks because it does not know class invariants.717  _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI718  basic_string_view(__assume_valid, const _CharT* __s, size_type __len) _NOEXCEPT719      : __data_(__s),720        __size_(__len) {}721 722  const value_type* __data_;723  size_type __size_;724 725  template <class, class, class>726  friend class basic_string;727};728_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_string_view);729 730#  if _LIBCPP_STD_VER >= 20731template <class _CharT, class _Traits>732inline constexpr bool ranges::enable_view<basic_string_view<_CharT, _Traits>> = true;733 734template <class _CharT, class _Traits>735inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true;736#  endif // _LIBCPP_STD_VER >= 20737 738// [string.view.deduct]739 740#  if _LIBCPP_STD_VER >= 20741template <contiguous_iterator _It, sized_sentinel_for<_It> _End>742basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>;743#  endif // _LIBCPP_STD_VER >= 20744 745#  if _LIBCPP_STD_VER >= 23746template <ranges::contiguous_range _Range>747basic_string_view(_Range) -> basic_string_view<ranges::range_value_t<_Range>>;748#  endif749 750// [string.view.comparison]751 752// The dummy default template parameters are used to work around a MSVC issue with mangling, see VSO-409326 for details.753// This applies to the other sufficient overloads below for the other comparison operators.754template <class _CharT, class _Traits, int = 1>755_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool756operator==(basic_string_view<_CharT, _Traits> __lhs,757           __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {758  if (__lhs.size() != __rhs.size())759    return false;760  return __lhs.compare(__rhs) == 0;761}762 763#  if _LIBCPP_STD_VER >= 20764 765template <class _CharT, class _Traits>766_LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(basic_string_view<_CharT, _Traits> __lhs,767                                                 type_identity_t<basic_string_view<_CharT, _Traits>> __rhs) noexcept {768  if constexpr (requires { typename _Traits::comparison_category; }) {769    // [string.view]/4770    static_assert(771        __comparison_category<typename _Traits::comparison_category>, "return type is not a comparison category type");772    return static_cast<typename _Traits::comparison_category>(__lhs.compare(__rhs) <=> 0);773  } else {774    return static_cast<weak_ordering>(__lhs.compare(__rhs) <=> 0);775  }776}777 778#  else779 780// operator ==781 782template <class _CharT, class _Traits>783_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool784operator==(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {785  if (__lhs.size() != __rhs.size())786    return false;787  return __lhs.compare(__rhs) == 0;788}789 790template <class _CharT, class _Traits, int = 2>791_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool792operator==(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,793           basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {794  return __lhs == __rhs;795}796 797// operator !=798template <class _CharT, class _Traits>799_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool800operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {801  return !(__lhs == __rhs);802}803 804template <class _CharT, class _Traits, int = 1>805_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool806operator!=(basic_string_view<_CharT, _Traits> __lhs,807           __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {808  return !(__lhs == __rhs);809}810 811template <class _CharT, class _Traits, int = 2>812_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool813operator!=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,814           basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {815  return !(__lhs == __rhs);816}817 818// operator <819template <class _CharT, class _Traits>820_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool821operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {822  return __lhs.compare(__rhs) < 0;823}824 825template <class _CharT, class _Traits, int = 1>826_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool827operator<(basic_string_view<_CharT, _Traits> __lhs,828          __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {829  return __lhs.compare(__rhs) < 0;830}831 832template <class _CharT, class _Traits, int = 2>833_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool834operator<(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,835          basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {836  return __lhs.compare(__rhs) < 0;837}838 839// operator >840template <class _CharT, class _Traits>841_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool842operator>(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {843  return __lhs.compare(__rhs) > 0;844}845 846template <class _CharT, class _Traits, int = 1>847_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool848operator>(basic_string_view<_CharT, _Traits> __lhs,849          __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {850  return __lhs.compare(__rhs) > 0;851}852 853template <class _CharT, class _Traits, int = 2>854_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool855operator>(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,856          basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {857  return __lhs.compare(__rhs) > 0;858}859 860// operator <=861template <class _CharT, class _Traits>862_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool863operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {864  return __lhs.compare(__rhs) <= 0;865}866 867template <class _CharT, class _Traits, int = 1>868_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool869operator<=(basic_string_view<_CharT, _Traits> __lhs,870           __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {871  return __lhs.compare(__rhs) <= 0;872}873 874template <class _CharT, class _Traits, int = 2>875_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool876operator<=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,877           basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {878  return __lhs.compare(__rhs) <= 0;879}880 881// operator >=882template <class _CharT, class _Traits>883_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool884operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {885  return __lhs.compare(__rhs) >= 0;886}887 888template <class _CharT, class _Traits, int = 1>889_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool890operator>=(basic_string_view<_CharT, _Traits> __lhs,891           __type_identity_t<basic_string_view<_CharT, _Traits> > __rhs) _NOEXCEPT {892  return __lhs.compare(__rhs) >= 0;893}894 895template <class _CharT, class _Traits, int = 2>896_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool897operator>=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs,898           basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT {899  return __lhs.compare(__rhs) >= 0;900}901 902#  endif //  _LIBCPP_STD_VER >= 20903 904template <class _CharT, class _Traits>905_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&906operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __str);907 908// [string.view.hash]909template <class _CharT>910struct __string_view_hash : public __unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t> {911  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t912  operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT {913    return std::__do_string_hash(__val.data(), __val.data() + __val.size());914  }915};916 917template <>918struct hash<basic_string_view<char, char_traits<char> > > : __string_view_hash<char> {};919 920#  if _LIBCPP_HAS_CHAR8_T921template <>922struct hash<basic_string_view<char8_t, char_traits<char8_t> > > : __string_view_hash<char8_t> {};923#  endif924 925template <>926struct hash<basic_string_view<char16_t, char_traits<char16_t> > > : __string_view_hash<char16_t> {};927 928template <>929struct hash<basic_string_view<char32_t, char_traits<char32_t> > > : __string_view_hash<char32_t> {};930 931#  if _LIBCPP_HAS_WIDE_CHARACTERS932template <>933struct hash<basic_string_view<wchar_t, char_traits<wchar_t> > > : __string_view_hash<wchar_t> {};934#  endif935 936#  if _LIBCPP_STD_VER >= 14937inline namespace literals {938inline namespace string_view_literals {939[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char>940operator""sv(const char* __str, size_t __len) noexcept {941  return basic_string_view<char>(__str, __len);942}943 944#    if _LIBCPP_HAS_WIDE_CHARACTERS945[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<wchar_t>946operator""sv(const wchar_t* __str, size_t __len) noexcept {947  return basic_string_view<wchar_t>(__str, __len);948}949#    endif950 951#    if _LIBCPP_HAS_CHAR8_T952[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char8_t>953operator""sv(const char8_t* __str, size_t __len) noexcept {954  return basic_string_view<char8_t>(__str, __len);955}956#    endif957 958[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char16_t>959operator""sv(const char16_t* __str, size_t __len) noexcept {960  return basic_string_view<char16_t>(__str, __len);961}962 963[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<char32_t>964operator""sv(const char32_t* __str, size_t __len) noexcept {965  return basic_string_view<char32_t>(__str, __len);966}967} // namespace string_view_literals968} // namespace literals969#  endif970_LIBCPP_END_NAMESPACE_STD971 972_LIBCPP_POP_MACROS973 974#  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20975#    include <algorithm>976#    include <concepts>977#    include <cstdlib>978#    include <iterator>979#    include <optional>980#    include <type_traits>981#  endif982#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)983 984#endif // _LIBCPP_STRING_VIEW985