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