string_view 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974
  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. //===----------------------------------------------------------------------===//
  9. #ifndef _LIBCPP_STRING_VIEW
  10. #define _LIBCPP_STRING_VIEW
  11. /*
  12. string_view synopsis
  13. namespace std {
  14. // 7.2, Class template basic_string_view
  15. template<class charT, class traits = char_traits<charT>>
  16. class basic_string_view;
  17. template<class charT, class traits>
  18. inline constexpr bool ranges::enable_view<basic_string_view<charT, traits>> = true;
  19. template<class charT, class traits>
  20. inline constexpr bool ranges::enable_borrowed_range<basic_string_view<charT, traits>> = true; // C++20
  21. // 7.9, basic_string_view non-member comparison functions
  22. template<class charT, class traits>
  23. constexpr bool operator==(basic_string_view<charT, traits> x,
  24. basic_string_view<charT, traits> y) noexcept;
  25. template<class charT, class traits>
  26. constexpr bool operator!=(basic_string_view<charT, traits> x,
  27. basic_string_view<charT, traits> y) noexcept;
  28. template<class charT, class traits>
  29. constexpr bool operator< (basic_string_view<charT, traits> x,
  30. basic_string_view<charT, traits> y) noexcept;
  31. template<class charT, class traits>
  32. constexpr bool operator> (basic_string_view<charT, traits> x,
  33. basic_string_view<charT, traits> y) noexcept;
  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>
  38. constexpr bool operator>=(basic_string_view<charT, traits> x,
  39. basic_string_view<charT, traits> y) noexcept;
  40. // see below, sufficient additional overloads of comparison functions
  41. // 7.10, Inserters and extractors
  42. template<class charT, class traits>
  43. basic_ostream<charT, traits>&
  44. operator<<(basic_ostream<charT, traits>& os,
  45. basic_string_view<charT, traits> str);
  46. // basic_string_view typedef names
  47. typedef basic_string_view<char> string_view;
  48. typedef basic_string_view<char8_t> u8string_view; // C++20
  49. typedef basic_string_view<char16_t> u16string_view;
  50. typedef basic_string_view<char32_t> u32string_view;
  51. typedef basic_string_view<wchar_t> wstring_view;
  52. template<class charT, class traits = char_traits<charT>>
  53. class basic_string_view {
  54. public:
  55. // types
  56. typedef traits traits_type;
  57. typedef charT value_type;
  58. typedef charT* pointer;
  59. typedef const charT* const_pointer;
  60. typedef charT& reference;
  61. typedef const charT& const_reference;
  62. typedef implementation-defined const_iterator;
  63. typedef const_iterator iterator;
  64. typedef reverse_iterator<const_iterator> const_reverse_iterator;
  65. typedef const_reverse_iterator reverse_iterator;
  66. typedef size_t size_type;
  67. typedef ptrdiff_t difference_type;
  68. static constexpr size_type npos = size_type(-1);
  69. // 7.3, basic_string_view constructors and assignment operators
  70. constexpr basic_string_view() noexcept;
  71. constexpr basic_string_view(const basic_string_view&) noexcept = default;
  72. basic_string_view& operator=(const basic_string_view&) noexcept = default;
  73. template<class Allocator>
  74. constexpr basic_string_view(const charT* str);
  75. basic_string_view(nullptr_t) = delete; // C++2b
  76. constexpr basic_string_view(const charT* str, size_type len);
  77. template <class It, class End>
  78. constexpr basic_string_view(It begin, End end); // C++20
  79. template <class Range>
  80. constexpr basic_string_view(Range&& r); // C++23
  81. // 7.4, basic_string_view iterator support
  82. constexpr const_iterator begin() const noexcept;
  83. constexpr const_iterator end() const noexcept;
  84. constexpr const_iterator cbegin() const noexcept;
  85. constexpr const_iterator cend() const noexcept;
  86. const_reverse_iterator rbegin() const noexcept;
  87. const_reverse_iterator rend() const noexcept;
  88. const_reverse_iterator crbegin() const noexcept;
  89. const_reverse_iterator crend() const noexcept;
  90. // 7.5, basic_string_view capacity
  91. constexpr size_type size() const noexcept;
  92. constexpr size_type length() const noexcept;
  93. constexpr size_type max_size() const noexcept;
  94. constexpr bool empty() const noexcept;
  95. // 7.6, basic_string_view element access
  96. constexpr const_reference operator[](size_type pos) const;
  97. constexpr const_reference at(size_type pos) const;
  98. constexpr const_reference front() const;
  99. constexpr const_reference back() const;
  100. constexpr const_pointer data() const noexcept;
  101. // 7.7, basic_string_view modifiers
  102. constexpr void remove_prefix(size_type n);
  103. constexpr void remove_suffix(size_type n);
  104. constexpr void swap(basic_string_view& s) noexcept;
  105. size_type copy(charT* s, size_type n, size_type pos = 0) const; // constexpr in C++20
  106. constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
  107. constexpr int compare(basic_string_view s) const noexcept;
  108. constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;
  109. constexpr int compare(size_type pos1, size_type n1,
  110. basic_string_view s, size_type pos2, size_type n2) const;
  111. constexpr int compare(const charT* s) const;
  112. constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
  113. constexpr int compare(size_type pos1, size_type n1,
  114. const charT* s, size_type n2) const;
  115. constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;
  116. constexpr size_type find(charT c, size_type pos = 0) const noexcept;
  117. constexpr size_type find(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
  118. constexpr size_type find(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension
  119. constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;
  120. constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;
  121. constexpr size_type rfind(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
  122. constexpr size_type rfind(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension
  123. constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;
  124. constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;
  125. constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
  126. constexpr size_type find_first_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension
  127. constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;
  128. constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;
  129. constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
  130. constexpr size_type find_last_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension
  131. constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;
  132. constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;
  133. constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
  134. constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension
  135. constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept;
  136. constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;
  137. constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
  138. constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension
  139. constexpr bool starts_with(basic_string_view s) const noexcept; // C++20
  140. constexpr bool starts_with(charT c) const noexcept; // C++20
  141. constexpr bool starts_with(const charT* s) const; // C++20
  142. constexpr bool ends_with(basic_string_view s) const noexcept; // C++20
  143. constexpr bool ends_with(charT c) const noexcept; // C++20
  144. constexpr bool ends_with(const charT* s) const; // C++20
  145. constexpr bool contains(basic_string_view s) const noexcept; // C++2b
  146. constexpr bool contains(charT c) const noexcept; // C++2b
  147. constexpr bool contains(const charT* s) const; // C++2b
  148. private:
  149. const_pointer data_; // exposition only
  150. size_type size_; // exposition only
  151. };
  152. // basic_string_view deduction guides
  153. template<class It, class End>
  154. basic_string_view(It, End) -> basic_string_view<iter_value_t<It>>; // C++20
  155. template<class Range>
  156. basic_string_view(Range&&) -> basic_string_view<ranges::range_value_t<Range>>; // C++23
  157. // 7.11, Hash support
  158. template <class T> struct hash;
  159. template <> struct hash<string_view>;
  160. template <> struct hash<u8string_view>; // C++20
  161. template <> struct hash<u16string_view>;
  162. template <> struct hash<u32string_view>;
  163. template <> struct hash<wstring_view>;
  164. constexpr basic_string_view<char> operator "" sv( const char *str, size_t len ) noexcept;
  165. constexpr basic_string_view<wchar_t> operator "" sv( const wchar_t *str, size_t len ) noexcept;
  166. constexpr basic_string_view<char8_t> operator "" sv( const char8_t *str, size_t len ) noexcept; // C++20
  167. constexpr basic_string_view<char16_t> operator "" sv( const char16_t *str, size_t len ) noexcept;
  168. constexpr basic_string_view<char32_t> operator "" sv( const char32_t *str, size_t len ) noexcept;
  169. } // namespace std
  170. */
  171. #include <__config>
  172. #include <__debug>
  173. #include <__ranges/concepts.h>
  174. #include <__ranges/data.h>
  175. #include <__ranges/enable_borrowed_range.h>
  176. #include <__ranges/enable_view.h>
  177. #include <__ranges/size.h>
  178. #include <__string>
  179. #include <algorithm>
  180. #include <compare>
  181. #include <iosfwd>
  182. #include <iterator>
  183. #include <limits>
  184. #include <stdexcept>
  185. #include <type_traits>
  186. #include <version>
  187. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  188. #pragma GCC system_header
  189. #endif
  190. #ifdef _LIBCPP_COMPILER_MSVC
  191. #pragma warning ( push )
  192. #pragma warning ( disable : 4455 )
  193. #endif
  194. _LIBCPP_PUSH_MACROS
  195. #include <__undef_macros>
  196. _LIBCPP_BEGIN_NAMESPACE_STD
  197. template<class _CharT, class _Traits = char_traits<_CharT> >
  198. class _LIBCPP_TEMPLATE_VIS basic_string_view;
  199. typedef basic_string_view<char> string_view;
  200. #ifndef _LIBCPP_HAS_NO_CHAR8_T
  201. typedef basic_string_view<char8_t> u8string_view;
  202. #endif
  203. typedef basic_string_view<char16_t> u16string_view;
  204. typedef basic_string_view<char32_t> u32string_view;
  205. #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
  206. typedef basic_string_view<wchar_t> wstring_view;
  207. #endif
  208. template<class _CharT, class _Traits>
  209. class
  210. _LIBCPP_PREFERRED_NAME(string_view)
  211. #ifndef _LIBCPP_HAS_NO_CHAR8_T
  212. _LIBCPP_PREFERRED_NAME(u8string_view)
  213. #endif
  214. _LIBCPP_PREFERRED_NAME(u16string_view)
  215. _LIBCPP_PREFERRED_NAME(u32string_view)
  216. _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstring_view))
  217. basic_string_view {
  218. public:
  219. // types
  220. typedef _Traits traits_type;
  221. typedef _CharT value_type;
  222. typedef _CharT* pointer;
  223. typedef const _CharT* const_pointer;
  224. typedef _CharT& reference;
  225. typedef const _CharT& const_reference;
  226. typedef const_pointer const_iterator; // See [string.view.iterators]
  227. typedef const_iterator iterator;
  228. typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
  229. typedef const_reverse_iterator reverse_iterator;
  230. typedef size_t size_type;
  231. typedef ptrdiff_t difference_type;
  232. static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1);
  233. static_assert((!is_array<value_type>::value), "Character type of basic_string_view must not be an array");
  234. static_assert(( is_standard_layout<value_type>::value), "Character type of basic_string_view must be standard-layout");
  235. static_assert(( is_trivial<value_type>::value), "Character type of basic_string_view must be trivial");
  236. static_assert((is_same<_CharT, typename traits_type::char_type>::value),
  237. "traits_type::char_type must be the same type as CharT");
  238. // [string.view.cons], construct/copy
  239. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  240. basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {}
  241. _LIBCPP_INLINE_VISIBILITY
  242. basic_string_view(const basic_string_view&) _NOEXCEPT = default;
  243. _LIBCPP_INLINE_VISIBILITY
  244. basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
  245. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  246. basic_string_view(nullptr_t, size_t) = delete;
  247. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  248. basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT
  249. : __data(__s), __size(__len)
  250. {
  251. #if _LIBCPP_STD_VER > 11
  252. _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr");
  253. #endif
  254. }
  255. #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
  256. template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
  257. requires (is_same_v<iter_value_t<_It>, _CharT> && !is_convertible_v<_End, size_type>)
  258. constexpr _LIBCPP_HIDE_FROM_ABI basic_string_view(_It __begin, _End __end)
  259. : __data(_VSTD::to_address(__begin)), __size(__end - __begin)
  260. {
  261. _LIBCPP_ASSERT((__end - __begin) >= 0, "std::string_view::string_view(iterator, sentinel) received invalid range");
  262. }
  263. #endif
  264. #if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_RANGES)
  265. template <class _Range>
  266. requires (
  267. !is_same_v<remove_cvref_t<_Range>, basic_string_view> &&
  268. ranges::contiguous_range<_Range> &&
  269. ranges::sized_range<_Range> &&
  270. is_same_v<ranges::range_value_t<_Range>, _CharT> &&
  271. !is_convertible_v<_Range, const _CharT*> &&
  272. (!requires(remove_cvref_t<_Range>& d) {
  273. d.operator _VSTD::basic_string_view<_CharT, _Traits>();
  274. }) &&
  275. (!requires {
  276. typename remove_reference_t<_Range>::traits_type;
  277. } || is_same_v<typename remove_reference_t<_Range>::traits_type, _Traits>)
  278. )
  279. constexpr _LIBCPP_HIDE_FROM_ABI
  280. basic_string_view(_Range&& __r) : __data(ranges::data(__r)), __size(ranges::size(__r)) {}
  281. #endif
  282. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  283. basic_string_view(nullptr_t) = delete;
  284. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  285. basic_string_view(const _CharT* __s)
  286. : __data(__s), __size(_VSTD::__char_traits_length_checked<_Traits>(__s)) {}
  287. #if _LIBCPP_STD_VER > 20
  288. basic_string_view(nullptr_t) = delete;
  289. #endif
  290. // [string.view.iterators], iterators
  291. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  292. const_iterator begin() const _NOEXCEPT { return cbegin(); }
  293. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  294. const_iterator end() const _NOEXCEPT { return cend(); }
  295. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  296. const_iterator cbegin() const _NOEXCEPT { return __data; }
  297. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  298. const_iterator cend() const _NOEXCEPT { return __data + __size; }
  299. _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
  300. const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); }
  301. _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
  302. const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
  303. _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
  304. const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); }
  305. _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
  306. const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
  307. // [string.view.capacity], capacity
  308. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  309. size_type size() const _NOEXCEPT { return __size; }
  310. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  311. size_type length() const _NOEXCEPT { return __size; }
  312. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  313. size_type max_size() const _NOEXCEPT { return numeric_limits<size_type>::max() / sizeof(value_type); }
  314. _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  315. bool empty() const _NOEXCEPT { return __size == 0; }
  316. // [string.view.access], element access
  317. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  318. const_reference operator[](size_type __pos) const _NOEXCEPT {
  319. return _LIBCPP_ASSERT(__pos < size(), "string_view[] index out of bounds"), __data[__pos];
  320. }
  321. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  322. const_reference at(size_type __pos) const
  323. {
  324. return __pos >= size()
  325. ? (__throw_out_of_range("string_view::at"), __data[0])
  326. : __data[__pos];
  327. }
  328. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  329. const_reference front() const _NOEXCEPT
  330. {
  331. return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data[0];
  332. }
  333. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  334. const_reference back() const _NOEXCEPT
  335. {
  336. return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data[__size-1];
  337. }
  338. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  339. const_pointer data() const _NOEXCEPT { return __data; }
  340. // [string.view.modifiers], modifiers:
  341. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  342. void remove_prefix(size_type __n) _NOEXCEPT
  343. {
  344. _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()");
  345. __data += __n;
  346. __size -= __n;
  347. }
  348. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  349. void remove_suffix(size_type __n) _NOEXCEPT
  350. {
  351. _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()");
  352. __size -= __n;
  353. }
  354. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  355. void swap(basic_string_view& __other) _NOEXCEPT
  356. {
  357. const value_type *__p = __data;
  358. __data = __other.__data;
  359. __other.__data = __p;
  360. size_type __sz = __size;
  361. __size = __other.__size;
  362. __other.__size = __sz;
  363. }
  364. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
  365. size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
  366. {
  367. if (__pos > size())
  368. __throw_out_of_range("string_view::copy");
  369. size_type __rlen = _VSTD::min(__n, size() - __pos);
  370. _Traits::copy(__s, data() + __pos, __rlen);
  371. return __rlen;
  372. }
  373. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  374. basic_string_view substr(size_type __pos = 0, size_type __n = npos) const
  375. {
  376. return __pos > size()
  377. ? (__throw_out_of_range("string_view::substr"), basic_string_view())
  378. : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos));
  379. }
  380. _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT
  381. {
  382. size_type __rlen = _VSTD::min( size(), __sv.size());
  383. int __retval = _Traits::compare(data(), __sv.data(), __rlen);
  384. if ( __retval == 0 ) // first __rlen chars matched
  385. __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 );
  386. return __retval;
  387. }
  388. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  389. int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const
  390. {
  391. return substr(__pos1, __n1).compare(__sv);
  392. }
  393. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  394. int compare( size_type __pos1, size_type __n1,
  395. basic_string_view __sv, size_type __pos2, size_type __n2) const
  396. {
  397. return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
  398. }
  399. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  400. int compare(const _CharT* __s) const _NOEXCEPT
  401. {
  402. return compare(basic_string_view(__s));
  403. }
  404. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  405. int compare(size_type __pos1, size_type __n1, const _CharT* __s) const
  406. {
  407. return substr(__pos1, __n1).compare(basic_string_view(__s));
  408. }
  409. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  410. int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
  411. {
  412. return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
  413. }
  414. // find
  415. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  416. size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
  417. {
  418. _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
  419. return __str_find<value_type, size_type, traits_type, npos>
  420. (data(), size(), __s.data(), __pos, __s.size());
  421. }
  422. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  423. size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT
  424. {
  425. return __str_find<value_type, size_type, traits_type, npos>
  426. (data(), size(), __c, __pos);
  427. }
  428. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  429. size_type find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
  430. {
  431. _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
  432. return __str_find<value_type, size_type, traits_type, npos>
  433. (data(), size(), __s, __pos, __n);
  434. }
  435. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  436. size_type find(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT
  437. {
  438. _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr");
  439. return __str_find<value_type, size_type, traits_type, npos>
  440. (data(), size(), __s, __pos, traits_type::length(__s));
  441. }
  442. // rfind
  443. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  444. size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT
  445. {
  446. _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
  447. return __str_rfind<value_type, size_type, traits_type, npos>
  448. (data(), size(), __s.data(), __pos, __s.size());
  449. }
  450. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  451. size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT
  452. {
  453. return __str_rfind<value_type, size_type, traits_type, npos>
  454. (data(), size(), __c, __pos);
  455. }
  456. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  457. size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
  458. {
  459. _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
  460. return __str_rfind<value_type, size_type, traits_type, npos>
  461. (data(), size(), __s, __pos, __n);
  462. }
  463. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  464. size_type rfind(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
  465. {
  466. _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr");
  467. return __str_rfind<value_type, size_type, traits_type, npos>
  468. (data(), size(), __s, __pos, traits_type::length(__s));
  469. }
  470. // find_first_of
  471. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  472. size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
  473. {
  474. _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
  475. return __str_find_first_of<value_type, size_type, traits_type, npos>
  476. (data(), size(), __s.data(), __pos, __s.size());
  477. }
  478. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  479. size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT
  480. { return find(__c, __pos); }
  481. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  482. size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
  483. {
  484. _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
  485. return __str_find_first_of<value_type, size_type, traits_type, npos>
  486. (data(), size(), __s, __pos, __n);
  487. }
  488. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  489. size_type find_first_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT
  490. {
  491. _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr");
  492. return __str_find_first_of<value_type, size_type, traits_type, npos>
  493. (data(), size(), __s, __pos, traits_type::length(__s));
  494. }
  495. // find_last_of
  496. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  497. size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
  498. {
  499. _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
  500. return __str_find_last_of<value_type, size_type, traits_type, npos>
  501. (data(), size(), __s.data(), __pos, __s.size());
  502. }
  503. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  504. size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT
  505. { return rfind(__c, __pos); }
  506. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  507. size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
  508. {
  509. _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
  510. return __str_find_last_of<value_type, size_type, traits_type, npos>
  511. (data(), size(), __s, __pos, __n);
  512. }
  513. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  514. size_type find_last_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
  515. {
  516. _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr");
  517. return __str_find_last_of<value_type, size_type, traits_type, npos>
  518. (data(), size(), __s, __pos, traits_type::length(__s));
  519. }
  520. // find_first_not_of
  521. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  522. size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT
  523. {
  524. _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
  525. return __str_find_first_not_of<value_type, size_type, traits_type, npos>
  526. (data(), size(), __s.data(), __pos, __s.size());
  527. }
  528. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  529. size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT
  530. {
  531. return __str_find_first_not_of<value_type, size_type, traits_type, npos>
  532. (data(), size(), __c, __pos);
  533. }
  534. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  535. size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
  536. {
  537. _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
  538. return __str_find_first_not_of<value_type, size_type, traits_type, npos>
  539. (data(), size(), __s, __pos, __n);
  540. }
  541. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  542. size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT
  543. {
  544. _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
  545. return __str_find_first_not_of<value_type, size_type, traits_type, npos>
  546. (data(), size(), __s, __pos, traits_type::length(__s));
  547. }
  548. // find_last_not_of
  549. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  550. size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
  551. {
  552. _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
  553. return __str_find_last_not_of<value_type, size_type, traits_type, npos>
  554. (data(), size(), __s.data(), __pos, __s.size());
  555. }
  556. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  557. size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT
  558. {
  559. return __str_find_last_not_of<value_type, size_type, traits_type, npos>
  560. (data(), size(), __c, __pos);
  561. }
  562. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  563. size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
  564. {
  565. _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
  566. return __str_find_last_not_of<value_type, size_type, traits_type, npos>
  567. (data(), size(), __s, __pos, __n);
  568. }
  569. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  570. size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
  571. {
  572. _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
  573. return __str_find_last_not_of<value_type, size_type, traits_type, npos>
  574. (data(), size(), __s, __pos, traits_type::length(__s));
  575. }
  576. //WARN: disabled std guards in order to allow using these options without switching to new std
  577. //#if _LIBCPP_STD_VER > 17
  578. constexpr _LIBCPP_INLINE_VISIBILITY
  579. bool starts_with(basic_string_view __s) const noexcept
  580. { return size() >= __s.size() && compare(0, __s.size(), __s) == 0; }
  581. constexpr _LIBCPP_INLINE_VISIBILITY
  582. bool starts_with(value_type __c) const noexcept
  583. { return !empty() && _Traits::eq(front(), __c); }
  584. constexpr _LIBCPP_INLINE_VISIBILITY
  585. bool starts_with(const value_type* __s) const noexcept
  586. { return starts_with(basic_string_view(__s)); }
  587. constexpr _LIBCPP_INLINE_VISIBILITY
  588. bool ends_with(basic_string_view __s) const noexcept
  589. { return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0; }
  590. constexpr _LIBCPP_INLINE_VISIBILITY
  591. bool ends_with(value_type __c) const noexcept
  592. { return !empty() && _Traits::eq(back(), __c); }
  593. constexpr _LIBCPP_INLINE_VISIBILITY
  594. bool ends_with(const value_type* __s) const noexcept
  595. { return ends_with(basic_string_view(__s)); }
  596. //#endif
  597. #if _LIBCPP_STD_VER >= 20
  598. constexpr _LIBCPP_INLINE_VISIBILITY
  599. bool contains(basic_string_view __sv) const noexcept
  600. { return find(__sv) != npos; }
  601. constexpr _LIBCPP_INLINE_VISIBILITY
  602. bool contains(value_type __c) const noexcept
  603. { return find(__c) != npos; }
  604. constexpr _LIBCPP_INLINE_VISIBILITY
  605. bool contains(const value_type* __s) const
  606. { return find(__s) != npos; }
  607. #endif
  608. private:
  609. const value_type* __data;
  610. size_type __size;
  611. };
  612. #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
  613. template <class _CharT, class _Traits>
  614. inline constexpr bool ranges::enable_view<basic_string_view<_CharT, _Traits>> = true;
  615. template <class _CharT, class _Traits>
  616. inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true;
  617. #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
  618. // [string.view.deduct]
  619. #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
  620. template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
  621. basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>;
  622. #endif
  623. #if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_RANGES)
  624. template <ranges::contiguous_range _Range>
  625. basic_string_view(_Range) -> basic_string_view<ranges::range_value_t<_Range>>;
  626. #endif
  627. // [string.view.comparison]
  628. // operator ==
  629. template<class _CharT, class _Traits>
  630. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  631. bool operator==(basic_string_view<_CharT, _Traits> __lhs,
  632. basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  633. {
  634. if ( __lhs.size() != __rhs.size()) return false;
  635. return __lhs.compare(__rhs) == 0;
  636. }
  637. // The dummy default template parameters are used to work around a MSVC issue with mangling, see VSO-409236 for details.
  638. // This applies to the other sufficient overloads below for the other comparison operators.
  639. template<class _CharT, class _Traits, int = 1>
  640. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  641. bool operator==(basic_string_view<_CharT, _Traits> __lhs,
  642. typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
  643. {
  644. if ( __lhs.size() != __rhs.size()) return false;
  645. return __lhs.compare(__rhs) == 0;
  646. }
  647. template<class _CharT, class _Traits, int = 2>
  648. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  649. bool operator==(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
  650. basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  651. {
  652. if ( __lhs.size() != __rhs.size()) return false;
  653. return __lhs.compare(__rhs) == 0;
  654. }
  655. // operator !=
  656. template<class _CharT, class _Traits>
  657. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  658. bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  659. {
  660. if ( __lhs.size() != __rhs.size())
  661. return true;
  662. return __lhs.compare(__rhs) != 0;
  663. }
  664. template<class _CharT, class _Traits, int = 1>
  665. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  666. bool operator!=(basic_string_view<_CharT, _Traits> __lhs,
  667. typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
  668. {
  669. if ( __lhs.size() != __rhs.size())
  670. return true;
  671. return __lhs.compare(__rhs) != 0;
  672. }
  673. template<class _CharT, class _Traits, int = 2>
  674. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  675. bool operator!=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
  676. basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  677. {
  678. if ( __lhs.size() != __rhs.size())
  679. return true;
  680. return __lhs.compare(__rhs) != 0;
  681. }
  682. // operator <
  683. template<class _CharT, class _Traits>
  684. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  685. bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  686. {
  687. return __lhs.compare(__rhs) < 0;
  688. }
  689. template<class _CharT, class _Traits, int = 1>
  690. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  691. bool operator<(basic_string_view<_CharT, _Traits> __lhs,
  692. typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
  693. {
  694. return __lhs.compare(__rhs) < 0;
  695. }
  696. template<class _CharT, class _Traits, int = 2>
  697. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  698. bool operator<(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
  699. basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  700. {
  701. return __lhs.compare(__rhs) < 0;
  702. }
  703. // operator >
  704. template<class _CharT, class _Traits>
  705. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  706. bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  707. {
  708. return __lhs.compare(__rhs) > 0;
  709. }
  710. template<class _CharT, class _Traits, int = 1>
  711. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  712. bool operator>(basic_string_view<_CharT, _Traits> __lhs,
  713. typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
  714. {
  715. return __lhs.compare(__rhs) > 0;
  716. }
  717. template<class _CharT, class _Traits, int = 2>
  718. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  719. bool operator>(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
  720. basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  721. {
  722. return __lhs.compare(__rhs) > 0;
  723. }
  724. // operator <=
  725. template<class _CharT, class _Traits>
  726. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  727. bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  728. {
  729. return __lhs.compare(__rhs) <= 0;
  730. }
  731. template<class _CharT, class _Traits, int = 1>
  732. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  733. bool operator<=(basic_string_view<_CharT, _Traits> __lhs,
  734. typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
  735. {
  736. return __lhs.compare(__rhs) <= 0;
  737. }
  738. template<class _CharT, class _Traits, int = 2>
  739. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  740. bool operator<=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
  741. basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  742. {
  743. return __lhs.compare(__rhs) <= 0;
  744. }
  745. // operator >=
  746. template<class _CharT, class _Traits>
  747. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  748. bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  749. {
  750. return __lhs.compare(__rhs) >= 0;
  751. }
  752. template<class _CharT, class _Traits, int = 1>
  753. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  754. bool operator>=(basic_string_view<_CharT, _Traits> __lhs,
  755. typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
  756. {
  757. return __lhs.compare(__rhs) >= 0;
  758. }
  759. template<class _CharT, class _Traits, int = 2>
  760. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  761. bool operator>=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
  762. basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  763. {
  764. return __lhs.compare(__rhs) >= 0;
  765. }
  766. template<class _CharT, class _Traits>
  767. basic_ostream<_CharT, _Traits>&
  768. operator<<(basic_ostream<_CharT, _Traits>& __os,
  769. basic_string_view<_CharT, _Traits> __str);
  770. // [string.view.hash]
  771. template<class _CharT>
  772. struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, char_traits<_CharT> > >
  773. : public unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t>
  774. {
  775. _LIBCPP_INLINE_VISIBILITY
  776. size_t operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT {
  777. return __do_string_hash(__val.data(), __val.data() + __val.size());
  778. }
  779. };
  780. #if _LIBCPP_STD_VER > 11
  781. inline namespace literals
  782. {
  783. inline namespace string_view_literals
  784. {
  785. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  786. basic_string_view<char> operator "" sv(const char *__str, size_t __len) _NOEXCEPT
  787. {
  788. return basic_string_view<char> (__str, __len);
  789. }
  790. #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
  791. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  792. basic_string_view<wchar_t> operator "" sv(const wchar_t *__str, size_t __len) _NOEXCEPT
  793. {
  794. return basic_string_view<wchar_t> (__str, __len);
  795. }
  796. #endif
  797. #ifndef _LIBCPP_HAS_NO_CHAR8_T
  798. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  799. basic_string_view<char8_t> operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT
  800. {
  801. return basic_string_view<char8_t> (__str, __len);
  802. }
  803. #endif
  804. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  805. basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT
  806. {
  807. return basic_string_view<char16_t> (__str, __len);
  808. }
  809. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  810. basic_string_view<char32_t> operator "" sv(const char32_t *__str, size_t __len) _NOEXCEPT
  811. {
  812. return basic_string_view<char32_t> (__str, __len);
  813. }
  814. } // namespace string_view_literals
  815. } // namespace literals
  816. #endif
  817. _LIBCPP_END_NAMESPACE_STD
  818. #ifdef _LIBCPP_COMPILER_MSVC
  819. #pragma warning ( pop )
  820. #endif
  821. _LIBCPP_POP_MACROS
  822. #endif // _LIBCPP_STRING_VIEW