string_view 22 KB

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