string_view 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970
  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 <__algorithm/min.h>
  172. #include <__assert>
  173. #include <__config>
  174. #include <__ranges/concepts.h>
  175. #include <__ranges/data.h>
  176. #include <__ranges/enable_borrowed_range.h>
  177. #include <__ranges/enable_view.h>
  178. #include <__ranges/size.h>
  179. #include <__string>
  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 = numeric_limits<size_type>::max(); // 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 !defined(_LIBCPP_HAS_NO_CONCEPTS)
  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 // !defined(_LIBCPP_HAS_NO_CONCEPTS)
  264. #if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_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(const _CharT* __s)
  284. : __data(__s), __size(_VSTD::__char_traits_length_checked<_Traits>(__s)) {}
  285. #if _LIBCPP_STD_VER > 17
  286. basic_string_view(nullptr_t) = delete;
  287. #endif
  288. // [string.view.iterators], iterators
  289. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  290. const_iterator begin() const _NOEXCEPT { return cbegin(); }
  291. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  292. const_iterator end() const _NOEXCEPT { return cend(); }
  293. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  294. const_iterator cbegin() const _NOEXCEPT { return __data; }
  295. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  296. const_iterator cend() const _NOEXCEPT { return __data + __size; }
  297. _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
  298. const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); }
  299. _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
  300. const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
  301. _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
  302. const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); }
  303. _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
  304. const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
  305. // [string.view.capacity], capacity
  306. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  307. size_type size() const _NOEXCEPT { return __size; }
  308. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  309. size_type length() const _NOEXCEPT { return __size; }
  310. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  311. size_type max_size() const _NOEXCEPT { return numeric_limits<size_type>::max() / sizeof(value_type); }
  312. _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  313. bool empty() const _NOEXCEPT { return __size == 0; }
  314. // [string.view.access], element access
  315. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  316. const_reference operator[](size_type __pos) const _NOEXCEPT {
  317. return _LIBCPP_ASSERT(__pos < size(), "string_view[] index out of bounds"), __data[__pos];
  318. }
  319. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  320. const_reference at(size_type __pos) const
  321. {
  322. return __pos >= size()
  323. ? (__throw_out_of_range("string_view::at"), __data[0])
  324. : __data[__pos];
  325. }
  326. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  327. const_reference front() const _NOEXCEPT
  328. {
  329. return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data[0];
  330. }
  331. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  332. const_reference back() const _NOEXCEPT
  333. {
  334. return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data[__size-1];
  335. }
  336. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  337. const_pointer data() const _NOEXCEPT { return __data; }
  338. // [string.view.modifiers], modifiers:
  339. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  340. void remove_prefix(size_type __n) _NOEXCEPT
  341. {
  342. _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()");
  343. __data += __n;
  344. __size -= __n;
  345. }
  346. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  347. void remove_suffix(size_type __n) _NOEXCEPT
  348. {
  349. _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()");
  350. __size -= __n;
  351. }
  352. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  353. void swap(basic_string_view& __other) _NOEXCEPT
  354. {
  355. const value_type *__p = __data;
  356. __data = __other.__data;
  357. __other.__data = __p;
  358. size_type __sz = __size;
  359. __size = __other.__size;
  360. __other.__size = __sz;
  361. }
  362. _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
  363. size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
  364. {
  365. if (__pos > size())
  366. __throw_out_of_range("string_view::copy");
  367. size_type __rlen = _VSTD::min(__n, size() - __pos);
  368. _Traits::copy(__s, data() + __pos, __rlen);
  369. return __rlen;
  370. }
  371. _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
  372. basic_string_view substr(size_type __pos = 0, size_type __n = npos) const
  373. {
  374. return __pos > size()
  375. ? (__throw_out_of_range("string_view::substr"), basic_string_view())
  376. : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos));
  377. }
  378. _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT
  379. {
  380. size_type __rlen = _VSTD::min( size(), __sv.size());
  381. int __retval = _Traits::compare(data(), __sv.data(), __rlen);
  382. if ( __retval == 0 ) // first __rlen chars matched
  383. __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 );
  384. return __retval;
  385. }
  386. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  387. int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const
  388. {
  389. return substr(__pos1, __n1).compare(__sv);
  390. }
  391. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  392. int compare( size_type __pos1, size_type __n1,
  393. basic_string_view __sv, size_type __pos2, size_type __n2) const
  394. {
  395. return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
  396. }
  397. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  398. int compare(const _CharT* __s) const _NOEXCEPT
  399. {
  400. return compare(basic_string_view(__s));
  401. }
  402. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  403. int compare(size_type __pos1, size_type __n1, const _CharT* __s) const
  404. {
  405. return substr(__pos1, __n1).compare(basic_string_view(__s));
  406. }
  407. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  408. int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
  409. {
  410. return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
  411. }
  412. // find
  413. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  414. size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
  415. {
  416. _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
  417. return __str_find<value_type, size_type, traits_type, npos>
  418. (data(), size(), __s.data(), __pos, __s.size());
  419. }
  420. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  421. size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT
  422. {
  423. return __str_find<value_type, size_type, traits_type, npos>
  424. (data(), size(), __c, __pos);
  425. }
  426. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  427. size_type find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
  428. {
  429. _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
  430. return __str_find<value_type, size_type, traits_type, npos>
  431. (data(), size(), __s, __pos, __n);
  432. }
  433. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  434. size_type find(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT
  435. {
  436. _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr");
  437. return __str_find<value_type, size_type, traits_type, npos>
  438. (data(), size(), __s, __pos, traits_type::length(__s));
  439. }
  440. // rfind
  441. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  442. size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT
  443. {
  444. _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
  445. return __str_rfind<value_type, size_type, traits_type, npos>
  446. (data(), size(), __s.data(), __pos, __s.size());
  447. }
  448. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  449. size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT
  450. {
  451. return __str_rfind<value_type, size_type, traits_type, npos>
  452. (data(), size(), __c, __pos);
  453. }
  454. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  455. size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
  456. {
  457. _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
  458. return __str_rfind<value_type, size_type, traits_type, npos>
  459. (data(), size(), __s, __pos, __n);
  460. }
  461. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  462. size_type rfind(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
  463. {
  464. _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr");
  465. return __str_rfind<value_type, size_type, traits_type, npos>
  466. (data(), size(), __s, __pos, traits_type::length(__s));
  467. }
  468. // find_first_of
  469. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  470. size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
  471. {
  472. _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
  473. return __str_find_first_of<value_type, size_type, traits_type, npos>
  474. (data(), size(), __s.data(), __pos, __s.size());
  475. }
  476. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  477. size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT
  478. { return find(__c, __pos); }
  479. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  480. size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
  481. {
  482. _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
  483. return __str_find_first_of<value_type, size_type, traits_type, npos>
  484. (data(), size(), __s, __pos, __n);
  485. }
  486. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  487. size_type find_first_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT
  488. {
  489. _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr");
  490. return __str_find_first_of<value_type, size_type, traits_type, npos>
  491. (data(), size(), __s, __pos, traits_type::length(__s));
  492. }
  493. // find_last_of
  494. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  495. size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
  496. {
  497. _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
  498. return __str_find_last_of<value_type, size_type, traits_type, npos>
  499. (data(), size(), __s.data(), __pos, __s.size());
  500. }
  501. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  502. size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT
  503. { return rfind(__c, __pos); }
  504. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  505. size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
  506. {
  507. _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
  508. return __str_find_last_of<value_type, size_type, traits_type, npos>
  509. (data(), size(), __s, __pos, __n);
  510. }
  511. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  512. size_type find_last_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
  513. {
  514. _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr");
  515. return __str_find_last_of<value_type, size_type, traits_type, npos>
  516. (data(), size(), __s, __pos, traits_type::length(__s));
  517. }
  518. // find_first_not_of
  519. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  520. size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT
  521. {
  522. _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
  523. return __str_find_first_not_of<value_type, size_type, traits_type, npos>
  524. (data(), size(), __s.data(), __pos, __s.size());
  525. }
  526. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  527. size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT
  528. {
  529. return __str_find_first_not_of<value_type, size_type, traits_type, npos>
  530. (data(), size(), __c, __pos);
  531. }
  532. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  533. size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
  534. {
  535. _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
  536. return __str_find_first_not_of<value_type, size_type, traits_type, npos>
  537. (data(), size(), __s, __pos, __n);
  538. }
  539. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  540. size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT
  541. {
  542. _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
  543. return __str_find_first_not_of<value_type, size_type, traits_type, npos>
  544. (data(), size(), __s, __pos, traits_type::length(__s));
  545. }
  546. // find_last_not_of
  547. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  548. size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
  549. {
  550. _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
  551. return __str_find_last_not_of<value_type, size_type, traits_type, npos>
  552. (data(), size(), __s.data(), __pos, __s.size());
  553. }
  554. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  555. size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT
  556. {
  557. return __str_find_last_not_of<value_type, size_type, traits_type, npos>
  558. (data(), size(), __c, __pos);
  559. }
  560. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  561. size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
  562. {
  563. _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
  564. return __str_find_last_not_of<value_type, size_type, traits_type, npos>
  565. (data(), size(), __s, __pos, __n);
  566. }
  567. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  568. size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
  569. {
  570. _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
  571. return __str_find_last_not_of<value_type, size_type, traits_type, npos>
  572. (data(), size(), __s, __pos, traits_type::length(__s));
  573. }
  574. //WARN: disabled std guards in order to allow using these options without switching to new std
  575. //#if _LIBCPP_STD_VER > 17
  576. constexpr _LIBCPP_INLINE_VISIBILITY
  577. bool starts_with(basic_string_view __s) const noexcept
  578. { return size() >= __s.size() && compare(0, __s.size(), __s) == 0; }
  579. constexpr _LIBCPP_INLINE_VISIBILITY
  580. bool starts_with(value_type __c) const noexcept
  581. { return !empty() && _Traits::eq(front(), __c); }
  582. constexpr _LIBCPP_INLINE_VISIBILITY
  583. bool starts_with(const value_type* __s) const noexcept
  584. { return starts_with(basic_string_view(__s)); }
  585. constexpr _LIBCPP_INLINE_VISIBILITY
  586. bool ends_with(basic_string_view __s) const noexcept
  587. { return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0; }
  588. constexpr _LIBCPP_INLINE_VISIBILITY
  589. bool ends_with(value_type __c) const noexcept
  590. { return !empty() && _Traits::eq(back(), __c); }
  591. constexpr _LIBCPP_INLINE_VISIBILITY
  592. bool ends_with(const value_type* __s) const noexcept
  593. { return ends_with(basic_string_view(__s)); }
  594. //#endif
  595. #if _LIBCPP_STD_VER >= 20
  596. constexpr _LIBCPP_INLINE_VISIBILITY
  597. bool contains(basic_string_view __sv) const noexcept
  598. { return find(__sv) != npos; }
  599. constexpr _LIBCPP_INLINE_VISIBILITY
  600. bool contains(value_type __c) const noexcept
  601. { return find(__c) != npos; }
  602. constexpr _LIBCPP_INLINE_VISIBILITY
  603. bool contains(const value_type* __s) const
  604. { return find(__s) != npos; }
  605. #endif
  606. private:
  607. const value_type* __data;
  608. size_type __size;
  609. };
  610. #if !defined(_LIBCPP_HAS_NO_CONCEPTS)
  611. template <class _CharT, class _Traits>
  612. inline constexpr bool ranges::enable_view<basic_string_view<_CharT, _Traits>> = true;
  613. template <class _CharT, class _Traits>
  614. inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true;
  615. #endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
  616. // [string.view.deduct]
  617. #if !defined(_LIBCPP_HAS_NO_CONCEPTS)
  618. template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
  619. basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>;
  620. #endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
  621. #if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
  622. template <ranges::contiguous_range _Range>
  623. basic_string_view(_Range) -> basic_string_view<ranges::range_value_t<_Range>>;
  624. #endif
  625. // [string.view.comparison]
  626. // operator ==
  627. template<class _CharT, class _Traits>
  628. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  629. bool operator==(basic_string_view<_CharT, _Traits> __lhs,
  630. basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  631. {
  632. if ( __lhs.size() != __rhs.size()) return false;
  633. return __lhs.compare(__rhs) == 0;
  634. }
  635. // The dummy default template parameters are used to work around a MSVC issue with mangling, see VSO-409326 for details.
  636. // This applies to the other sufficient overloads below for the other comparison operators.
  637. template<class _CharT, class _Traits, int = 1>
  638. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  639. bool operator==(basic_string_view<_CharT, _Traits> __lhs,
  640. typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
  641. {
  642. if ( __lhs.size() != __rhs.size()) return false;
  643. return __lhs.compare(__rhs) == 0;
  644. }
  645. template<class _CharT, class _Traits, int = 2>
  646. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  647. bool operator==(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
  648. basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  649. {
  650. if ( __lhs.size() != __rhs.size()) return false;
  651. return __lhs.compare(__rhs) == 0;
  652. }
  653. // operator !=
  654. template<class _CharT, class _Traits>
  655. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  656. bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  657. {
  658. if ( __lhs.size() != __rhs.size())
  659. return true;
  660. return __lhs.compare(__rhs) != 0;
  661. }
  662. template<class _CharT, class _Traits, int = 1>
  663. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  664. bool operator!=(basic_string_view<_CharT, _Traits> __lhs,
  665. typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
  666. {
  667. if ( __lhs.size() != __rhs.size())
  668. return true;
  669. return __lhs.compare(__rhs) != 0;
  670. }
  671. template<class _CharT, class _Traits, int = 2>
  672. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  673. bool operator!=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
  674. basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  675. {
  676. if ( __lhs.size() != __rhs.size())
  677. return true;
  678. return __lhs.compare(__rhs) != 0;
  679. }
  680. // operator <
  681. template<class _CharT, class _Traits>
  682. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  683. bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  684. {
  685. return __lhs.compare(__rhs) < 0;
  686. }
  687. template<class _CharT, class _Traits, int = 1>
  688. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  689. bool operator<(basic_string_view<_CharT, _Traits> __lhs,
  690. typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
  691. {
  692. return __lhs.compare(__rhs) < 0;
  693. }
  694. template<class _CharT, class _Traits, int = 2>
  695. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  696. bool operator<(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
  697. basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  698. {
  699. return __lhs.compare(__rhs) < 0;
  700. }
  701. // operator >
  702. template<class _CharT, class _Traits>
  703. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  704. bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  705. {
  706. return __lhs.compare(__rhs) > 0;
  707. }
  708. template<class _CharT, class _Traits, int = 1>
  709. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  710. bool operator>(basic_string_view<_CharT, _Traits> __lhs,
  711. typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
  712. {
  713. return __lhs.compare(__rhs) > 0;
  714. }
  715. template<class _CharT, class _Traits, int = 2>
  716. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  717. bool operator>(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
  718. basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  719. {
  720. return __lhs.compare(__rhs) > 0;
  721. }
  722. // operator <=
  723. template<class _CharT, class _Traits>
  724. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  725. bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  726. {
  727. return __lhs.compare(__rhs) <= 0;
  728. }
  729. template<class _CharT, class _Traits, int = 1>
  730. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  731. bool operator<=(basic_string_view<_CharT, _Traits> __lhs,
  732. typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
  733. {
  734. return __lhs.compare(__rhs) <= 0;
  735. }
  736. template<class _CharT, class _Traits, int = 2>
  737. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  738. bool operator<=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
  739. basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  740. {
  741. return __lhs.compare(__rhs) <= 0;
  742. }
  743. // operator >=
  744. template<class _CharT, class _Traits>
  745. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  746. bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  747. {
  748. return __lhs.compare(__rhs) >= 0;
  749. }
  750. template<class _CharT, class _Traits, int = 1>
  751. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  752. bool operator>=(basic_string_view<_CharT, _Traits> __lhs,
  753. typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
  754. {
  755. return __lhs.compare(__rhs) >= 0;
  756. }
  757. template<class _CharT, class _Traits, int = 2>
  758. _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
  759. bool operator>=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
  760. basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
  761. {
  762. return __lhs.compare(__rhs) >= 0;
  763. }
  764. template<class _CharT, class _Traits>
  765. basic_ostream<_CharT, _Traits>&
  766. operator<<(basic_ostream<_CharT, _Traits>& __os,
  767. basic_string_view<_CharT, _Traits> __str);
  768. // [string.view.hash]
  769. template<class _CharT>
  770. struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, char_traits<_CharT> > >
  771. : public unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t>
  772. {
  773. _LIBCPP_INLINE_VISIBILITY
  774. size_t operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT {
  775. return __do_string_hash(__val.data(), __val.data() + __val.size());
  776. }
  777. };
  778. #if _LIBCPP_STD_VER > 11
  779. inline namespace literals
  780. {
  781. inline namespace string_view_literals
  782. {
  783. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  784. basic_string_view<char> operator "" sv(const char *__str, size_t __len) _NOEXCEPT
  785. {
  786. return basic_string_view<char> (__str, __len);
  787. }
  788. #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
  789. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  790. basic_string_view<wchar_t> operator "" sv(const wchar_t *__str, size_t __len) _NOEXCEPT
  791. {
  792. return basic_string_view<wchar_t> (__str, __len);
  793. }
  794. #endif
  795. #ifndef _LIBCPP_HAS_NO_CHAR8_T
  796. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  797. basic_string_view<char8_t> operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT
  798. {
  799. return basic_string_view<char8_t> (__str, __len);
  800. }
  801. #endif
  802. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  803. basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT
  804. {
  805. return basic_string_view<char16_t> (__str, __len);
  806. }
  807. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  808. basic_string_view<char32_t> operator "" sv(const char32_t *__str, size_t __len) _NOEXCEPT
  809. {
  810. return basic_string_view<char32_t> (__str, __len);
  811. }
  812. } // namespace string_view_literals
  813. } // namespace literals
  814. #endif
  815. _LIBCPP_END_NAMESPACE_STD
  816. #ifdef _LIBCPP_COMPILER_MSVC
  817. #pragma warning ( pop )
  818. #endif
  819. _LIBCPP_POP_MACROS
  820. #endif // _LIBCPP_STRING_VIEW