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 201603 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 constexpr bool 314 starts_with(basic_string_view __x) const noexcept 315 { return this->substr(0, __x.size()) == __x; } 316 317 constexpr bool 318 starts_with(_CharT __x) const noexcept 319 { return !this->empty() && traits_type::eq(this->front(), __x); } 320 321 constexpr bool 322 starts_with(const _CharT* __x) const noexcept 323 { return this->starts_with(basic_string_view(__x)); } 324 325 constexpr bool 326 ends_with(basic_string_view __x) const noexcept 327 { 328 return this->size() >= __x.size() 329 && this->compare(this->size() - __x.size(), npos, __x) == 0; 330 } 331 332 constexpr bool 333 ends_with(_CharT __x) const noexcept 334 { return !this->empty() && traits_type::eq(this->back(), __x); } 335 336 constexpr bool 337 ends_with(const _CharT* __x) const noexcept 338 { return this->ends_with(basic_string_view(__x)); } 339#endif // C++20 340 341 // [string.view.find], searching 342 343 constexpr size_type 344 find(basic_string_view __str, size_type __pos = 0) const noexcept 345 { return this->find(__str._M_str, __pos, __str._M_len); } 346 347 constexpr size_type 348 find(_CharT __c, size_type __pos = 0) const noexcept; 349 350 constexpr size_type 351 find(const _CharT* __str, size_type __pos, size_type __n) const noexcept; 352 353 __attribute__((__nonnull__)) constexpr size_type 354 find(const _CharT* __str, size_type __pos = 0) const noexcept 355 { return this->find(__str, __pos, traits_type::length(__str)); } 356 357 constexpr size_type 358 rfind(basic_string_view __str, size_type __pos = npos) const noexcept 359 { return this->rfind(__str._M_str, __pos, __str._M_len); } 360 361 constexpr size_type 362 rfind(_CharT __c, size_type __pos = npos) const noexcept; 363 364 constexpr size_type 365 rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept; 366 367 __attribute__((__nonnull__)) constexpr size_type 368 rfind(const _CharT* __str, size_type __pos = npos) const noexcept 369 { return this->rfind(__str, __pos, traits_type::length(__str)); } 370 371 constexpr size_type 372 find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept 373 { return this->find_first_of(__str._M_str, __pos, __str._M_len); } 374 375 constexpr size_type 376 find_first_of(_CharT __c, size_type __pos = 0) const noexcept 377 { return this->find(__c, __pos); } 378 379 constexpr size_type 380 find_first_of(const _CharT* __str, size_type __pos, 381 size_type __n) const noexcept; 382 383 __attribute__((__nonnull__)) constexpr size_type 384 find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept 385 { return this->find_first_of(__str, __pos, traits_type::length(__str)); } 386 387 constexpr size_type 388 find_last_of(basic_string_view __str, 389 size_type __pos = npos) const noexcept 390 { return this->find_last_of(__str._M_str, __pos, __str._M_len); } 391 392 constexpr size_type 393 find_last_of(_CharT __c, size_type __pos=npos) const noexcept 394 { return this->rfind(__c, __pos); } 395 396 constexpr size_type 397 find_last_of(const _CharT* __str, size_type __pos, 398 size_type __n) const noexcept; 399 400 __attribute__((__nonnull__)) constexpr size_type 401 find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept 402 { return this->find_last_of(__str, __pos, traits_type::length(__str)); } 403 404 constexpr size_type 405 find_first_not_of(basic_string_view __str, 406 size_type __pos = 0) const noexcept 407 { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); } 408 409 constexpr size_type 410 find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept; 411 412 constexpr size_type 413 find_first_not_of(const _CharT* __str, 414 size_type __pos, size_type __n) const noexcept; 415 416 __attribute__((__nonnull__)) constexpr size_type 417 find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept 418 { 419 return this->find_first_not_of(__str, __pos, 420 traits_type::length(__str)); 421 } 422 423 constexpr size_type 424 find_last_not_of(basic_string_view __str, 425 size_type __pos = npos) const noexcept 426 { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); } 427 428 constexpr size_type 429 find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept; 430 431 constexpr size_type 432 find_last_not_of(const _CharT* __str, 433 size_type __pos, size_type __n) const noexcept; 434 435 __attribute__((__nonnull__)) constexpr size_type 436 find_last_not_of(const _CharT* __str, 437 size_type __pos = npos) const noexcept 438 { 439 return this->find_last_not_of(__str, __pos, 440 traits_type::length(__str)); 441 } 442 443 private: 444 445 static constexpr int 446 _S_compare(size_type __n1, size_type __n2) noexcept 447 { 448 const difference_type __diff = __n1 - __n2; 449 if (__diff > std::numeric_limits<int>::max()) 450 return std::numeric_limits<int>::max(); 451 if (__diff < std::numeric_limits<int>::min()) 452 return std::numeric_limits<int>::min(); 453 return static_cast<int>(__diff); 454 } 455 456 size_t _M_len; 457 const _CharT* _M_str; 458 }; 459 460 // [string.view.comparison], non-member basic_string_view comparison function 461 462 namespace __detail 463 { 464 // Identity transform to create a non-deduced context, so that only one 465 // argument participates in template argument deduction and the other 466 // argument gets implicitly converted to the deduced type. See n3766.html. 467 template<typename _Tp> 468 using __idt = common_type_t<_Tp>; 469 } 470 471 template<typename _CharT, typename _Traits> 472 constexpr bool 473 operator==(basic_string_view<_CharT, _Traits> __x, 474 basic_string_view<_CharT, _Traits> __y) noexcept 475 { return __x.size() == __y.size() && __x.compare(__y) == 0; } 476 477 template<typename _CharT, typename _Traits> 478 constexpr bool 479 operator==(basic_string_view<_CharT, _Traits> __x, 480 __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept 481 { return __x.size() == __y.size() && __x.compare(__y) == 0; } 482 483 template<typename _CharT, typename _Traits> 484 constexpr bool 485 operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, 486 basic_string_view<_CharT, _Traits> __y) noexcept 487 { return __x.size() == __y.size() && __x.compare(__y) == 0; } 488 489 template<typename _CharT, typename _Traits> 490 constexpr bool 491 operator!=(basic_string_view<_CharT, _Traits> __x, 492 basic_string_view<_CharT, _Traits> __y) noexcept 493 { return !(__x == __y); } 494 495 template<typename _CharT, typename _Traits> 496 constexpr bool 497 operator!=(basic_string_view<_CharT, _Traits> __x, 498 __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept 499 { return !(__x == __y); } 500 501 template<typename _CharT, typename _Traits> 502 constexpr bool 503 operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, 504 basic_string_view<_CharT, _Traits> __y) noexcept 505 { return !(__x == __y); } 506 507 template<typename _CharT, typename _Traits> 508 constexpr bool 509 operator< (basic_string_view<_CharT, _Traits> __x, 510 basic_string_view<_CharT, _Traits> __y) noexcept 511 { return __x.compare(__y) < 0; } 512 513 template<typename _CharT, typename _Traits> 514 constexpr bool 515 operator< (basic_string_view<_CharT, _Traits> __x, 516 __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept 517 { return __x.compare(__y) < 0; } 518 519 template<typename _CharT, typename _Traits> 520 constexpr bool 521 operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x, 522 basic_string_view<_CharT, _Traits> __y) noexcept 523 { return __x.compare(__y) < 0; } 524 525 template<typename _CharT, typename _Traits> 526 constexpr bool 527 operator> (basic_string_view<_CharT, _Traits> __x, 528 basic_string_view<_CharT, _Traits> __y) noexcept 529 { return __x.compare(__y) > 0; } 530 531 template<typename _CharT, typename _Traits> 532 constexpr bool 533 operator> (basic_string_view<_CharT, _Traits> __x, 534 __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept 535 { return __x.compare(__y) > 0; } 536 537 template<typename _CharT, typename _Traits> 538 constexpr bool 539 operator> (__detail::__idt<basic_string_view<_CharT, _Traits>> __x, 540 basic_string_view<_CharT, _Traits> __y) noexcept 541 { return __x.compare(__y) > 0; } 542 543 template<typename _CharT, typename _Traits> 544 constexpr bool 545 operator<=(basic_string_view<_CharT, _Traits> __x, 546 basic_string_view<_CharT, _Traits> __y) noexcept 547 { return __x.compare(__y) <= 0; } 548 549 template<typename _CharT, typename _Traits> 550 constexpr bool 551 operator<=(basic_string_view<_CharT, _Traits> __x, 552 __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept 553 { return __x.compare(__y) <= 0; } 554 555 template<typename _CharT, typename _Traits> 556 constexpr bool 557 operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, 558 basic_string_view<_CharT, _Traits> __y) noexcept 559 { return __x.compare(__y) <= 0; } 560 561 template<typename _CharT, typename _Traits> 562 constexpr bool 563 operator>=(basic_string_view<_CharT, _Traits> __x, 564 basic_string_view<_CharT, _Traits> __y) noexcept 565 { return __x.compare(__y) >= 0; } 566 567 template<typename _CharT, typename _Traits> 568 constexpr bool 569 operator>=(basic_string_view<_CharT, _Traits> __x, 570 __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept 571 { return __x.compare(__y) >= 0; } 572 573 template<typename _CharT, typename _Traits> 574 constexpr bool 575 operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, 576 basic_string_view<_CharT, _Traits> __y) noexcept 577 { return __x.compare(__y) >= 0; } 578 579 // [string.view.io], Inserters and extractors 580 template<typename _CharT, typename _Traits> 581 inline basic_ostream<_CharT, _Traits>& 582 operator<<(basic_ostream<_CharT, _Traits>& __os, 583 basic_string_view<_CharT,_Traits> __str) 584 { return __ostream_insert(__os, __str.data(), __str.size()); } 585 586 587 // basic_string_view typedef names 588 589 using string_view = basic_string_view<char>; 590#ifdef _GLIBCXX_USE_WCHAR_T 591 using wstring_view = basic_string_view<wchar_t>; 592#endif 593#ifdef _GLIBCXX_USE_CHAR8_T 594 using u8string_view = basic_string_view<char8_t>; 595#endif 596 using u16string_view = basic_string_view<char16_t>; 597 using u32string_view = basic_string_view<char32_t>; 598 599 // [string.view.hash], hash support: 600 601 template<typename _Tp> 602 struct hash; 603 604 template<> 605 struct hash<string_view> 606 : public __hash_base<size_t, string_view> 607 { 608 size_t 609 operator()(const string_view& __str) const noexcept 610 { return std::_Hash_impl::hash(__str.data(), __str.length()); } 611 }; 612 613 template<> 614 struct __is_fast_hash<hash<string_view>> : std::false_type 615 { }; 616 617#ifdef _GLIBCXX_USE_WCHAR_T 618 template<> 619 struct hash<wstring_view> 620 : public __hash_base<size_t, wstring_view> 621 { 622 size_t 623 operator()(const wstring_view& __s) const noexcept 624 { return std::_Hash_impl::hash(__s.data(), 625 __s.length() * sizeof(wchar_t)); } 626 }; 627 628 template<> 629 struct __is_fast_hash<hash<wstring_view>> : std::false_type 630 { }; 631#endif 632 633#ifdef _GLIBCXX_USE_CHAR8_T 634 template<> 635 struct hash<u8string_view> 636 : public __hash_base<size_t, u8string_view> 637 { 638 size_t 639 operator()(const u8string_view& __str) const noexcept 640 { return std::_Hash_impl::hash(__str.data(), __str.length()); } 641 }; 642 643 template<> 644 struct __is_fast_hash<hash<u8string_view>> : std::false_type 645 { }; 646#endif 647 648 template<> 649 struct hash<u16string_view> 650 : public __hash_base<size_t, u16string_view> 651 { 652 size_t 653 operator()(const u16string_view& __s) const noexcept 654 { return std::_Hash_impl::hash(__s.data(), 655 __s.length() * sizeof(char16_t)); } 656 }; 657 658 template<> 659 struct __is_fast_hash<hash<u16string_view>> : std::false_type 660 { }; 661 662 template<> 663 struct hash<u32string_view> 664 : public __hash_base<size_t, u32string_view> 665 { 666 size_t 667 operator()(const u32string_view& __s) const noexcept 668 { return std::_Hash_impl::hash(__s.data(), 669 __s.length() * sizeof(char32_t)); } 670 }; 671 672 template<> 673 struct __is_fast_hash<hash<u32string_view>> : std::false_type 674 { }; 675 676 inline namespace literals 677 { 678 inline namespace string_view_literals 679 { 680#pragma GCC diagnostic push 681#pragma GCC diagnostic ignored "-Wliteral-suffix" 682 inline constexpr basic_string_view<char> 683 operator""sv(const char* __str, size_t __len) noexcept 684 { return basic_string_view<char>{__str, __len}; } 685 686#ifdef _GLIBCXX_USE_WCHAR_T 687 inline constexpr basic_string_view<wchar_t> 688 operator""sv(const wchar_t* __str, size_t __len) noexcept 689 { return basic_string_view<wchar_t>{__str, __len}; } 690#endif 691 692#ifdef _GLIBCXX_USE_CHAR8_T 693 inline constexpr basic_string_view<char8_t> 694 operator""sv(const char8_t* __str, size_t __len) noexcept 695 { return basic_string_view<char8_t>{__str, __len}; } 696#endif 697 698 inline constexpr basic_string_view<char16_t> 699 operator""sv(const char16_t* __str, size_t __len) noexcept 700 { return basic_string_view<char16_t>{__str, __len}; } 701 702 inline constexpr basic_string_view<char32_t> 703 operator""sv(const char32_t* __str, size_t __len) noexcept 704 { return basic_string_view<char32_t>{__str, __len}; } 705 706#pragma GCC diagnostic pop 707 } // namespace string_literals 708 } // namespace literals 709 710_GLIBCXX_END_NAMESPACE_VERSION 711} // namespace std 712 713#include <bits/string_view.tcc> 714 715#endif // __cplusplus <= 201402L 716 717#endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW 718