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