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