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