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