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