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