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 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 <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 __glibcxx_assert(__pos < this->_M_len); 197 return *(this->_M_str + __pos); 198 } 199 200 constexpr const_reference 201 at(size_type __pos) const 202 { 203 if (__pos >= _M_len) 204 __throw_out_of_range_fmt(__N("basic_string_view::at: __pos " 205 "(which is %zu) >= this->size() " 206 "(which is %zu)"), __pos, this->size()); 207 return *(this->_M_str + __pos); 208 } 209 210 constexpr const_reference 211 front() const noexcept 212 { 213 __glibcxx_assert(this->_M_len > 0); 214 return *this->_M_str; 215 } 216 217 constexpr const_reference 218 back() const noexcept 219 { 220 __glibcxx_assert(this->_M_len > 0); 221 return *(this->_M_str + this->_M_len - 1); 222 } 223 224 constexpr const_pointer 225 data() const noexcept 226 { return this->_M_str; } 227 228 // [string.view.modifiers], modifiers: 229 230 constexpr void 231 remove_prefix(size_type __n) noexcept 232 { 233 __glibcxx_assert(this->_M_len >= __n); 234 this->_M_str += __n; 235 this->_M_len -= __n; 236 } 237 238 constexpr void 239 remove_suffix(size_type __n) noexcept 240 { this->_M_len -= __n; } 241 242 constexpr void 243 swap(basic_string_view& __sv) noexcept 244 { 245 auto __tmp = *this; 246 *this = __sv; 247 __sv = __tmp; 248 } 249 250 // [string.view.ops], string operations: 251 252 size_type 253 copy(_CharT* __str, size_type __n, size_type __pos = 0) const 254 { 255 __glibcxx_requires_string_len(__str, __n); 256 __pos = std::__sv_check(size(), __pos, "basic_string_view::copy"); 257 const size_type __rlen = std::min(__n, _M_len - __pos); 258 // _GLIBCXX_RESOLVE_LIB_DEFECTS 259 // 2777. basic_string_view::copy should use char_traits::copy 260 traits_type::copy(__str, data() + __pos, __rlen); 261 return __rlen; 262 } 263 264 constexpr basic_string_view 265 substr(size_type __pos = 0, size_type __n = npos) const noexcept(false) 266 { 267 __pos = std::__sv_check(size(), __pos, "basic_string_view::substr"); 268 const size_type __rlen = std::min(__n, _M_len - __pos); 269 return basic_string_view{_M_str + __pos, __rlen}; 270 } 271 272 constexpr int 273 compare(basic_string_view __str) const noexcept 274 { 275 const size_type __rlen = std::min(this->_M_len, __str._M_len); 276 int __ret = traits_type::compare(this->_M_str, __str._M_str, __rlen); 277 if (__ret == 0) 278 __ret = _S_compare(this->_M_len, __str._M_len); 279 return __ret; 280 } 281 282 constexpr int 283 compare(size_type __pos1, size_type __n1, basic_string_view __str) const 284 { return this->substr(__pos1, __n1).compare(__str); } 285 286 constexpr int 287 compare(size_type __pos1, size_type __n1, 288 basic_string_view __str, size_type __pos2, size_type __n2) const 289 { 290 return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); 291 } 292 293 __attribute__((__nonnull__)) constexpr int 294 compare(const _CharT* __str) const noexcept 295 { return this->compare(basic_string_view{__str}); } 296 297 __attribute__((__nonnull__)) constexpr int 298 compare(size_type __pos1, size_type __n1, const _CharT* __str) const 299 { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); } 300 301 constexpr int 302 compare(size_type __pos1, size_type __n1, 303 const _CharT* __str, size_type __n2) const noexcept(false) 304 { 305 return this->substr(__pos1, __n1) 306 .compare(basic_string_view(__str, __n2)); 307 } 308 309#if __cplusplus > 201703L 310#define __cpp_lib_starts_ends_with 201711L 311 constexpr bool 312 starts_with(basic_string_view __x) const noexcept 313 { return this->substr(0, __x.size()) == __x; } 314 315 constexpr bool 316 starts_with(_CharT __x) const noexcept 317 { return !this->empty() && traits_type::eq(this->front(), __x); } 318 319 constexpr bool 320 starts_with(const _CharT* __x) const noexcept 321 { return this->starts_with(basic_string_view(__x)); } 322 323 constexpr bool 324 ends_with(basic_string_view __x) const noexcept 325 { 326 return this->size() >= __x.size() 327 && this->compare(this->size() - __x.size(), npos, __x) == 0; 328 } 329 330 constexpr bool 331 ends_with(_CharT __x) const noexcept 332 { return !this->empty() && traits_type::eq(this->back(), __x); } 333 334 constexpr bool 335 ends_with(const _CharT* __x) const noexcept 336 { return this->ends_with(basic_string_view(__x)); } 337#endif // C++20 338 339 // [string.view.find], searching 340 341 constexpr size_type 342 find(basic_string_view __str, size_type __pos = 0) const noexcept 343 { return this->find(__str._M_str, __pos, __str._M_len); } 344 345 constexpr size_type 346 find(_CharT __c, size_type __pos = 0) const noexcept; 347 348 constexpr size_type 349 find(const _CharT* __str, size_type __pos, size_type __n) const noexcept; 350 351 __attribute__((__nonnull__)) constexpr size_type 352 find(const _CharT* __str, size_type __pos = 0) const noexcept 353 { return this->find(__str, __pos, traits_type::length(__str)); } 354 355 constexpr size_type 356 rfind(basic_string_view __str, size_type __pos = npos) const noexcept 357 { return this->rfind(__str._M_str, __pos, __str._M_len); } 358 359 constexpr size_type 360 rfind(_CharT __c, size_type __pos = npos) const noexcept; 361 362 constexpr size_type 363 rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept; 364 365 __attribute__((__nonnull__)) constexpr size_type 366 rfind(const _CharT* __str, size_type __pos = npos) const noexcept 367 { return this->rfind(__str, __pos, traits_type::length(__str)); } 368 369 constexpr size_type 370 find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept 371 { return this->find_first_of(__str._M_str, __pos, __str._M_len); } 372 373 constexpr size_type 374 find_first_of(_CharT __c, size_type __pos = 0) const noexcept 375 { return this->find(__c, __pos); } 376 377 constexpr size_type 378 find_first_of(const _CharT* __str, size_type __pos, 379 size_type __n) const noexcept; 380 381 __attribute__((__nonnull__)) constexpr size_type 382 find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept 383 { return this->find_first_of(__str, __pos, traits_type::length(__str)); } 384 385 constexpr size_type 386 find_last_of(basic_string_view __str, 387 size_type __pos = npos) const noexcept 388 { return this->find_last_of(__str._M_str, __pos, __str._M_len); } 389 390 constexpr size_type 391 find_last_of(_CharT __c, size_type __pos=npos) const noexcept 392 { return this->rfind(__c, __pos); } 393 394 constexpr size_type 395 find_last_of(const _CharT* __str, size_type __pos, 396 size_type __n) const noexcept; 397 398 __attribute__((__nonnull__)) constexpr size_type 399 find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept 400 { return this->find_last_of(__str, __pos, traits_type::length(__str)); } 401 402 constexpr size_type 403 find_first_not_of(basic_string_view __str, 404 size_type __pos = 0) const noexcept 405 { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); } 406 407 constexpr size_type 408 find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept; 409 410 constexpr size_type 411 find_first_not_of(const _CharT* __str, 412 size_type __pos, size_type __n) const noexcept; 413 414 __attribute__((__nonnull__)) constexpr size_type 415 find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept 416 { 417 return this->find_first_not_of(__str, __pos, 418 traits_type::length(__str)); 419 } 420 421 constexpr size_type 422 find_last_not_of(basic_string_view __str, 423 size_type __pos = npos) const noexcept 424 { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); } 425 426 constexpr size_type 427 find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept; 428 429 constexpr size_type 430 find_last_not_of(const _CharT* __str, 431 size_type __pos, size_type __n) const noexcept; 432 433 __attribute__((__nonnull__)) constexpr size_type 434 find_last_not_of(const _CharT* __str, 435 size_type __pos = npos) const noexcept 436 { 437 return this->find_last_not_of(__str, __pos, 438 traits_type::length(__str)); 439 } 440 441 private: 442 443 static constexpr int 444 _S_compare(size_type __n1, size_type __n2) noexcept 445 { 446 const difference_type __diff = __n1 - __n2; 447 if (__diff > std::numeric_limits<int>::max()) 448 return std::numeric_limits<int>::max(); 449 if (__diff < std::numeric_limits<int>::min()) 450 return std::numeric_limits<int>::min(); 451 return static_cast<int>(__diff); 452 } 453 454 size_t _M_len; 455 const _CharT* _M_str; 456 }; 457 458 // [string.view.comparison], non-member basic_string_view comparison function 459 460 namespace __detail 461 { 462 // Identity transform to create a non-deduced context, so that only one 463 // argument participates in template argument deduction and the other 464 // argument gets implicitly converted to the deduced type. See n3766.html. 465 template<typename _Tp> 466 using __idt = common_type_t<_Tp>; 467 } 468 469 template<typename _CharT, typename _Traits> 470 constexpr bool 471 operator==(basic_string_view<_CharT, _Traits> __x, 472 basic_string_view<_CharT, _Traits> __y) noexcept 473 { return __x.size() == __y.size() && __x.compare(__y) == 0; } 474 475 template<typename _CharT, typename _Traits> 476 constexpr bool 477 operator==(basic_string_view<_CharT, _Traits> __x, 478 __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept 479 { return __x.size() == __y.size() && __x.compare(__y) == 0; } 480 481 template<typename _CharT, typename _Traits> 482 constexpr bool 483 operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, 484 basic_string_view<_CharT, _Traits> __y) noexcept 485 { return __x.size() == __y.size() && __x.compare(__y) == 0; } 486 487 template<typename _CharT, typename _Traits> 488 constexpr bool 489 operator!=(basic_string_view<_CharT, _Traits> __x, 490 basic_string_view<_CharT, _Traits> __y) noexcept 491 { return !(__x == __y); } 492 493 template<typename _CharT, typename _Traits> 494 constexpr bool 495 operator!=(basic_string_view<_CharT, _Traits> __x, 496 __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept 497 { return !(__x == __y); } 498 499 template<typename _CharT, typename _Traits> 500 constexpr bool 501 operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, 502 basic_string_view<_CharT, _Traits> __y) noexcept 503 { return !(__x == __y); } 504 505 template<typename _CharT, typename _Traits> 506 constexpr bool 507 operator< (basic_string_view<_CharT, _Traits> __x, 508 basic_string_view<_CharT, _Traits> __y) noexcept 509 { return __x.compare(__y) < 0; } 510 511 template<typename _CharT, typename _Traits> 512 constexpr bool 513 operator< (basic_string_view<_CharT, _Traits> __x, 514 __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept 515 { return __x.compare(__y) < 0; } 516 517 template<typename _CharT, typename _Traits> 518 constexpr bool 519 operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x, 520 basic_string_view<_CharT, _Traits> __y) noexcept 521 { return __x.compare(__y) < 0; } 522 523 template<typename _CharT, typename _Traits> 524 constexpr bool 525 operator> (basic_string_view<_CharT, _Traits> __x, 526 basic_string_view<_CharT, _Traits> __y) noexcept 527 { return __x.compare(__y) > 0; } 528 529 template<typename _CharT, typename _Traits> 530 constexpr bool 531 operator> (basic_string_view<_CharT, _Traits> __x, 532 __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept 533 { return __x.compare(__y) > 0; } 534 535 template<typename _CharT, typename _Traits> 536 constexpr bool 537 operator> (__detail::__idt<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 __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept 551 { return __x.compare(__y) <= 0; } 552 553 template<typename _CharT, typename _Traits> 554 constexpr bool 555 operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, 556 basic_string_view<_CharT, _Traits> __y) noexcept 557 { return __x.compare(__y) <= 0; } 558 559 template<typename _CharT, typename _Traits> 560 constexpr bool 561 operator>=(basic_string_view<_CharT, _Traits> __x, 562 basic_string_view<_CharT, _Traits> __y) noexcept 563 { return __x.compare(__y) >= 0; } 564 565 template<typename _CharT, typename _Traits> 566 constexpr bool 567 operator>=(basic_string_view<_CharT, _Traits> __x, 568 __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept 569 { return __x.compare(__y) >= 0; } 570 571 template<typename _CharT, typename _Traits> 572 constexpr bool 573 operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, 574 basic_string_view<_CharT, _Traits> __y) noexcept 575 { return __x.compare(__y) >= 0; } 576 577 // [string.view.io], Inserters and extractors 578 template<typename _CharT, typename _Traits> 579 inline basic_ostream<_CharT, _Traits>& 580 operator<<(basic_ostream<_CharT, _Traits>& __os, 581 basic_string_view<_CharT,_Traits> __str) 582 { return __ostream_insert(__os, __str.data(), __str.size()); } 583 584 585 // basic_string_view typedef names 586 587 using string_view = basic_string_view<char>; 588#ifdef _GLIBCXX_USE_WCHAR_T 589 using wstring_view = basic_string_view<wchar_t>; 590#endif 591#ifdef _GLIBCXX_USE_CHAR8_T 592 using u8string_view = basic_string_view<char8_t>; 593#endif 594 using u16string_view = basic_string_view<char16_t>; 595 using u32string_view = basic_string_view<char32_t>; 596 597 // [string.view.hash], hash support: 598 599 template<typename _Tp> 600 struct hash; 601 602 template<> 603 struct hash<string_view> 604 : public __hash_base<size_t, string_view> 605 { 606 size_t 607 operator()(const string_view& __str) const noexcept 608 { return std::_Hash_impl::hash(__str.data(), __str.length()); } 609 }; 610 611 template<> 612 struct __is_fast_hash<hash<string_view>> : std::false_type 613 { }; 614 615#ifdef _GLIBCXX_USE_WCHAR_T 616 template<> 617 struct hash<wstring_view> 618 : public __hash_base<size_t, wstring_view> 619 { 620 size_t 621 operator()(const wstring_view& __s) const noexcept 622 { return std::_Hash_impl::hash(__s.data(), 623 __s.length() * sizeof(wchar_t)); } 624 }; 625 626 template<> 627 struct __is_fast_hash<hash<wstring_view>> : std::false_type 628 { }; 629#endif 630 631#ifdef _GLIBCXX_USE_CHAR8_T 632 template<> 633 struct hash<u8string_view> 634 : public __hash_base<size_t, u8string_view> 635 { 636 size_t 637 operator()(const u8string_view& __str) const noexcept 638 { return std::_Hash_impl::hash(__str.data(), __str.length()); } 639 }; 640 641 template<> 642 struct __is_fast_hash<hash<u8string_view>> : std::false_type 643 { }; 644#endif 645 646 template<> 647 struct hash<u16string_view> 648 : public __hash_base<size_t, u16string_view> 649 { 650 size_t 651 operator()(const u16string_view& __s) const noexcept 652 { return std::_Hash_impl::hash(__s.data(), 653 __s.length() * sizeof(char16_t)); } 654 }; 655 656 template<> 657 struct __is_fast_hash<hash<u16string_view>> : std::false_type 658 { }; 659 660 template<> 661 struct hash<u32string_view> 662 : public __hash_base<size_t, u32string_view> 663 { 664 size_t 665 operator()(const u32string_view& __s) const noexcept 666 { return std::_Hash_impl::hash(__s.data(), 667 __s.length() * sizeof(char32_t)); } 668 }; 669 670 template<> 671 struct __is_fast_hash<hash<u32string_view>> : std::false_type 672 { }; 673 674 inline namespace literals 675 { 676 inline namespace string_view_literals 677 { 678#pragma GCC diagnostic push 679#pragma GCC diagnostic ignored "-Wliteral-suffix" 680 inline constexpr basic_string_view<char> 681 operator""sv(const char* __str, size_t __len) noexcept 682 { return basic_string_view<char>{__str, __len}; } 683 684#ifdef _GLIBCXX_USE_WCHAR_T 685 inline constexpr basic_string_view<wchar_t> 686 operator""sv(const wchar_t* __str, size_t __len) noexcept 687 { return basic_string_view<wchar_t>{__str, __len}; } 688#endif 689 690#ifdef _GLIBCXX_USE_CHAR8_T 691 inline constexpr basic_string_view<char8_t> 692 operator""sv(const char8_t* __str, size_t __len) noexcept 693 { return basic_string_view<char8_t>{__str, __len}; } 694#endif 695 696 inline constexpr basic_string_view<char16_t> 697 operator""sv(const char16_t* __str, size_t __len) noexcept 698 { return basic_string_view<char16_t>{__str, __len}; } 699 700 inline constexpr basic_string_view<char32_t> 701 operator""sv(const char32_t* __str, size_t __len) noexcept 702 { return basic_string_view<char32_t>{__str, __len}; } 703 704#pragma GCC diagnostic pop 705 } // namespace string_literals 706 } // namespace literals 707 708_GLIBCXX_END_NAMESPACE_VERSION 709} // namespace std 710 711#include <bits/string_view.tcc> 712 713#endif // __cplusplus <= 201402L 714 715#endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW 716