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