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