string_view 34 KB

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