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