string_view 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  1. // Components for manipulating non-owning sequences of characters -*- C++ -*-
  2. // Copyright (C) 2013-2020 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 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 <iosfwd>
  31. #include <bits/char_traits.h>
  32. #include <bits/functional_hash.h>
  33. #include <bits/int_limits.h>
  34. #include <bits/range_access.h>
  35. #include <bits/ostream_insert.h>
  36. namespace std _GLIBCXX_VISIBILITY(default)
  37. {
  38. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  39. # define __cpp_lib_string_view 201803L
  40. #if __cplusplus > 201703L
  41. # define __cpp_lib_constexpr_string_view 201811L
  42. #endif
  43. // Helper for basic_string and basic_string_view members.
  44. constexpr size_t
  45. __sv_check(size_t __size, size_t __pos, const char* __s)
  46. {
  47. if (__pos > __size)
  48. __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > __size "
  49. "(which is %zu)"), __s, __pos, __size);
  50. return __pos;
  51. }
  52. // Helper for basic_string members.
  53. // NB: __sv_limit doesn't check for a bad __pos value.
  54. constexpr size_t
  55. __sv_limit(size_t __size, size_t __pos, size_t __off) noexcept
  56. {
  57. const bool __testoff = __off < __size - __pos;
  58. return __testoff ? __off : __size - __pos;
  59. }
  60. /**
  61. * @class basic_string_view <string_view>
  62. * @brief A non-owning reference to a string.
  63. *
  64. * @ingroup strings
  65. * @ingroup sequences
  66. *
  67. * @tparam _CharT Type of character
  68. * @tparam _Traits Traits for character type, defaults to
  69. * char_traits<_CharT>.
  70. *
  71. * A basic_string_view looks like this:
  72. *
  73. * @code
  74. * _CharT* _M_str
  75. * size_t _M_len
  76. * @endcode
  77. */
  78. template<typename _CharT, typename _Traits = std::char_traits<_CharT>>
  79. class basic_string_view
  80. {
  81. static_assert(!is_array_v<_CharT>);
  82. static_assert(is_trivial_v<_CharT> && is_standard_layout_v<_CharT>);
  83. static_assert(is_same_v<_CharT, typename _Traits::char_type>);
  84. public:
  85. // types
  86. using traits_type = _Traits;
  87. using value_type = _CharT;
  88. using pointer = value_type*;
  89. using const_pointer = const value_type*;
  90. using reference = value_type&;
  91. using const_reference = const value_type&;
  92. using const_iterator = const value_type*;
  93. using iterator = const_iterator;
  94. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  95. using reverse_iterator = const_reverse_iterator;
  96. using size_type = size_t;
  97. using difference_type = ptrdiff_t;
  98. static constexpr size_type npos = size_type(-1);
  99. // [string.view.cons], construction and assignment
  100. constexpr
  101. basic_string_view() noexcept
  102. : _M_len{0}, _M_str{nullptr}
  103. { }
  104. constexpr basic_string_view(const basic_string_view&) noexcept = default;
  105. __attribute__((__nonnull__)) constexpr
  106. basic_string_view(const _CharT* __str) noexcept
  107. : _M_len{traits_type::length(__str)},
  108. _M_str{__str}
  109. { }
  110. constexpr
  111. basic_string_view(const _CharT* __str, size_type __len) noexcept
  112. : _M_len{__len}, _M_str{__str}
  113. { }
  114. #if __cplusplus > 201703L && __cpp_lib_concepts
  115. template<contiguous_iterator _It, sized_sentinel_for<_It> _End>
  116. requires same_as<iter_value_t<_It>, _CharT>
  117. && (!convertible_to<_End, size_type>)
  118. constexpr
  119. basic_string_view(_It __first, _End __last)
  120. : _M_len(__last - __first), _M_str(std::to_address(__first))
  121. { }
  122. #endif
  123. constexpr basic_string_view&
  124. operator=(const basic_string_view&) noexcept = default;
  125. // [string.view.iterators], iterator support
  126. constexpr const_iterator
  127. begin() const noexcept
  128. { return this->_M_str; }
  129. constexpr const_iterator
  130. end() const noexcept
  131. { return this->_M_str + this->_M_len; }
  132. constexpr const_iterator
  133. cbegin() const noexcept
  134. { return this->_M_str; }
  135. constexpr const_iterator
  136. cend() const noexcept
  137. { return this->_M_str + this->_M_len; }
  138. constexpr const_reverse_iterator
  139. rbegin() const noexcept
  140. { return const_reverse_iterator(this->end()); }
  141. constexpr const_reverse_iterator
  142. rend() const noexcept
  143. { return const_reverse_iterator(this->begin()); }
  144. constexpr const_reverse_iterator
  145. crbegin() const noexcept
  146. { return const_reverse_iterator(this->end()); }
  147. constexpr const_reverse_iterator
  148. crend() const noexcept
  149. { return const_reverse_iterator(this->begin()); }
  150. // [string.view.capacity], capacity
  151. constexpr size_type
  152. size() const noexcept
  153. { return this->_M_len; }
  154. constexpr size_type
  155. length() const noexcept
  156. { return _M_len; }
  157. constexpr size_type
  158. max_size() const noexcept
  159. {
  160. return (npos - sizeof(size_type) - sizeof(void*))
  161. / sizeof(value_type) / 4;
  162. }
  163. [[nodiscard]] constexpr bool
  164. empty() const noexcept
  165. { return this->_M_len == 0; }
  166. // [string.view.access], element access
  167. constexpr const_reference
  168. operator[](size_type __pos) const noexcept
  169. {
  170. // TODO: Assert to restore in a way compatible with the constexpr.
  171. // __glibcxx_assert(__pos < this->_M_len);
  172. return *(this->_M_str + __pos);
  173. }
  174. constexpr const_reference
  175. at(size_type __pos) const
  176. {
  177. if (__pos >= _M_len)
  178. __throw_out_of_range_fmt(__N("basic_string_view::at: __pos "
  179. "(which is %zu) >= this->size() "
  180. "(which is %zu)"), __pos, this->size());
  181. return *(this->_M_str + __pos);
  182. }
  183. constexpr const_reference
  184. front() const noexcept
  185. {
  186. // TODO: Assert to restore in a way compatible with the constexpr.
  187. // __glibcxx_assert(this->_M_len > 0);
  188. return *this->_M_str;
  189. }
  190. constexpr const_reference
  191. back() const noexcept
  192. {
  193. // TODO: Assert to restore in a way compatible with the constexpr.
  194. // __glibcxx_assert(this->_M_len > 0);
  195. return *(this->_M_str + this->_M_len - 1);
  196. }
  197. constexpr const_pointer
  198. data() const noexcept
  199. { return this->_M_str; }
  200. // [string.view.modifiers], modifiers:
  201. constexpr void
  202. remove_prefix(size_type __n) noexcept
  203. {
  204. __glibcxx_assert(this->_M_len >= __n);
  205. this->_M_str += __n;
  206. this->_M_len -= __n;
  207. }
  208. constexpr void
  209. remove_suffix(size_type __n) noexcept
  210. { this->_M_len -= __n; }
  211. constexpr void
  212. swap(basic_string_view& __sv) noexcept
  213. {
  214. auto __tmp = *this;
  215. *this = __sv;
  216. __sv = __tmp;
  217. }
  218. // [string.view.ops], string operations:
  219. _GLIBCXX20_CONSTEXPR
  220. size_type
  221. copy(_CharT* __str, size_type __n, size_type __pos = 0) const
  222. {
  223. __glibcxx_requires_string_len(__str, __n);
  224. __pos = std::__sv_check(size(), __pos, "basic_string_view::copy");
  225. const size_type __rlen = std::min(__n, _M_len - __pos);
  226. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  227. // 2777. basic_string_view::copy should use char_traits::copy
  228. traits_type::copy(__str, data() + __pos, __rlen);
  229. return __rlen;
  230. }
  231. constexpr basic_string_view
  232. substr(size_type __pos = 0, size_type __n = npos) const noexcept(false)
  233. {
  234. __pos = std::__sv_check(size(), __pos, "basic_string_view::substr");
  235. const size_type __rlen = std::min(__n, _M_len - __pos);
  236. return basic_string_view{_M_str + __pos, __rlen};
  237. }
  238. constexpr int
  239. compare(basic_string_view __str) const noexcept
  240. {
  241. const size_type __rlen = std::min(this->_M_len, __str._M_len);
  242. int __ret = traits_type::compare(this->_M_str, __str._M_str, __rlen);
  243. if (__ret == 0)
  244. __ret = _S_compare(this->_M_len, __str._M_len);
  245. return __ret;
  246. }
  247. constexpr int
  248. compare(size_type __pos1, size_type __n1, basic_string_view __str) const
  249. { return this->substr(__pos1, __n1).compare(__str); }
  250. constexpr int
  251. compare(size_type __pos1, size_type __n1,
  252. basic_string_view __str, size_type __pos2, size_type __n2) const
  253. {
  254. return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2));
  255. }
  256. __attribute__((__nonnull__)) constexpr int
  257. compare(const _CharT* __str) const noexcept
  258. { return this->compare(basic_string_view{__str}); }
  259. __attribute__((__nonnull__)) constexpr int
  260. compare(size_type __pos1, size_type __n1, const _CharT* __str) const
  261. { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
  262. constexpr int
  263. compare(size_type __pos1, size_type __n1,
  264. const _CharT* __str, size_type __n2) const noexcept(false)
  265. {
  266. return this->substr(__pos1, __n1)
  267. .compare(basic_string_view(__str, __n2));
  268. }
  269. #if __cplusplus > 201703L
  270. #define __cpp_lib_starts_ends_with 201711L
  271. constexpr bool
  272. starts_with(basic_string_view __x) const noexcept
  273. { return this->substr(0, __x.size()) == __x; }
  274. constexpr bool
  275. starts_with(_CharT __x) const noexcept
  276. { return !this->empty() && traits_type::eq(this->front(), __x); }
  277. constexpr bool
  278. starts_with(const _CharT* __x) const noexcept
  279. { return this->starts_with(basic_string_view(__x)); }
  280. constexpr bool
  281. ends_with(basic_string_view __x) const noexcept
  282. {
  283. return this->size() >= __x.size()
  284. && this->compare(this->size() - __x.size(), npos, __x) == 0;
  285. }
  286. constexpr bool
  287. ends_with(_CharT __x) const noexcept
  288. { return !this->empty() && traits_type::eq(this->back(), __x); }
  289. constexpr bool
  290. ends_with(const _CharT* __x) const noexcept
  291. { return this->ends_with(basic_string_view(__x)); }
  292. #endif // C++20
  293. // [string.view.find], searching
  294. constexpr size_type
  295. find(basic_string_view __str, size_type __pos = 0) const noexcept
  296. { return this->find(__str._M_str, __pos, __str._M_len); }
  297. constexpr size_type
  298. find(_CharT __c, size_type __pos = 0) const noexcept;
  299. constexpr size_type
  300. find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
  301. __attribute__((__nonnull__)) constexpr size_type
  302. find(const _CharT* __str, size_type __pos = 0) const noexcept
  303. { return this->find(__str, __pos, traits_type::length(__str)); }
  304. constexpr size_type
  305. rfind(basic_string_view __str, size_type __pos = npos) const noexcept
  306. { return this->rfind(__str._M_str, __pos, __str._M_len); }
  307. constexpr size_type
  308. rfind(_CharT __c, size_type __pos = npos) const noexcept;
  309. constexpr size_type
  310. rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
  311. __attribute__((__nonnull__)) constexpr size_type
  312. rfind(const _CharT* __str, size_type __pos = npos) const noexcept
  313. { return this->rfind(__str, __pos, traits_type::length(__str)); }
  314. constexpr size_type
  315. find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept
  316. { return this->find_first_of(__str._M_str, __pos, __str._M_len); }
  317. constexpr size_type
  318. find_first_of(_CharT __c, size_type __pos = 0) const noexcept
  319. { return this->find(__c, __pos); }
  320. constexpr size_type
  321. find_first_of(const _CharT* __str, size_type __pos,
  322. size_type __n) const noexcept;
  323. __attribute__((__nonnull__)) constexpr size_type
  324. find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept
  325. { return this->find_first_of(__str, __pos, traits_type::length(__str)); }
  326. constexpr size_type
  327. find_last_of(basic_string_view __str,
  328. size_type __pos = npos) const noexcept
  329. { return this->find_last_of(__str._M_str, __pos, __str._M_len); }
  330. constexpr size_type
  331. find_last_of(_CharT __c, size_type __pos=npos) const noexcept
  332. { return this->rfind(__c, __pos); }
  333. constexpr size_type
  334. find_last_of(const _CharT* __str, size_type __pos,
  335. size_type __n) const noexcept;
  336. __attribute__((__nonnull__)) constexpr size_type
  337. find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
  338. { return this->find_last_of(__str, __pos, traits_type::length(__str)); }
  339. constexpr size_type
  340. find_first_not_of(basic_string_view __str,
  341. size_type __pos = 0) const noexcept
  342. { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); }
  343. constexpr size_type
  344. find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept;
  345. constexpr size_type
  346. find_first_not_of(const _CharT* __str,
  347. size_type __pos, size_type __n) const noexcept;
  348. __attribute__((__nonnull__)) constexpr size_type
  349. find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept
  350. {
  351. return this->find_first_not_of(__str, __pos,
  352. traits_type::length(__str));
  353. }
  354. constexpr size_type
  355. find_last_not_of(basic_string_view __str,
  356. size_type __pos = npos) const noexcept
  357. { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); }
  358. constexpr size_type
  359. find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept;
  360. constexpr size_type
  361. find_last_not_of(const _CharT* __str,
  362. size_type __pos, size_type __n) const noexcept;
  363. __attribute__((__nonnull__)) constexpr size_type
  364. find_last_not_of(const _CharT* __str,
  365. size_type __pos = npos) const noexcept
  366. {
  367. return this->find_last_not_of(__str, __pos,
  368. traits_type::length(__str));
  369. }
  370. private:
  371. static constexpr int
  372. _S_compare(size_type __n1, size_type __n2) noexcept
  373. {
  374. const difference_type __diff = __n1 - __n2;
  375. if (__diff > __detail::__int_limits<int>::max())
  376. return __detail::__int_limits<int>::max();
  377. if (__diff < __detail::__int_limits<int>::min())
  378. return __detail::__int_limits<int>::min();
  379. return static_cast<int>(__diff);
  380. }
  381. size_t _M_len;
  382. const _CharT* _M_str;
  383. };
  384. #if __cplusplus > 201703L && __cpp_lib_concepts && __cpp_deduction_guides
  385. template<contiguous_iterator _It, sized_sentinel_for<_It> _End>
  386. basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>;
  387. #endif
  388. // [string.view.comparison], non-member basic_string_view comparison function
  389. // Several of these functions use type_identity_t to create a non-deduced
  390. // context, so that only one argument participates in template argument
  391. // deduction and the other argument gets implicitly converted to the deduced
  392. // type (see N3766).
  393. template<typename _CharT, typename _Traits>
  394. constexpr bool
  395. operator==(basic_string_view<_CharT, _Traits> __x,
  396. basic_string_view<_CharT, _Traits> __y) noexcept
  397. { return __x.size() == __y.size() && __x.compare(__y) == 0; }
  398. template<typename _CharT, typename _Traits>
  399. constexpr bool
  400. operator==(basic_string_view<_CharT, _Traits> __x,
  401. __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
  402. noexcept
  403. { return __x.size() == __y.size() && __x.compare(__y) == 0; }
  404. #if __cpp_lib_three_way_comparison
  405. template<typename _CharT, typename _Traits>
  406. constexpr auto
  407. operator<=>(basic_string_view<_CharT, _Traits> __x,
  408. basic_string_view<_CharT, _Traits> __y) noexcept
  409. -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
  410. { return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); }
  411. template<typename _CharT, typename _Traits>
  412. constexpr auto
  413. operator<=>(basic_string_view<_CharT, _Traits> __x,
  414. __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
  415. noexcept
  416. -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
  417. { return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); }
  418. #else
  419. template<typename _CharT, typename _Traits>
  420. constexpr bool
  421. operator==(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
  422. basic_string_view<_CharT, _Traits> __y) noexcept
  423. { return __x.size() == __y.size() && __x.compare(__y) == 0; }
  424. template<typename _CharT, typename _Traits>
  425. constexpr bool
  426. operator!=(basic_string_view<_CharT, _Traits> __x,
  427. basic_string_view<_CharT, _Traits> __y) noexcept
  428. { return !(__x == __y); }
  429. template<typename _CharT, typename _Traits>
  430. constexpr bool
  431. operator!=(basic_string_view<_CharT, _Traits> __x,
  432. __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
  433. noexcept
  434. { return !(__x == __y); }
  435. template<typename _CharT, typename _Traits>
  436. constexpr bool
  437. operator!=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
  438. basic_string_view<_CharT, _Traits> __y) noexcept
  439. { return !(__x == __y); }
  440. template<typename _CharT, typename _Traits>
  441. constexpr bool
  442. operator< (basic_string_view<_CharT, _Traits> __x,
  443. basic_string_view<_CharT, _Traits> __y) noexcept
  444. { return __x.compare(__y) < 0; }
  445. template<typename _CharT, typename _Traits>
  446. constexpr bool
  447. operator< (basic_string_view<_CharT, _Traits> __x,
  448. __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
  449. noexcept
  450. { return __x.compare(__y) < 0; }
  451. template<typename _CharT, typename _Traits>
  452. constexpr bool
  453. operator< (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
  454. basic_string_view<_CharT, _Traits> __y) noexcept
  455. { return __x.compare(__y) < 0; }
  456. template<typename _CharT, typename _Traits>
  457. constexpr bool
  458. operator> (basic_string_view<_CharT, _Traits> __x,
  459. basic_string_view<_CharT, _Traits> __y) noexcept
  460. { return __x.compare(__y) > 0; }
  461. template<typename _CharT, typename _Traits>
  462. constexpr bool
  463. operator> (basic_string_view<_CharT, _Traits> __x,
  464. __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
  465. noexcept
  466. { return __x.compare(__y) > 0; }
  467. template<typename _CharT, typename _Traits>
  468. constexpr bool
  469. operator> (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
  470. basic_string_view<_CharT, _Traits> __y) noexcept
  471. { return __x.compare(__y) > 0; }
  472. template<typename _CharT, typename _Traits>
  473. constexpr bool
  474. operator<=(basic_string_view<_CharT, _Traits> __x,
  475. basic_string_view<_CharT, _Traits> __y) noexcept
  476. { return __x.compare(__y) <= 0; }
  477. template<typename _CharT, typename _Traits>
  478. constexpr bool
  479. operator<=(basic_string_view<_CharT, _Traits> __x,
  480. __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
  481. noexcept
  482. { return __x.compare(__y) <= 0; }
  483. template<typename _CharT, typename _Traits>
  484. constexpr bool
  485. operator<=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
  486. basic_string_view<_CharT, _Traits> __y) noexcept
  487. { return __x.compare(__y) <= 0; }
  488. template<typename _CharT, typename _Traits>
  489. constexpr bool
  490. operator>=(basic_string_view<_CharT, _Traits> __x,
  491. basic_string_view<_CharT, _Traits> __y) noexcept
  492. { return __x.compare(__y) >= 0; }
  493. template<typename _CharT, typename _Traits>
  494. constexpr bool
  495. operator>=(basic_string_view<_CharT, _Traits> __x,
  496. __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
  497. noexcept
  498. { return __x.compare(__y) >= 0; }
  499. template<typename _CharT, typename _Traits>
  500. constexpr bool
  501. operator>=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
  502. basic_string_view<_CharT, _Traits> __y) noexcept
  503. { return __x.compare(__y) >= 0; }
  504. #endif // three-way comparison
  505. // [string.view.io], Inserters and extractors
  506. template<typename _CharT, typename _Traits>
  507. inline basic_ostream<_CharT, _Traits>&
  508. operator<<(basic_ostream<_CharT, _Traits>& __os,
  509. basic_string_view<_CharT,_Traits> __str)
  510. { return __ostream_insert(__os, __str.data(), __str.size()); }
  511. // basic_string_view typedef names
  512. using string_view = basic_string_view<char>;
  513. #ifdef _GLIBCXX_USE_WCHAR_T
  514. using wstring_view = basic_string_view<wchar_t>;
  515. #endif
  516. #ifdef _GLIBCXX_USE_CHAR8_T
  517. using u8string_view = basic_string_view<char8_t>;
  518. #endif
  519. using u16string_view = basic_string_view<char16_t>;
  520. using u32string_view = basic_string_view<char32_t>;
  521. // [string.view.hash], hash support:
  522. template<typename _Tp>
  523. struct hash;
  524. template<>
  525. struct hash<string_view>
  526. : public __hash_base<size_t, string_view>
  527. {
  528. size_t
  529. operator()(const string_view& __str) const noexcept
  530. { return std::_Hash_impl::hash(__str.data(), __str.length()); }
  531. };
  532. template<>
  533. struct __is_fast_hash<hash<string_view>> : std::false_type
  534. { };
  535. #ifdef _GLIBCXX_USE_WCHAR_T
  536. template<>
  537. struct hash<wstring_view>
  538. : public __hash_base<size_t, wstring_view>
  539. {
  540. size_t
  541. operator()(const wstring_view& __s) const noexcept
  542. { return std::_Hash_impl::hash(__s.data(),
  543. __s.length() * sizeof(wchar_t)); }
  544. };
  545. template<>
  546. struct __is_fast_hash<hash<wstring_view>> : std::false_type
  547. { };
  548. #endif
  549. #ifdef _GLIBCXX_USE_CHAR8_T
  550. template<>
  551. struct hash<u8string_view>
  552. : public __hash_base<size_t, u8string_view>
  553. {
  554. size_t
  555. operator()(const u8string_view& __str) const noexcept
  556. { return std::_Hash_impl::hash(__str.data(), __str.length()); }
  557. };
  558. template<>
  559. struct __is_fast_hash<hash<u8string_view>> : std::false_type
  560. { };
  561. #endif
  562. template<>
  563. struct hash<u16string_view>
  564. : public __hash_base<size_t, u16string_view>
  565. {
  566. size_t
  567. operator()(const u16string_view& __s) const noexcept
  568. { return std::_Hash_impl::hash(__s.data(),
  569. __s.length() * sizeof(char16_t)); }
  570. };
  571. template<>
  572. struct __is_fast_hash<hash<u16string_view>> : std::false_type
  573. { };
  574. template<>
  575. struct hash<u32string_view>
  576. : public __hash_base<size_t, u32string_view>
  577. {
  578. size_t
  579. operator()(const u32string_view& __s) const noexcept
  580. { return std::_Hash_impl::hash(__s.data(),
  581. __s.length() * sizeof(char32_t)); }
  582. };
  583. template<>
  584. struct __is_fast_hash<hash<u32string_view>> : std::false_type
  585. { };
  586. inline namespace literals
  587. {
  588. inline namespace string_view_literals
  589. {
  590. #pragma GCC diagnostic push
  591. #pragma GCC diagnostic ignored "-Wliteral-suffix"
  592. inline constexpr basic_string_view<char>
  593. operator""sv(const char* __str, size_t __len) noexcept
  594. { return basic_string_view<char>{__str, __len}; }
  595. #ifdef _GLIBCXX_USE_WCHAR_T
  596. inline constexpr basic_string_view<wchar_t>
  597. operator""sv(const wchar_t* __str, size_t __len) noexcept
  598. { return basic_string_view<wchar_t>{__str, __len}; }
  599. #endif
  600. #ifdef _GLIBCXX_USE_CHAR8_T
  601. inline constexpr basic_string_view<char8_t>
  602. operator""sv(const char8_t* __str, size_t __len) noexcept
  603. { return basic_string_view<char8_t>{__str, __len}; }
  604. #endif
  605. inline constexpr basic_string_view<char16_t>
  606. operator""sv(const char16_t* __str, size_t __len) noexcept
  607. { return basic_string_view<char16_t>{__str, __len}; }
  608. inline constexpr basic_string_view<char32_t>
  609. operator""sv(const char32_t* __str, size_t __len) noexcept
  610. { return basic_string_view<char32_t>{__str, __len}; }
  611. #pragma GCC diagnostic pop
  612. } // namespace string_literals
  613. } // namespace literals
  614. #if __cpp_lib_concepts
  615. namespace ranges
  616. {
  617. // Opt-in to borrowed_range concept
  618. template<typename _CharT, typename _Traits>
  619. inline constexpr bool
  620. enable_borrowed_range<basic_string_view<_CharT, _Traits>> = true;
  621. // Opt-in to view concept
  622. template<typename _CharT, typename _Traits>
  623. inline constexpr bool
  624. enable_view<basic_string_view<_CharT, _Traits>> = true;
  625. }
  626. #endif
  627. _GLIBCXX_END_NAMESPACE_VERSION
  628. } // namespace std
  629. #include <bits/string_view.tcc>
  630. #endif // __cplusplus <= 201402L
  631. #endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW