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