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