string_view 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909
  1. // Components for manipulating non-owning sequences of characters -*- C++ -*-
  2. // Copyright (C) 2013-2023 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file include/string_view
  21. * This is a Standard C++ Library header.
  22. */
  23. //
  24. // N3762 basic_string_view library
  25. //
  26. #ifndef _GLIBCXX_STRING_VIEW
  27. #define _GLIBCXX_STRING_VIEW 1
  28. #pragma GCC system_header
  29. #if __cplusplus >= 201703L
  30. #include <bits/char_traits.h>
  31. #include <bits/functexcept.h>
  32. #include <bits/functional_hash.h>
  33. #include <bits/range_access.h>
  34. #include <bits/stl_algobase.h>
  35. #include <ext/numeric_traits.h>
  36. #if __cplusplus >= 202002L
  37. # include <bits/ranges_base.h>
  38. #endif
  39. #if _GLIBCXX_HOSTED
  40. # include <iosfwd>
  41. # include <bits/ostream_insert.h>
  42. #endif
  43. namespace std _GLIBCXX_VISIBILITY(default)
  44. {
  45. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  46. #if _GLIBCXX_HOSTED
  47. # define __cpp_lib_string_view 201803L
  48. #endif
  49. #if __cplusplus > 201703L
  50. # define __cpp_lib_constexpr_string_view 201811L
  51. #endif
  52. // Helper for basic_string and basic_string_view members.
  53. constexpr size_t
  54. __sv_check(size_t __size, size_t __pos, const char* __s)
  55. {
  56. if (__pos > __size)
  57. __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > __size "
  58. "(which is %zu)"), __s, __pos, __size);
  59. return __pos;
  60. }
  61. // Helper for basic_string members.
  62. // NB: __sv_limit doesn't check for a bad __pos value.
  63. constexpr size_t
  64. __sv_limit(size_t __size, size_t __pos, size_t __off) noexcept
  65. {
  66. const bool __testoff = __off < __size - __pos;
  67. return __testoff ? __off : __size - __pos;
  68. }
  69. /**
  70. * @class basic_string_view <string_view>
  71. * @brief A non-owning reference to a string.
  72. *
  73. * @ingroup strings
  74. * @ingroup sequences
  75. *
  76. * @tparam _CharT Type of character
  77. * @tparam _Traits Traits for character type, defaults to
  78. * char_traits<_CharT>.
  79. *
  80. * A basic_string_view looks like this:
  81. *
  82. * @code
  83. * _CharT* _M_str
  84. * size_t _M_len
  85. * @endcode
  86. */
  87. template<typename _CharT, typename _Traits = std::char_traits<_CharT>>
  88. class basic_string_view
  89. {
  90. static_assert(!is_array_v<_CharT>);
  91. static_assert(is_trivial_v<_CharT> && is_standard_layout_v<_CharT>);
  92. static_assert(is_same_v<_CharT, typename _Traits::char_type>);
  93. public:
  94. // types
  95. using traits_type = _Traits;
  96. using value_type = _CharT;
  97. using pointer = value_type*;
  98. using const_pointer = const value_type*;
  99. using reference = value_type&;
  100. using const_reference = const value_type&;
  101. using const_iterator = const value_type*;
  102. using iterator = const_iterator;
  103. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  104. using reverse_iterator = const_reverse_iterator;
  105. using size_type = size_t;
  106. using difference_type = ptrdiff_t;
  107. static constexpr size_type npos = size_type(-1);
  108. // [string.view.cons], construction and assignment
  109. constexpr
  110. basic_string_view() noexcept
  111. : _M_len{0}, _M_str{nullptr}
  112. { }
  113. constexpr basic_string_view(const basic_string_view&) noexcept = default;
  114. [[__gnu__::__nonnull__]]
  115. constexpr
  116. basic_string_view(const _CharT* __str) noexcept
  117. : _M_len{traits_type::length(__str)},
  118. _M_str{__str}
  119. { }
  120. constexpr
  121. basic_string_view(const _CharT* __str, size_type __len) noexcept
  122. : _M_len{__len}, _M_str{__str}
  123. { }
  124. #if __cplusplus >= 202002L && __cpp_lib_concepts
  125. template<contiguous_iterator _It, sized_sentinel_for<_It> _End>
  126. requires same_as<iter_value_t<_It>, _CharT>
  127. && (!convertible_to<_End, size_type>)
  128. constexpr
  129. basic_string_view(_It __first, _End __last)
  130. noexcept(noexcept(__last - __first))
  131. : _M_len(__last - __first), _M_str(std::to_address(__first))
  132. { }
  133. #if __cplusplus > 202002L
  134. template<typename _Range, typename _DRange = remove_cvref_t<_Range>>
  135. requires (!is_same_v<_DRange, basic_string_view>)
  136. && ranges::contiguous_range<_Range>
  137. && ranges::sized_range<_Range>
  138. && is_same_v<ranges::range_value_t<_Range>, _CharT>
  139. && (!is_convertible_v<_Range, const _CharT*>)
  140. && (!requires (_DRange& __d) {
  141. __d.operator ::std::basic_string_view<_CharT, _Traits>();
  142. })
  143. constexpr explicit
  144. basic_string_view(_Range&& __r)
  145. noexcept(noexcept(ranges::size(__r)) && noexcept(ranges::data(__r)))
  146. : _M_len(ranges::size(__r)), _M_str(ranges::data(__r))
  147. { }
  148. basic_string_view(nullptr_t) = delete;
  149. #endif // C++23
  150. #endif // C++20
  151. constexpr basic_string_view&
  152. operator=(const basic_string_view&) noexcept = default;
  153. // [string.view.iterators], iterator support
  154. [[nodiscard]]
  155. constexpr const_iterator
  156. begin() const noexcept
  157. { return this->_M_str; }
  158. [[nodiscard]]
  159. constexpr const_iterator
  160. end() const noexcept
  161. { return this->_M_str + this->_M_len; }
  162. [[nodiscard]]
  163. constexpr const_iterator
  164. cbegin() const noexcept
  165. { return this->_M_str; }
  166. [[nodiscard]]
  167. constexpr const_iterator
  168. cend() const noexcept
  169. { return this->_M_str + this->_M_len; }
  170. [[nodiscard]]
  171. constexpr const_reverse_iterator
  172. rbegin() const noexcept
  173. { return const_reverse_iterator(this->end()); }
  174. [[nodiscard]]
  175. constexpr const_reverse_iterator
  176. rend() const noexcept
  177. { return const_reverse_iterator(this->begin()); }
  178. [[nodiscard]]
  179. constexpr const_reverse_iterator
  180. crbegin() const noexcept
  181. { return const_reverse_iterator(this->end()); }
  182. [[nodiscard]]
  183. constexpr const_reverse_iterator
  184. crend() const noexcept
  185. { return const_reverse_iterator(this->begin()); }
  186. // [string.view.capacity], capacity
  187. [[nodiscard]]
  188. constexpr size_type
  189. size() const noexcept
  190. { return this->_M_len; }
  191. [[nodiscard]]
  192. constexpr size_type
  193. length() const noexcept
  194. { return _M_len; }
  195. [[nodiscard]]
  196. constexpr size_type
  197. max_size() const noexcept
  198. {
  199. return (npos - sizeof(size_type) - sizeof(void*))
  200. / sizeof(value_type) / 4;
  201. }
  202. [[nodiscard]]
  203. constexpr bool
  204. empty() const noexcept
  205. { return this->_M_len == 0; }
  206. // [string.view.access], element access
  207. [[nodiscard]]
  208. constexpr const_reference
  209. operator[](size_type __pos) const noexcept
  210. {
  211. __glibcxx_assert(__pos < this->_M_len);
  212. return *(this->_M_str + __pos);
  213. }
  214. [[nodiscard]]
  215. constexpr const_reference
  216. at(size_type __pos) const
  217. {
  218. if (__pos >= _M_len)
  219. __throw_out_of_range_fmt(__N("basic_string_view::at: __pos "
  220. "(which is %zu) >= this->size() "
  221. "(which is %zu)"), __pos, this->size());
  222. return *(this->_M_str + __pos);
  223. }
  224. [[nodiscard]]
  225. constexpr const_reference
  226. front() const noexcept
  227. {
  228. __glibcxx_assert(this->_M_len > 0);
  229. return *this->_M_str;
  230. }
  231. [[nodiscard]]
  232. constexpr const_reference
  233. back() const noexcept
  234. {
  235. __glibcxx_assert(this->_M_len > 0);
  236. return *(this->_M_str + this->_M_len - 1);
  237. }
  238. [[nodiscard]]
  239. constexpr const_pointer
  240. data() const noexcept
  241. { return this->_M_str; }
  242. // [string.view.modifiers], modifiers:
  243. constexpr void
  244. remove_prefix(size_type __n) noexcept
  245. {
  246. __glibcxx_assert(this->_M_len >= __n);
  247. this->_M_str += __n;
  248. this->_M_len -= __n;
  249. }
  250. constexpr void
  251. remove_suffix(size_type __n) noexcept
  252. {
  253. __glibcxx_assert(this->_M_len >= __n);
  254. this->_M_len -= __n;
  255. }
  256. constexpr void
  257. swap(basic_string_view& __sv) noexcept
  258. {
  259. auto __tmp = *this;
  260. *this = __sv;
  261. __sv = __tmp;
  262. }
  263. // [string.view.ops], string operations:
  264. _GLIBCXX20_CONSTEXPR
  265. size_type
  266. copy(_CharT* __str, size_type __n, size_type __pos = 0) const
  267. {
  268. __glibcxx_requires_string_len(__str, __n);
  269. __pos = std::__sv_check(size(), __pos, "basic_string_view::copy");
  270. const size_type __rlen = std::min<size_t>(__n, _M_len - __pos);
  271. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  272. // 2777. basic_string_view::copy should use char_traits::copy
  273. traits_type::copy(__str, data() + __pos, __rlen);
  274. return __rlen;
  275. }
  276. [[nodiscard]]
  277. constexpr basic_string_view
  278. substr(size_type __pos = 0, size_type __n = npos) const noexcept(false)
  279. {
  280. __pos = std::__sv_check(size(), __pos, "basic_string_view::substr");
  281. const size_type __rlen = std::min<size_t>(__n, _M_len - __pos);
  282. return basic_string_view{_M_str + __pos, __rlen};
  283. }
  284. [[nodiscard]]
  285. constexpr int
  286. compare(basic_string_view __str) const noexcept
  287. {
  288. const size_type __rlen = std::min(this->_M_len, __str._M_len);
  289. int __ret = traits_type::compare(this->_M_str, __str._M_str, __rlen);
  290. if (__ret == 0)
  291. __ret = _S_compare(this->_M_len, __str._M_len);
  292. return __ret;
  293. }
  294. [[nodiscard]]
  295. constexpr int
  296. compare(size_type __pos1, size_type __n1, basic_string_view __str) const
  297. { return this->substr(__pos1, __n1).compare(__str); }
  298. [[nodiscard]]
  299. constexpr int
  300. compare(size_type __pos1, size_type __n1,
  301. basic_string_view __str, size_type __pos2, size_type __n2) const
  302. {
  303. return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2));
  304. }
  305. [[nodiscard, __gnu__::__nonnull__]]
  306. constexpr int
  307. compare(const _CharT* __str) const noexcept
  308. { return this->compare(basic_string_view{__str}); }
  309. [[nodiscard, __gnu__::__nonnull__]]
  310. constexpr int
  311. compare(size_type __pos1, size_type __n1, const _CharT* __str) const
  312. { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
  313. [[nodiscard]]
  314. constexpr int
  315. compare(size_type __pos1, size_type __n1,
  316. const _CharT* __str, size_type __n2) const noexcept(false)
  317. {
  318. return this->substr(__pos1, __n1)
  319. .compare(basic_string_view(__str, __n2));
  320. }
  321. #if __cplusplus > 201703L
  322. #define __cpp_lib_starts_ends_with 201711L
  323. [[nodiscard]]
  324. constexpr bool
  325. starts_with(basic_string_view __x) const noexcept
  326. { return this->substr(0, __x.size()) == __x; }
  327. [[nodiscard]]
  328. constexpr bool
  329. starts_with(_CharT __x) const noexcept
  330. { return !this->empty() && traits_type::eq(this->front(), __x); }
  331. [[nodiscard, __gnu__::__nonnull__]]
  332. constexpr bool
  333. starts_with(const _CharT* __x) const noexcept
  334. { return this->starts_with(basic_string_view(__x)); }
  335. [[nodiscard]]
  336. constexpr bool
  337. ends_with(basic_string_view __x) const noexcept
  338. {
  339. const auto __len = this->size();
  340. const auto __xlen = __x.size();
  341. return __len >= __xlen
  342. && traits_type::compare(end() - __xlen, __x.data(), __xlen) == 0;
  343. }
  344. [[nodiscard]]
  345. constexpr bool
  346. ends_with(_CharT __x) const noexcept
  347. { return !this->empty() && traits_type::eq(this->back(), __x); }
  348. [[nodiscard, __gnu__::__nonnull__]]
  349. constexpr bool
  350. ends_with(const _CharT* __x) const noexcept
  351. { return this->ends_with(basic_string_view(__x)); }
  352. #endif // C++20
  353. #if __cplusplus > 202002L
  354. #if _GLIBCXX_HOSTED
  355. // This FTM is not freestanding as it also implies matching <string>
  356. // support, and <string> is omitted from the freestanding subset.
  357. # define __cpp_lib_string_contains 202011L
  358. #endif // HOSTED
  359. [[nodiscard]]
  360. constexpr bool
  361. contains(basic_string_view __x) const noexcept
  362. { return this->find(__x) != npos; }
  363. [[nodiscard]]
  364. constexpr bool
  365. contains(_CharT __x) const noexcept
  366. { return this->find(__x) != npos; }
  367. [[nodiscard, __gnu__::__nonnull__]]
  368. constexpr bool
  369. contains(const _CharT* __x) const noexcept
  370. { return this->find(__x) != npos; }
  371. #endif // C++23
  372. // [string.view.find], searching
  373. [[nodiscard]]
  374. constexpr size_type
  375. find(basic_string_view __str, size_type __pos = 0) const noexcept
  376. { return this->find(__str._M_str, __pos, __str._M_len); }
  377. [[nodiscard]]
  378. constexpr size_type
  379. find(_CharT __c, size_type __pos = 0) const noexcept;
  380. [[nodiscard]]
  381. constexpr size_type
  382. find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
  383. [[nodiscard, __gnu__::__nonnull__]]
  384. constexpr size_type
  385. find(const _CharT* __str, size_type __pos = 0) const noexcept
  386. { return this->find(__str, __pos, traits_type::length(__str)); }
  387. [[nodiscard]]
  388. constexpr size_type
  389. rfind(basic_string_view __str, size_type __pos = npos) const noexcept
  390. { return this->rfind(__str._M_str, __pos, __str._M_len); }
  391. [[nodiscard]]
  392. constexpr size_type
  393. rfind(_CharT __c, size_type __pos = npos) const noexcept;
  394. [[nodiscard]]
  395. constexpr size_type
  396. rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
  397. [[nodiscard, __gnu__::__nonnull__]]
  398. constexpr size_type
  399. rfind(const _CharT* __str, size_type __pos = npos) const noexcept
  400. { return this->rfind(__str, __pos, traits_type::length(__str)); }
  401. [[nodiscard]]
  402. constexpr size_type
  403. find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept
  404. { return this->find_first_of(__str._M_str, __pos, __str._M_len); }
  405. [[nodiscard]]
  406. constexpr size_type
  407. find_first_of(_CharT __c, size_type __pos = 0) const noexcept
  408. { return this->find(__c, __pos); }
  409. [[nodiscard]]
  410. constexpr size_type
  411. find_first_of(const _CharT* __str, size_type __pos,
  412. size_type __n) const noexcept;
  413. [[nodiscard, __gnu__::__nonnull__]]
  414. constexpr size_type
  415. find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept
  416. { return this->find_first_of(__str, __pos, traits_type::length(__str)); }
  417. [[nodiscard]]
  418. constexpr size_type
  419. find_last_of(basic_string_view __str,
  420. size_type __pos = npos) const noexcept
  421. { return this->find_last_of(__str._M_str, __pos, __str._M_len); }
  422. [[nodiscard]]
  423. constexpr size_type
  424. find_last_of(_CharT __c, size_type __pos=npos) const noexcept
  425. { return this->rfind(__c, __pos); }
  426. [[nodiscard]]
  427. constexpr size_type
  428. find_last_of(const _CharT* __str, size_type __pos,
  429. size_type __n) const noexcept;
  430. [[nodiscard, __gnu__::__nonnull__]]
  431. constexpr size_type
  432. find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
  433. { return this->find_last_of(__str, __pos, traits_type::length(__str)); }
  434. [[nodiscard]]
  435. constexpr size_type
  436. find_first_not_of(basic_string_view __str,
  437. size_type __pos = 0) const noexcept
  438. { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); }
  439. [[nodiscard]]
  440. constexpr size_type
  441. find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept;
  442. [[nodiscard]]
  443. constexpr size_type
  444. find_first_not_of(const _CharT* __str,
  445. size_type __pos, size_type __n) const noexcept;
  446. [[nodiscard, __gnu__::__nonnull__]]
  447. constexpr size_type
  448. find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept
  449. {
  450. return this->find_first_not_of(__str, __pos,
  451. traits_type::length(__str));
  452. }
  453. [[nodiscard]]
  454. constexpr size_type
  455. find_last_not_of(basic_string_view __str,
  456. size_type __pos = npos) const noexcept
  457. { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); }
  458. [[nodiscard]]
  459. constexpr size_type
  460. find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept;
  461. [[nodiscard]]
  462. constexpr size_type
  463. find_last_not_of(const _CharT* __str,
  464. size_type __pos, size_type __n) const noexcept;
  465. [[nodiscard, __gnu__::__nonnull__]]
  466. constexpr size_type
  467. find_last_not_of(const _CharT* __str,
  468. size_type __pos = npos) const noexcept
  469. {
  470. return this->find_last_not_of(__str, __pos,
  471. traits_type::length(__str));
  472. }
  473. private:
  474. static constexpr int
  475. _S_compare(size_type __n1, size_type __n2) noexcept
  476. {
  477. using __limits = __gnu_cxx::__int_traits<int>;
  478. const difference_type __diff = __n1 - __n2;
  479. if (__diff > __limits::__max)
  480. return __limits::__max;
  481. if (__diff < __limits::__min)
  482. return __limits::__min;
  483. return static_cast<int>(__diff);
  484. }
  485. size_t _M_len;
  486. const _CharT* _M_str;
  487. };
  488. #if __cplusplus > 201703L && __cpp_lib_concepts && __cpp_deduction_guides
  489. template<contiguous_iterator _It, sized_sentinel_for<_It> _End>
  490. basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>;
  491. #if __cplusplus > 202002L
  492. template<ranges::contiguous_range _Range>
  493. basic_string_view(_Range&&)
  494. -> basic_string_view<ranges::range_value_t<_Range>>;
  495. #endif
  496. #endif
  497. // [string.view.comparison], non-member basic_string_view comparison function
  498. // Several of these functions use type_identity_t to create a non-deduced
  499. // context, so that only one argument participates in template argument
  500. // deduction and the other argument gets implicitly converted to the deduced
  501. // type (see N3766).
  502. template<typename _CharT, typename _Traits>
  503. [[nodiscard]]
  504. constexpr bool
  505. operator==(basic_string_view<_CharT, _Traits> __x,
  506. basic_string_view<_CharT, _Traits> __y) noexcept
  507. { return __x.size() == __y.size() && __x.compare(__y) == 0; }
  508. template<typename _CharT, typename _Traits>
  509. [[nodiscard]]
  510. constexpr bool
  511. operator==(basic_string_view<_CharT, _Traits> __x,
  512. __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
  513. noexcept
  514. { return __x.size() == __y.size() && __x.compare(__y) == 0; }
  515. #if __cpp_lib_three_way_comparison
  516. template<typename _CharT, typename _Traits>
  517. [[nodiscard]]
  518. constexpr auto
  519. operator<=>(basic_string_view<_CharT, _Traits> __x,
  520. basic_string_view<_CharT, _Traits> __y) noexcept
  521. -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
  522. { return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); }
  523. template<typename _CharT, typename _Traits>
  524. [[nodiscard]]
  525. constexpr auto
  526. operator<=>(basic_string_view<_CharT, _Traits> __x,
  527. __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
  528. noexcept
  529. -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
  530. { return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); }
  531. #else
  532. template<typename _CharT, typename _Traits>
  533. [[nodiscard]]
  534. constexpr bool
  535. operator==(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
  536. basic_string_view<_CharT, _Traits> __y) noexcept
  537. { return __x.size() == __y.size() && __x.compare(__y) == 0; }
  538. template<typename _CharT, typename _Traits>
  539. [[nodiscard]]
  540. constexpr bool
  541. operator!=(basic_string_view<_CharT, _Traits> __x,
  542. basic_string_view<_CharT, _Traits> __y) noexcept
  543. { return !(__x == __y); }
  544. template<typename _CharT, typename _Traits>
  545. [[nodiscard]]
  546. constexpr bool
  547. operator!=(basic_string_view<_CharT, _Traits> __x,
  548. __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
  549. noexcept
  550. { return !(__x == __y); }
  551. template<typename _CharT, typename _Traits>
  552. [[nodiscard]]
  553. constexpr bool
  554. operator!=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
  555. basic_string_view<_CharT, _Traits> __y) noexcept
  556. { return !(__x == __y); }
  557. template<typename _CharT, typename _Traits>
  558. [[nodiscard]]
  559. constexpr bool
  560. operator< (basic_string_view<_CharT, _Traits> __x,
  561. basic_string_view<_CharT, _Traits> __y) noexcept
  562. { return __x.compare(__y) < 0; }
  563. template<typename _CharT, typename _Traits>
  564. [[nodiscard]]
  565. constexpr bool
  566. operator< (basic_string_view<_CharT, _Traits> __x,
  567. __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
  568. noexcept
  569. { return __x.compare(__y) < 0; }
  570. template<typename _CharT, typename _Traits>
  571. [[nodiscard]]
  572. constexpr bool
  573. operator< (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
  574. basic_string_view<_CharT, _Traits> __y) noexcept
  575. { return __x.compare(__y) < 0; }
  576. template<typename _CharT, typename _Traits>
  577. [[nodiscard]]
  578. constexpr bool
  579. operator> (basic_string_view<_CharT, _Traits> __x,
  580. basic_string_view<_CharT, _Traits> __y) noexcept
  581. { return __x.compare(__y) > 0; }
  582. template<typename _CharT, typename _Traits>
  583. [[nodiscard]]
  584. constexpr bool
  585. operator> (basic_string_view<_CharT, _Traits> __x,
  586. __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
  587. noexcept
  588. { return __x.compare(__y) > 0; }
  589. template<typename _CharT, typename _Traits>
  590. [[nodiscard]]
  591. constexpr bool
  592. operator> (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
  593. basic_string_view<_CharT, _Traits> __y) noexcept
  594. { return __x.compare(__y) > 0; }
  595. template<typename _CharT, typename _Traits>
  596. [[nodiscard]]
  597. constexpr bool
  598. operator<=(basic_string_view<_CharT, _Traits> __x,
  599. basic_string_view<_CharT, _Traits> __y) noexcept
  600. { return __x.compare(__y) <= 0; }
  601. template<typename _CharT, typename _Traits>
  602. [[nodiscard]]
  603. constexpr bool
  604. operator<=(basic_string_view<_CharT, _Traits> __x,
  605. __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
  606. noexcept
  607. { return __x.compare(__y) <= 0; }
  608. template<typename _CharT, typename _Traits>
  609. [[nodiscard]]
  610. constexpr bool
  611. operator<=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
  612. basic_string_view<_CharT, _Traits> __y) noexcept
  613. { return __x.compare(__y) <= 0; }
  614. template<typename _CharT, typename _Traits>
  615. [[nodiscard]]
  616. constexpr bool
  617. operator>=(basic_string_view<_CharT, _Traits> __x,
  618. basic_string_view<_CharT, _Traits> __y) noexcept
  619. { return __x.compare(__y) >= 0; }
  620. template<typename _CharT, typename _Traits>
  621. [[nodiscard]]
  622. constexpr bool
  623. operator>=(basic_string_view<_CharT, _Traits> __x,
  624. __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
  625. noexcept
  626. { return __x.compare(__y) >= 0; }
  627. template<typename _CharT, typename _Traits>
  628. [[nodiscard]]
  629. constexpr bool
  630. operator>=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
  631. basic_string_view<_CharT, _Traits> __y) noexcept
  632. { return __x.compare(__y) >= 0; }
  633. #endif // three-way comparison
  634. #if _GLIBCXX_HOSTED
  635. // [string.view.io], Inserters and extractors
  636. template<typename _CharT, typename _Traits>
  637. inline basic_ostream<_CharT, _Traits>&
  638. operator<<(basic_ostream<_CharT, _Traits>& __os,
  639. basic_string_view<_CharT,_Traits> __str)
  640. { return __ostream_insert(__os, __str.data(), __str.size()); }
  641. #endif // HOSTED
  642. // basic_string_view typedef names
  643. using string_view = basic_string_view<char>;
  644. using wstring_view = basic_string_view<wchar_t>;
  645. #ifdef _GLIBCXX_USE_CHAR8_T
  646. using u8string_view = basic_string_view<char8_t>;
  647. #endif
  648. using u16string_view = basic_string_view<char16_t>;
  649. using u32string_view = basic_string_view<char32_t>;
  650. // [string.view.hash], hash support:
  651. template<typename _Tp>
  652. struct hash;
  653. template<>
  654. struct hash<string_view>
  655. : public __hash_base<size_t, string_view>
  656. {
  657. [[nodiscard]]
  658. size_t
  659. operator()(const string_view& __str) const noexcept
  660. { return std::_Hash_impl::hash(__str.data(), __str.length()); }
  661. };
  662. template<>
  663. struct __is_fast_hash<hash<string_view>> : std::false_type
  664. { };
  665. template<>
  666. struct hash<wstring_view>
  667. : public __hash_base<size_t, wstring_view>
  668. {
  669. [[nodiscard]]
  670. size_t
  671. operator()(const wstring_view& __s) const noexcept
  672. { return std::_Hash_impl::hash(__s.data(),
  673. __s.length() * sizeof(wchar_t)); }
  674. };
  675. template<>
  676. struct __is_fast_hash<hash<wstring_view>> : std::false_type
  677. { };
  678. #ifdef _GLIBCXX_USE_CHAR8_T
  679. template<>
  680. struct hash<u8string_view>
  681. : public __hash_base<size_t, u8string_view>
  682. {
  683. [[nodiscard]]
  684. size_t
  685. operator()(const u8string_view& __str) const noexcept
  686. { return std::_Hash_impl::hash(__str.data(), __str.length()); }
  687. };
  688. template<>
  689. struct __is_fast_hash<hash<u8string_view>> : std::false_type
  690. { };
  691. #endif
  692. template<>
  693. struct hash<u16string_view>
  694. : public __hash_base<size_t, u16string_view>
  695. {
  696. [[nodiscard]]
  697. size_t
  698. operator()(const u16string_view& __s) const noexcept
  699. { return std::_Hash_impl::hash(__s.data(),
  700. __s.length() * sizeof(char16_t)); }
  701. };
  702. template<>
  703. struct __is_fast_hash<hash<u16string_view>> : std::false_type
  704. { };
  705. template<>
  706. struct hash<u32string_view>
  707. : public __hash_base<size_t, u32string_view>
  708. {
  709. [[nodiscard]]
  710. size_t
  711. operator()(const u32string_view& __s) const noexcept
  712. { return std::_Hash_impl::hash(__s.data(),
  713. __s.length() * sizeof(char32_t)); }
  714. };
  715. template<>
  716. struct __is_fast_hash<hash<u32string_view>> : std::false_type
  717. { };
  718. inline namespace literals
  719. {
  720. inline namespace string_view_literals
  721. {
  722. #pragma GCC diagnostic push
  723. #pragma GCC diagnostic ignored "-Wliteral-suffix"
  724. inline constexpr basic_string_view<char>
  725. operator""sv(const char* __str, size_t __len) noexcept
  726. { return basic_string_view<char>{__str, __len}; }
  727. inline constexpr basic_string_view<wchar_t>
  728. operator""sv(const wchar_t* __str, size_t __len) noexcept
  729. { return basic_string_view<wchar_t>{__str, __len}; }
  730. #ifdef _GLIBCXX_USE_CHAR8_T
  731. inline constexpr basic_string_view<char8_t>
  732. operator""sv(const char8_t* __str, size_t __len) noexcept
  733. { return basic_string_view<char8_t>{__str, __len}; }
  734. #endif
  735. inline constexpr basic_string_view<char16_t>
  736. operator""sv(const char16_t* __str, size_t __len) noexcept
  737. { return basic_string_view<char16_t>{__str, __len}; }
  738. inline constexpr basic_string_view<char32_t>
  739. operator""sv(const char32_t* __str, size_t __len) noexcept
  740. { return basic_string_view<char32_t>{__str, __len}; }
  741. #pragma GCC diagnostic pop
  742. } // namespace string_literals
  743. } // namespace literals
  744. #if __cpp_lib_concepts
  745. namespace ranges
  746. {
  747. // Opt-in to borrowed_range concept
  748. template<typename _CharT, typename _Traits>
  749. inline constexpr bool
  750. enable_borrowed_range<basic_string_view<_CharT, _Traits>> = true;
  751. // Opt-in to view concept
  752. template<typename _CharT, typename _Traits>
  753. inline constexpr bool
  754. enable_view<basic_string_view<_CharT, _Traits>> = true;
  755. }
  756. #endif
  757. _GLIBCXX_END_NAMESPACE_VERSION
  758. } // namespace std
  759. #include <bits/string_view.tcc>
  760. #endif // __cplusplus <= 201402L
  761. #endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW