13ad841b2Smrg// Components for manipulating non-owning sequences of characters -*- C++ -*- 23ad841b2Smrg 3*4c3eb207Smrg// Copyright (C) 2013-2020 Free Software Foundation, Inc. 43ad841b2Smrg// 53ad841b2Smrg// This file is part of the GNU ISO C++ Library. This library is free 63ad841b2Smrg// software; you can redistribute it and/or modify it under the 73ad841b2Smrg// terms of the GNU General Public License as published by the 83ad841b2Smrg// Free Software Foundation; either version 3, or (at your option) 93ad841b2Smrg// any later version. 103ad841b2Smrg 113ad841b2Smrg// This library is distributed in the hope that it will be useful, 123ad841b2Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of 133ad841b2Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 143ad841b2Smrg// GNU General Public License for more details. 153ad841b2Smrg 163ad841b2Smrg// Under Section 7 of GPL version 3, you are granted additional 173ad841b2Smrg// permissions described in the GCC Runtime Library Exception, version 183ad841b2Smrg// 3.1, as published by the Free Software Foundation. 193ad841b2Smrg 203ad841b2Smrg// You should have received a copy of the GNU General Public License and 213ad841b2Smrg// a copy of the GCC Runtime Library Exception along with this program; 223ad841b2Smrg// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 233ad841b2Smrg// <http://www.gnu.org/licenses/>. 243ad841b2Smrg 25*4c3eb207Smrg/** @file include/string_view 263ad841b2Smrg * This is a Standard C++ Library header. 273ad841b2Smrg */ 283ad841b2Smrg 293ad841b2Smrg// 303ad841b2Smrg// N3762 basic_string_view library 313ad841b2Smrg// 323ad841b2Smrg 333ad841b2Smrg#ifndef _GLIBCXX_STRING_VIEW 343ad841b2Smrg#define _GLIBCXX_STRING_VIEW 1 353ad841b2Smrg 363ad841b2Smrg#pragma GCC system_header 373ad841b2Smrg 383ad841b2Smrg#if __cplusplus >= 201703L 393ad841b2Smrg 403ad841b2Smrg#include <iosfwd> 413ad841b2Smrg#include <bits/char_traits.h> 423ad841b2Smrg#include <bits/functional_hash.h> 433ad841b2Smrg#include <bits/range_access.h> 44*4c3eb207Smrg#include <bits/ostream_insert.h> 45*4c3eb207Smrg#include <ext/numeric_traits.h> 463ad841b2Smrg 473ad841b2Smrgnamespace std _GLIBCXX_VISIBILITY(default) 483ad841b2Smrg{ 493ad841b2Smrg_GLIBCXX_BEGIN_NAMESPACE_VERSION 503ad841b2Smrg 51*4c3eb207Smrg# define __cpp_lib_string_view 201803L 52*4c3eb207Smrg#if __cplusplus > 201703L 53*4c3eb207Smrg# define __cpp_lib_constexpr_string_view 201811L 54*4c3eb207Smrg#endif 553ad841b2Smrg 56627f7eb2Smrg // Helper for basic_string and basic_string_view members. 57627f7eb2Smrg constexpr size_t 58627f7eb2Smrg __sv_check(size_t __size, size_t __pos, const char* __s) 59627f7eb2Smrg { 60627f7eb2Smrg if (__pos > __size) 61627f7eb2Smrg __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > __size " 62627f7eb2Smrg "(which is %zu)"), __s, __pos, __size); 63627f7eb2Smrg return __pos; 64627f7eb2Smrg } 65627f7eb2Smrg 66627f7eb2Smrg // Helper for basic_string members. 67627f7eb2Smrg // NB: __sv_limit doesn't check for a bad __pos value. 68627f7eb2Smrg constexpr size_t 69627f7eb2Smrg __sv_limit(size_t __size, size_t __pos, size_t __off) noexcept 70627f7eb2Smrg { 71627f7eb2Smrg const bool __testoff = __off < __size - __pos; 72627f7eb2Smrg return __testoff ? __off : __size - __pos; 73627f7eb2Smrg } 74627f7eb2Smrg 753ad841b2Smrg /** 763ad841b2Smrg * @class basic_string_view <string_view> 773ad841b2Smrg * @brief A non-owning reference to a string. 783ad841b2Smrg * 793ad841b2Smrg * @ingroup strings 803ad841b2Smrg * @ingroup sequences 813ad841b2Smrg * 823ad841b2Smrg * @tparam _CharT Type of character 833ad841b2Smrg * @tparam _Traits Traits for character type, defaults to 843ad841b2Smrg * char_traits<_CharT>. 853ad841b2Smrg * 863ad841b2Smrg * A basic_string_view looks like this: 873ad841b2Smrg * 883ad841b2Smrg * @code 893ad841b2Smrg * _CharT* _M_str 903ad841b2Smrg * size_t _M_len 913ad841b2Smrg * @endcode 923ad841b2Smrg */ 933ad841b2Smrg template<typename _CharT, typename _Traits = std::char_traits<_CharT>> 943ad841b2Smrg class basic_string_view 953ad841b2Smrg { 96627f7eb2Smrg static_assert(!is_array_v<_CharT>); 97627f7eb2Smrg static_assert(is_trivial_v<_CharT> && is_standard_layout_v<_CharT>); 98627f7eb2Smrg static_assert(is_same_v<_CharT, typename _Traits::char_type>); 99627f7eb2Smrg 1003ad841b2Smrg public: 1013ad841b2Smrg 1023ad841b2Smrg // types 1033ad841b2Smrg using traits_type = _Traits; 1043ad841b2Smrg using value_type = _CharT; 105627f7eb2Smrg using pointer = value_type*; 106627f7eb2Smrg using const_pointer = const value_type*; 107627f7eb2Smrg using reference = value_type&; 108627f7eb2Smrg using const_reference = const value_type&; 109627f7eb2Smrg using const_iterator = const value_type*; 1103ad841b2Smrg using iterator = const_iterator; 1113ad841b2Smrg using const_reverse_iterator = std::reverse_iterator<const_iterator>; 1123ad841b2Smrg using reverse_iterator = const_reverse_iterator; 1133ad841b2Smrg using size_type = size_t; 1143ad841b2Smrg using difference_type = ptrdiff_t; 1153ad841b2Smrg static constexpr size_type npos = size_type(-1); 1163ad841b2Smrg 117627f7eb2Smrg // [string.view.cons], construction and assignment 1183ad841b2Smrg 1193ad841b2Smrg constexpr 1203ad841b2Smrg basic_string_view() noexcept 1213ad841b2Smrg : _M_len{0}, _M_str{nullptr} 1223ad841b2Smrg { } 1233ad841b2Smrg 1243ad841b2Smrg constexpr basic_string_view(const basic_string_view&) noexcept = default; 1253ad841b2Smrg 126627f7eb2Smrg __attribute__((__nonnull__)) constexpr 127627f7eb2Smrg basic_string_view(const _CharT* __str) noexcept 128627f7eb2Smrg : _M_len{traits_type::length(__str)}, 1293ad841b2Smrg _M_str{__str} 1303ad841b2Smrg { } 1313ad841b2Smrg 132cef8759bSmrg constexpr 133cef8759bSmrg basic_string_view(const _CharT* __str, size_type __len) noexcept 134cef8759bSmrg : _M_len{__len}, _M_str{__str} 1353ad841b2Smrg { } 1363ad841b2Smrg 137*4c3eb207Smrg#if __cplusplus > 201703L && __cpp_lib_concepts 138*4c3eb207Smrg template<contiguous_iterator _It, sized_sentinel_for<_It> _End> 139*4c3eb207Smrg requires same_as<iter_value_t<_It>, _CharT> 140*4c3eb207Smrg && (!convertible_to<_End, size_type>) 141*4c3eb207Smrg constexpr 142*4c3eb207Smrg basic_string_view(_It __first, _End __last) 143*4c3eb207Smrg : _M_len(__last - __first), _M_str(std::to_address(__first)) 144*4c3eb207Smrg { } 145*4c3eb207Smrg#endif 146*4c3eb207Smrg 1473ad841b2Smrg constexpr basic_string_view& 1483ad841b2Smrg operator=(const basic_string_view&) noexcept = default; 1493ad841b2Smrg 150627f7eb2Smrg // [string.view.iterators], iterator support 1513ad841b2Smrg 1523ad841b2Smrg constexpr const_iterator 1533ad841b2Smrg begin() const noexcept 1543ad841b2Smrg { return this->_M_str; } 1553ad841b2Smrg 1563ad841b2Smrg constexpr const_iterator 1573ad841b2Smrg end() const noexcept 1583ad841b2Smrg { return this->_M_str + this->_M_len; } 1593ad841b2Smrg 1603ad841b2Smrg constexpr const_iterator 1613ad841b2Smrg cbegin() const noexcept 1623ad841b2Smrg { return this->_M_str; } 1633ad841b2Smrg 1643ad841b2Smrg constexpr const_iterator 1653ad841b2Smrg cend() const noexcept 1663ad841b2Smrg { return this->_M_str + this->_M_len; } 1673ad841b2Smrg 1683ad841b2Smrg constexpr const_reverse_iterator 1693ad841b2Smrg rbegin() const noexcept 1703ad841b2Smrg { return const_reverse_iterator(this->end()); } 1713ad841b2Smrg 1723ad841b2Smrg constexpr const_reverse_iterator 1733ad841b2Smrg rend() const noexcept 1743ad841b2Smrg { return const_reverse_iterator(this->begin()); } 1753ad841b2Smrg 1763ad841b2Smrg constexpr const_reverse_iterator 1773ad841b2Smrg crbegin() const noexcept 1783ad841b2Smrg { return const_reverse_iterator(this->end()); } 1793ad841b2Smrg 1803ad841b2Smrg constexpr const_reverse_iterator 1813ad841b2Smrg crend() const noexcept 1823ad841b2Smrg { return const_reverse_iterator(this->begin()); } 1833ad841b2Smrg 1843ad841b2Smrg // [string.view.capacity], capacity 1853ad841b2Smrg 1863ad841b2Smrg constexpr size_type 1873ad841b2Smrg size() const noexcept 1883ad841b2Smrg { return this->_M_len; } 1893ad841b2Smrg 1903ad841b2Smrg constexpr size_type 1913ad841b2Smrg length() const noexcept 1923ad841b2Smrg { return _M_len; } 1933ad841b2Smrg 1943ad841b2Smrg constexpr size_type 1953ad841b2Smrg max_size() const noexcept 1963ad841b2Smrg { 1973ad841b2Smrg return (npos - sizeof(size_type) - sizeof(void*)) 1983ad841b2Smrg / sizeof(value_type) / 4; 1993ad841b2Smrg } 2003ad841b2Smrg 201cef8759bSmrg [[nodiscard]] constexpr bool 2023ad841b2Smrg empty() const noexcept 2033ad841b2Smrg { return this->_M_len == 0; } 2043ad841b2Smrg 2053ad841b2Smrg // [string.view.access], element access 2063ad841b2Smrg 207627f7eb2Smrg constexpr const_reference 2083ad841b2Smrg operator[](size_type __pos) const noexcept 2093ad841b2Smrg { 210*4c3eb207Smrg __glibcxx_assert(__pos < this->_M_len); 2113ad841b2Smrg return *(this->_M_str + __pos); 2123ad841b2Smrg } 2133ad841b2Smrg 214627f7eb2Smrg constexpr const_reference 2153ad841b2Smrg at(size_type __pos) const 2163ad841b2Smrg { 217cef8759bSmrg if (__pos >= _M_len) 218cef8759bSmrg __throw_out_of_range_fmt(__N("basic_string_view::at: __pos " 2193ad841b2Smrg "(which is %zu) >= this->size() " 220cef8759bSmrg "(which is %zu)"), __pos, this->size()); 221cef8759bSmrg return *(this->_M_str + __pos); 2223ad841b2Smrg } 2233ad841b2Smrg 224627f7eb2Smrg constexpr const_reference 225cef8759bSmrg front() const noexcept 2263ad841b2Smrg { 227*4c3eb207Smrg __glibcxx_assert(this->_M_len > 0); 2283ad841b2Smrg return *this->_M_str; 2293ad841b2Smrg } 2303ad841b2Smrg 231627f7eb2Smrg constexpr const_reference 232cef8759bSmrg back() const noexcept 2333ad841b2Smrg { 234*4c3eb207Smrg __glibcxx_assert(this->_M_len > 0); 2353ad841b2Smrg return *(this->_M_str + this->_M_len - 1); 2363ad841b2Smrg } 2373ad841b2Smrg 238627f7eb2Smrg constexpr const_pointer 2393ad841b2Smrg data() const noexcept 2403ad841b2Smrg { return this->_M_str; } 2413ad841b2Smrg 2423ad841b2Smrg // [string.view.modifiers], modifiers: 2433ad841b2Smrg 2443ad841b2Smrg constexpr void 245cef8759bSmrg remove_prefix(size_type __n) noexcept 2463ad841b2Smrg { 2473ad841b2Smrg __glibcxx_assert(this->_M_len >= __n); 2483ad841b2Smrg this->_M_str += __n; 2493ad841b2Smrg this->_M_len -= __n; 2503ad841b2Smrg } 2513ad841b2Smrg 2523ad841b2Smrg constexpr void 253cef8759bSmrg remove_suffix(size_type __n) noexcept 2543ad841b2Smrg { this->_M_len -= __n; } 2553ad841b2Smrg 2563ad841b2Smrg constexpr void 2573ad841b2Smrg swap(basic_string_view& __sv) noexcept 2583ad841b2Smrg { 2593ad841b2Smrg auto __tmp = *this; 2603ad841b2Smrg *this = __sv; 2613ad841b2Smrg __sv = __tmp; 2623ad841b2Smrg } 2633ad841b2Smrg 2643ad841b2Smrg // [string.view.ops], string operations: 2653ad841b2Smrg 266*4c3eb207Smrg _GLIBCXX20_CONSTEXPR 2673ad841b2Smrg size_type 2683ad841b2Smrg copy(_CharT* __str, size_type __n, size_type __pos = 0) const 2693ad841b2Smrg { 2703ad841b2Smrg __glibcxx_requires_string_len(__str, __n); 271627f7eb2Smrg __pos = std::__sv_check(size(), __pos, "basic_string_view::copy"); 272cef8759bSmrg const size_type __rlen = std::min(__n, _M_len - __pos); 273cef8759bSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 274cef8759bSmrg // 2777. basic_string_view::copy should use char_traits::copy 275cef8759bSmrg traits_type::copy(__str, data() + __pos, __rlen); 2763ad841b2Smrg return __rlen; 2773ad841b2Smrg } 2783ad841b2Smrg 2793ad841b2Smrg constexpr basic_string_view 280cef8759bSmrg substr(size_type __pos = 0, size_type __n = npos) const noexcept(false) 2813ad841b2Smrg { 282627f7eb2Smrg __pos = std::__sv_check(size(), __pos, "basic_string_view::substr"); 283cef8759bSmrg const size_type __rlen = std::min(__n, _M_len - __pos); 284cef8759bSmrg return basic_string_view{_M_str + __pos, __rlen}; 2853ad841b2Smrg } 2863ad841b2Smrg 2873ad841b2Smrg constexpr int 2883ad841b2Smrg compare(basic_string_view __str) const noexcept 2893ad841b2Smrg { 290cef8759bSmrg const size_type __rlen = std::min(this->_M_len, __str._M_len); 291cef8759bSmrg int __ret = traits_type::compare(this->_M_str, __str._M_str, __rlen); 2923ad841b2Smrg if (__ret == 0) 2933ad841b2Smrg __ret = _S_compare(this->_M_len, __str._M_len); 2943ad841b2Smrg return __ret; 2953ad841b2Smrg } 2963ad841b2Smrg 2973ad841b2Smrg constexpr int 2983ad841b2Smrg compare(size_type __pos1, size_type __n1, basic_string_view __str) const 2993ad841b2Smrg { return this->substr(__pos1, __n1).compare(__str); } 3003ad841b2Smrg 3013ad841b2Smrg constexpr int 3023ad841b2Smrg compare(size_type __pos1, size_type __n1, 3033ad841b2Smrg basic_string_view __str, size_type __pos2, size_type __n2) const 304cef8759bSmrg { 305cef8759bSmrg return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); 306cef8759bSmrg } 3073ad841b2Smrg 308627f7eb2Smrg __attribute__((__nonnull__)) constexpr int 3093ad841b2Smrg compare(const _CharT* __str) const noexcept 3103ad841b2Smrg { return this->compare(basic_string_view{__str}); } 3113ad841b2Smrg 312627f7eb2Smrg __attribute__((__nonnull__)) constexpr int 3133ad841b2Smrg compare(size_type __pos1, size_type __n1, const _CharT* __str) const 3143ad841b2Smrg { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); } 3153ad841b2Smrg 3163ad841b2Smrg constexpr int 3173ad841b2Smrg compare(size_type __pos1, size_type __n1, 318cef8759bSmrg const _CharT* __str, size_type __n2) const noexcept(false) 3193ad841b2Smrg { 3203ad841b2Smrg return this->substr(__pos1, __n1) 3213ad841b2Smrg .compare(basic_string_view(__str, __n2)); 3223ad841b2Smrg } 3233ad841b2Smrg 324627f7eb2Smrg#if __cplusplus > 201703L 325*4c3eb207Smrg#define __cpp_lib_starts_ends_with 201711L 326627f7eb2Smrg constexpr bool 327627f7eb2Smrg starts_with(basic_string_view __x) const noexcept 328627f7eb2Smrg { return this->substr(0, __x.size()) == __x; } 329627f7eb2Smrg 330627f7eb2Smrg constexpr bool 331627f7eb2Smrg starts_with(_CharT __x) const noexcept 332627f7eb2Smrg { return !this->empty() && traits_type::eq(this->front(), __x); } 333627f7eb2Smrg 334627f7eb2Smrg constexpr bool 335627f7eb2Smrg starts_with(const _CharT* __x) const noexcept 336627f7eb2Smrg { return this->starts_with(basic_string_view(__x)); } 337627f7eb2Smrg 338627f7eb2Smrg constexpr bool 339627f7eb2Smrg ends_with(basic_string_view __x) const noexcept 340627f7eb2Smrg { 341*4c3eb207Smrg const auto __len = this->size(); 342*4c3eb207Smrg const auto __xlen = __x.size(); 343*4c3eb207Smrg return __len >= __xlen 344*4c3eb207Smrg && traits_type::compare(end() - __xlen, __x.data(), __xlen) == 0; 345627f7eb2Smrg } 346627f7eb2Smrg 347627f7eb2Smrg constexpr bool 348627f7eb2Smrg ends_with(_CharT __x) const noexcept 349627f7eb2Smrg { return !this->empty() && traits_type::eq(this->back(), __x); } 350627f7eb2Smrg 351627f7eb2Smrg constexpr bool 352627f7eb2Smrg ends_with(const _CharT* __x) const noexcept 353627f7eb2Smrg { return this->ends_with(basic_string_view(__x)); } 354627f7eb2Smrg#endif // C++20 355627f7eb2Smrg 356627f7eb2Smrg // [string.view.find], searching 357627f7eb2Smrg 3583ad841b2Smrg constexpr size_type 3593ad841b2Smrg find(basic_string_view __str, size_type __pos = 0) const noexcept 3603ad841b2Smrg { return this->find(__str._M_str, __pos, __str._M_len); } 3613ad841b2Smrg 3623ad841b2Smrg constexpr size_type 3633ad841b2Smrg find(_CharT __c, size_type __pos = 0) const noexcept; 3643ad841b2Smrg 3653ad841b2Smrg constexpr size_type 3663ad841b2Smrg find(const _CharT* __str, size_type __pos, size_type __n) const noexcept; 3673ad841b2Smrg 368627f7eb2Smrg __attribute__((__nonnull__)) constexpr size_type 3693ad841b2Smrg find(const _CharT* __str, size_type __pos = 0) const noexcept 3703ad841b2Smrg { return this->find(__str, __pos, traits_type::length(__str)); } 3713ad841b2Smrg 3723ad841b2Smrg constexpr size_type 3733ad841b2Smrg rfind(basic_string_view __str, size_type __pos = npos) const noexcept 3743ad841b2Smrg { return this->rfind(__str._M_str, __pos, __str._M_len); } 3753ad841b2Smrg 3763ad841b2Smrg constexpr size_type 3773ad841b2Smrg rfind(_CharT __c, size_type __pos = npos) const noexcept; 3783ad841b2Smrg 3793ad841b2Smrg constexpr size_type 3803ad841b2Smrg rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept; 3813ad841b2Smrg 382627f7eb2Smrg __attribute__((__nonnull__)) constexpr size_type 3833ad841b2Smrg rfind(const _CharT* __str, size_type __pos = npos) const noexcept 3843ad841b2Smrg { return this->rfind(__str, __pos, traits_type::length(__str)); } 3853ad841b2Smrg 3863ad841b2Smrg constexpr size_type 3873ad841b2Smrg find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept 3883ad841b2Smrg { return this->find_first_of(__str._M_str, __pos, __str._M_len); } 3893ad841b2Smrg 3903ad841b2Smrg constexpr size_type 3913ad841b2Smrg find_first_of(_CharT __c, size_type __pos = 0) const noexcept 3923ad841b2Smrg { return this->find(__c, __pos); } 3933ad841b2Smrg 3943ad841b2Smrg constexpr size_type 395627f7eb2Smrg find_first_of(const _CharT* __str, size_type __pos, 396627f7eb2Smrg size_type __n) const noexcept; 3973ad841b2Smrg 398627f7eb2Smrg __attribute__((__nonnull__)) constexpr size_type 3993ad841b2Smrg find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept 4003ad841b2Smrg { return this->find_first_of(__str, __pos, traits_type::length(__str)); } 4013ad841b2Smrg 4023ad841b2Smrg constexpr size_type 4033ad841b2Smrg find_last_of(basic_string_view __str, 4043ad841b2Smrg size_type __pos = npos) const noexcept 4053ad841b2Smrg { return this->find_last_of(__str._M_str, __pos, __str._M_len); } 4063ad841b2Smrg 4073ad841b2Smrg constexpr size_type 4083ad841b2Smrg find_last_of(_CharT __c, size_type __pos=npos) const noexcept 4093ad841b2Smrg { return this->rfind(__c, __pos); } 4103ad841b2Smrg 4113ad841b2Smrg constexpr size_type 412cef8759bSmrg find_last_of(const _CharT* __str, size_type __pos, 413cef8759bSmrg size_type __n) const noexcept; 4143ad841b2Smrg 415627f7eb2Smrg __attribute__((__nonnull__)) constexpr size_type 4163ad841b2Smrg find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept 4173ad841b2Smrg { return this->find_last_of(__str, __pos, traits_type::length(__str)); } 4183ad841b2Smrg 4193ad841b2Smrg constexpr size_type 4203ad841b2Smrg find_first_not_of(basic_string_view __str, 4213ad841b2Smrg size_type __pos = 0) const noexcept 4223ad841b2Smrg { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); } 4233ad841b2Smrg 4243ad841b2Smrg constexpr size_type 4253ad841b2Smrg find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept; 4263ad841b2Smrg 4273ad841b2Smrg constexpr size_type 4283ad841b2Smrg find_first_not_of(const _CharT* __str, 429cef8759bSmrg size_type __pos, size_type __n) const noexcept; 4303ad841b2Smrg 431627f7eb2Smrg __attribute__((__nonnull__)) constexpr size_type 4323ad841b2Smrg find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept 4333ad841b2Smrg { 4343ad841b2Smrg return this->find_first_not_of(__str, __pos, 4353ad841b2Smrg traits_type::length(__str)); 4363ad841b2Smrg } 4373ad841b2Smrg 4383ad841b2Smrg constexpr size_type 4393ad841b2Smrg find_last_not_of(basic_string_view __str, 4403ad841b2Smrg size_type __pos = npos) const noexcept 4413ad841b2Smrg { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); } 4423ad841b2Smrg 4433ad841b2Smrg constexpr size_type 4443ad841b2Smrg find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept; 4453ad841b2Smrg 4463ad841b2Smrg constexpr size_type 4473ad841b2Smrg find_last_not_of(const _CharT* __str, 448cef8759bSmrg size_type __pos, size_type __n) const noexcept; 4493ad841b2Smrg 450627f7eb2Smrg __attribute__((__nonnull__)) constexpr size_type 4513ad841b2Smrg find_last_not_of(const _CharT* __str, 4523ad841b2Smrg size_type __pos = npos) const noexcept 4533ad841b2Smrg { 4543ad841b2Smrg return this->find_last_not_of(__str, __pos, 4553ad841b2Smrg traits_type::length(__str)); 4563ad841b2Smrg } 4573ad841b2Smrg 4583ad841b2Smrg private: 4593ad841b2Smrg 4603ad841b2Smrg static constexpr int 4613ad841b2Smrg _S_compare(size_type __n1, size_type __n2) noexcept 4623ad841b2Smrg { 463cef8759bSmrg const difference_type __diff = __n1 - __n2; 464*4c3eb207Smrg if (__diff > __gnu_cxx::__int_traits<int>::__max) 465*4c3eb207Smrg return __gnu_cxx::__int_traits<int>::__max; 466*4c3eb207Smrg if (__diff < __gnu_cxx::__int_traits<int>::__min) 467*4c3eb207Smrg return __gnu_cxx::__int_traits<int>::__min; 468cef8759bSmrg return static_cast<int>(__diff); 4693ad841b2Smrg } 4703ad841b2Smrg 4713ad841b2Smrg size_t _M_len; 4723ad841b2Smrg const _CharT* _M_str; 4733ad841b2Smrg }; 4743ad841b2Smrg 475*4c3eb207Smrg#if __cplusplus > 201703L && __cpp_lib_concepts && __cpp_deduction_guides 476*4c3eb207Smrg template<contiguous_iterator _It, sized_sentinel_for<_It> _End> 477*4c3eb207Smrg basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>; 478*4c3eb207Smrg#endif 479*4c3eb207Smrg 4803ad841b2Smrg // [string.view.comparison], non-member basic_string_view comparison function 4813ad841b2Smrg 482*4c3eb207Smrg // Several of these functions use type_identity_t to create a non-deduced 483*4c3eb207Smrg // context, so that only one argument participates in template argument 484*4c3eb207Smrg // deduction and the other argument gets implicitly converted to the deduced 485*4c3eb207Smrg // type (see N3766). 4863ad841b2Smrg 4873ad841b2Smrg template<typename _CharT, typename _Traits> 4883ad841b2Smrg constexpr bool 4893ad841b2Smrg operator==(basic_string_view<_CharT, _Traits> __x, 4903ad841b2Smrg basic_string_view<_CharT, _Traits> __y) noexcept 4913ad841b2Smrg { return __x.size() == __y.size() && __x.compare(__y) == 0; } 4923ad841b2Smrg 4933ad841b2Smrg template<typename _CharT, typename _Traits> 4943ad841b2Smrg constexpr bool 4953ad841b2Smrg operator==(basic_string_view<_CharT, _Traits> __x, 496*4c3eb207Smrg __type_identity_t<basic_string_view<_CharT, _Traits>> __y) 497*4c3eb207Smrg noexcept 4983ad841b2Smrg { return __x.size() == __y.size() && __x.compare(__y) == 0; } 4993ad841b2Smrg 500*4c3eb207Smrg#if __cpp_lib_three_way_comparison 501*4c3eb207Smrg template<typename _CharT, typename _Traits> 502*4c3eb207Smrg constexpr auto 503*4c3eb207Smrg operator<=>(basic_string_view<_CharT, _Traits> __x, 504*4c3eb207Smrg basic_string_view<_CharT, _Traits> __y) noexcept 505*4c3eb207Smrg -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0)) 506*4c3eb207Smrg { return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); } 507*4c3eb207Smrg 508*4c3eb207Smrg template<typename _CharT, typename _Traits> 509*4c3eb207Smrg constexpr auto 510*4c3eb207Smrg operator<=>(basic_string_view<_CharT, _Traits> __x, 511*4c3eb207Smrg __type_identity_t<basic_string_view<_CharT, _Traits>> __y) 512*4c3eb207Smrg noexcept 513*4c3eb207Smrg -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0)) 514*4c3eb207Smrg { return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); } 515*4c3eb207Smrg#else 5163ad841b2Smrg template<typename _CharT, typename _Traits> 5173ad841b2Smrg constexpr bool 518*4c3eb207Smrg operator==(__type_identity_t<basic_string_view<_CharT, _Traits>> __x, 5193ad841b2Smrg basic_string_view<_CharT, _Traits> __y) noexcept 5203ad841b2Smrg { return __x.size() == __y.size() && __x.compare(__y) == 0; } 5213ad841b2Smrg 5223ad841b2Smrg template<typename _CharT, typename _Traits> 5233ad841b2Smrg constexpr bool 5243ad841b2Smrg operator!=(basic_string_view<_CharT, _Traits> __x, 5253ad841b2Smrg basic_string_view<_CharT, _Traits> __y) noexcept 5263ad841b2Smrg { return !(__x == __y); } 5273ad841b2Smrg 5283ad841b2Smrg template<typename _CharT, typename _Traits> 5293ad841b2Smrg constexpr bool 5303ad841b2Smrg operator!=(basic_string_view<_CharT, _Traits> __x, 531*4c3eb207Smrg __type_identity_t<basic_string_view<_CharT, _Traits>> __y) 532*4c3eb207Smrg noexcept 5333ad841b2Smrg { return !(__x == __y); } 5343ad841b2Smrg 5353ad841b2Smrg template<typename _CharT, typename _Traits> 5363ad841b2Smrg constexpr bool 537*4c3eb207Smrg operator!=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x, 5383ad841b2Smrg basic_string_view<_CharT, _Traits> __y) noexcept 5393ad841b2Smrg { return !(__x == __y); } 5403ad841b2Smrg 5413ad841b2Smrg template<typename _CharT, typename _Traits> 5423ad841b2Smrg constexpr bool 5433ad841b2Smrg operator< (basic_string_view<_CharT, _Traits> __x, 5443ad841b2Smrg basic_string_view<_CharT, _Traits> __y) noexcept 5453ad841b2Smrg { return __x.compare(__y) < 0; } 5463ad841b2Smrg 5473ad841b2Smrg template<typename _CharT, typename _Traits> 5483ad841b2Smrg constexpr bool 5493ad841b2Smrg operator< (basic_string_view<_CharT, _Traits> __x, 550*4c3eb207Smrg __type_identity_t<basic_string_view<_CharT, _Traits>> __y) 551*4c3eb207Smrg noexcept 5523ad841b2Smrg { return __x.compare(__y) < 0; } 5533ad841b2Smrg 5543ad841b2Smrg template<typename _CharT, typename _Traits> 5553ad841b2Smrg constexpr bool 556*4c3eb207Smrg operator< (__type_identity_t<basic_string_view<_CharT, _Traits>> __x, 5573ad841b2Smrg basic_string_view<_CharT, _Traits> __y) noexcept 5583ad841b2Smrg { return __x.compare(__y) < 0; } 5593ad841b2Smrg 5603ad841b2Smrg template<typename _CharT, typename _Traits> 5613ad841b2Smrg constexpr bool 5623ad841b2Smrg operator> (basic_string_view<_CharT, _Traits> __x, 5633ad841b2Smrg basic_string_view<_CharT, _Traits> __y) noexcept 5643ad841b2Smrg { return __x.compare(__y) > 0; } 5653ad841b2Smrg 5663ad841b2Smrg template<typename _CharT, typename _Traits> 5673ad841b2Smrg constexpr bool 5683ad841b2Smrg operator> (basic_string_view<_CharT, _Traits> __x, 569*4c3eb207Smrg __type_identity_t<basic_string_view<_CharT, _Traits>> __y) 570*4c3eb207Smrg noexcept 5713ad841b2Smrg { return __x.compare(__y) > 0; } 5723ad841b2Smrg 5733ad841b2Smrg template<typename _CharT, typename _Traits> 5743ad841b2Smrg constexpr bool 575*4c3eb207Smrg operator> (__type_identity_t<basic_string_view<_CharT, _Traits>> __x, 5763ad841b2Smrg basic_string_view<_CharT, _Traits> __y) noexcept 5773ad841b2Smrg { return __x.compare(__y) > 0; } 5783ad841b2Smrg 5793ad841b2Smrg template<typename _CharT, typename _Traits> 5803ad841b2Smrg constexpr bool 5813ad841b2Smrg operator<=(basic_string_view<_CharT, _Traits> __x, 5823ad841b2Smrg basic_string_view<_CharT, _Traits> __y) noexcept 5833ad841b2Smrg { return __x.compare(__y) <= 0; } 5843ad841b2Smrg 5853ad841b2Smrg template<typename _CharT, typename _Traits> 5863ad841b2Smrg constexpr bool 5873ad841b2Smrg operator<=(basic_string_view<_CharT, _Traits> __x, 588*4c3eb207Smrg __type_identity_t<basic_string_view<_CharT, _Traits>> __y) 589*4c3eb207Smrg noexcept 5903ad841b2Smrg { return __x.compare(__y) <= 0; } 5913ad841b2Smrg 5923ad841b2Smrg template<typename _CharT, typename _Traits> 5933ad841b2Smrg constexpr bool 594*4c3eb207Smrg operator<=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x, 5953ad841b2Smrg basic_string_view<_CharT, _Traits> __y) noexcept 5963ad841b2Smrg { return __x.compare(__y) <= 0; } 5973ad841b2Smrg 5983ad841b2Smrg template<typename _CharT, typename _Traits> 5993ad841b2Smrg constexpr bool 6003ad841b2Smrg operator>=(basic_string_view<_CharT, _Traits> __x, 6013ad841b2Smrg basic_string_view<_CharT, _Traits> __y) noexcept 6023ad841b2Smrg { return __x.compare(__y) >= 0; } 6033ad841b2Smrg 6043ad841b2Smrg template<typename _CharT, typename _Traits> 6053ad841b2Smrg constexpr bool 6063ad841b2Smrg operator>=(basic_string_view<_CharT, _Traits> __x, 607*4c3eb207Smrg __type_identity_t<basic_string_view<_CharT, _Traits>> __y) 608*4c3eb207Smrg noexcept 6093ad841b2Smrg { return __x.compare(__y) >= 0; } 6103ad841b2Smrg 6113ad841b2Smrg template<typename _CharT, typename _Traits> 6123ad841b2Smrg constexpr bool 613*4c3eb207Smrg operator>=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x, 6143ad841b2Smrg basic_string_view<_CharT, _Traits> __y) noexcept 6153ad841b2Smrg { return __x.compare(__y) >= 0; } 616*4c3eb207Smrg#endif // three-way comparison 6173ad841b2Smrg 6183ad841b2Smrg // [string.view.io], Inserters and extractors 6193ad841b2Smrg template<typename _CharT, typename _Traits> 6203ad841b2Smrg inline basic_ostream<_CharT, _Traits>& 6213ad841b2Smrg operator<<(basic_ostream<_CharT, _Traits>& __os, 6223ad841b2Smrg basic_string_view<_CharT,_Traits> __str) 6233ad841b2Smrg { return __ostream_insert(__os, __str.data(), __str.size()); } 6243ad841b2Smrg 6253ad841b2Smrg 6263ad841b2Smrg // basic_string_view typedef names 6273ad841b2Smrg 6283ad841b2Smrg using string_view = basic_string_view<char>; 6293ad841b2Smrg#ifdef _GLIBCXX_USE_WCHAR_T 6303ad841b2Smrg using wstring_view = basic_string_view<wchar_t>; 6313ad841b2Smrg#endif 632627f7eb2Smrg#ifdef _GLIBCXX_USE_CHAR8_T 633627f7eb2Smrg using u8string_view = basic_string_view<char8_t>; 634627f7eb2Smrg#endif 6353ad841b2Smrg using u16string_view = basic_string_view<char16_t>; 6363ad841b2Smrg using u32string_view = basic_string_view<char32_t>; 6373ad841b2Smrg 6383ad841b2Smrg // [string.view.hash], hash support: 6393ad841b2Smrg 6403ad841b2Smrg template<typename _Tp> 6413ad841b2Smrg struct hash; 6423ad841b2Smrg 6433ad841b2Smrg template<> 6443ad841b2Smrg struct hash<string_view> 6453ad841b2Smrg : public __hash_base<size_t, string_view> 6463ad841b2Smrg { 6473ad841b2Smrg size_t 6483ad841b2Smrg operator()(const string_view& __str) const noexcept 6493ad841b2Smrg { return std::_Hash_impl::hash(__str.data(), __str.length()); } 6503ad841b2Smrg }; 6513ad841b2Smrg 6523ad841b2Smrg template<> 6533ad841b2Smrg struct __is_fast_hash<hash<string_view>> : std::false_type 6543ad841b2Smrg { }; 6553ad841b2Smrg 6563ad841b2Smrg#ifdef _GLIBCXX_USE_WCHAR_T 6573ad841b2Smrg template<> 6583ad841b2Smrg struct hash<wstring_view> 659627f7eb2Smrg : public __hash_base<size_t, wstring_view> 6603ad841b2Smrg { 6613ad841b2Smrg size_t 6623ad841b2Smrg operator()(const wstring_view& __s) const noexcept 6633ad841b2Smrg { return std::_Hash_impl::hash(__s.data(), 6643ad841b2Smrg __s.length() * sizeof(wchar_t)); } 6653ad841b2Smrg }; 6663ad841b2Smrg 6673ad841b2Smrg template<> 6683ad841b2Smrg struct __is_fast_hash<hash<wstring_view>> : std::false_type 6693ad841b2Smrg { }; 6703ad841b2Smrg#endif 6713ad841b2Smrg 672627f7eb2Smrg#ifdef _GLIBCXX_USE_CHAR8_T 673627f7eb2Smrg template<> 674627f7eb2Smrg struct hash<u8string_view> 675627f7eb2Smrg : public __hash_base<size_t, u8string_view> 676627f7eb2Smrg { 677627f7eb2Smrg size_t 678627f7eb2Smrg operator()(const u8string_view& __str) const noexcept 679627f7eb2Smrg { return std::_Hash_impl::hash(__str.data(), __str.length()); } 680627f7eb2Smrg }; 681627f7eb2Smrg 682627f7eb2Smrg template<> 683627f7eb2Smrg struct __is_fast_hash<hash<u8string_view>> : std::false_type 684627f7eb2Smrg { }; 685627f7eb2Smrg#endif 686627f7eb2Smrg 6873ad841b2Smrg template<> 6883ad841b2Smrg struct hash<u16string_view> 6893ad841b2Smrg : public __hash_base<size_t, u16string_view> 6903ad841b2Smrg { 6913ad841b2Smrg size_t 6923ad841b2Smrg operator()(const u16string_view& __s) const noexcept 6933ad841b2Smrg { return std::_Hash_impl::hash(__s.data(), 6943ad841b2Smrg __s.length() * sizeof(char16_t)); } 6953ad841b2Smrg }; 6963ad841b2Smrg 6973ad841b2Smrg template<> 6983ad841b2Smrg struct __is_fast_hash<hash<u16string_view>> : std::false_type 6993ad841b2Smrg { }; 7003ad841b2Smrg 7013ad841b2Smrg template<> 7023ad841b2Smrg struct hash<u32string_view> 7033ad841b2Smrg : public __hash_base<size_t, u32string_view> 7043ad841b2Smrg { 7053ad841b2Smrg size_t 7063ad841b2Smrg operator()(const u32string_view& __s) const noexcept 7073ad841b2Smrg { return std::_Hash_impl::hash(__s.data(), 7083ad841b2Smrg __s.length() * sizeof(char32_t)); } 7093ad841b2Smrg }; 7103ad841b2Smrg 7113ad841b2Smrg template<> 7123ad841b2Smrg struct __is_fast_hash<hash<u32string_view>> : std::false_type 7133ad841b2Smrg { }; 7143ad841b2Smrg 7153ad841b2Smrg inline namespace literals 7163ad841b2Smrg { 7173ad841b2Smrg inline namespace string_view_literals 7183ad841b2Smrg { 719cef8759bSmrg#pragma GCC diagnostic push 720cef8759bSmrg#pragma GCC diagnostic ignored "-Wliteral-suffix" 7213ad841b2Smrg inline constexpr basic_string_view<char> 7223ad841b2Smrg operator""sv(const char* __str, size_t __len) noexcept 7233ad841b2Smrg { return basic_string_view<char>{__str, __len}; } 7243ad841b2Smrg 7253ad841b2Smrg#ifdef _GLIBCXX_USE_WCHAR_T 7263ad841b2Smrg inline constexpr basic_string_view<wchar_t> 7273ad841b2Smrg operator""sv(const wchar_t* __str, size_t __len) noexcept 7283ad841b2Smrg { return basic_string_view<wchar_t>{__str, __len}; } 7293ad841b2Smrg#endif 7303ad841b2Smrg 731627f7eb2Smrg#ifdef _GLIBCXX_USE_CHAR8_T 732627f7eb2Smrg inline constexpr basic_string_view<char8_t> 733627f7eb2Smrg operator""sv(const char8_t* __str, size_t __len) noexcept 734627f7eb2Smrg { return basic_string_view<char8_t>{__str, __len}; } 735627f7eb2Smrg#endif 736627f7eb2Smrg 7373ad841b2Smrg inline constexpr basic_string_view<char16_t> 7383ad841b2Smrg operator""sv(const char16_t* __str, size_t __len) noexcept 7393ad841b2Smrg { return basic_string_view<char16_t>{__str, __len}; } 7403ad841b2Smrg 7413ad841b2Smrg inline constexpr basic_string_view<char32_t> 7423ad841b2Smrg operator""sv(const char32_t* __str, size_t __len) noexcept 7433ad841b2Smrg { return basic_string_view<char32_t>{__str, __len}; } 744627f7eb2Smrg 745cef8759bSmrg#pragma GCC diagnostic pop 7463ad841b2Smrg } // namespace string_literals 7473ad841b2Smrg } // namespace literals 7483ad841b2Smrg 749*4c3eb207Smrg#if __cpp_lib_concepts 750*4c3eb207Smrg namespace ranges 751*4c3eb207Smrg { 752*4c3eb207Smrg // Opt-in to borrowed_range concept 753*4c3eb207Smrg template<typename _CharT, typename _Traits> 754*4c3eb207Smrg inline constexpr bool 755*4c3eb207Smrg enable_borrowed_range<basic_string_view<_CharT, _Traits>> = true; 756*4c3eb207Smrg 757*4c3eb207Smrg // Opt-in to view concept 758*4c3eb207Smrg template<typename _CharT, typename _Traits> 759*4c3eb207Smrg inline constexpr bool 760*4c3eb207Smrg enable_view<basic_string_view<_CharT, _Traits>> = true; 761*4c3eb207Smrg } 762*4c3eb207Smrg#endif 763cef8759bSmrg_GLIBCXX_END_NAMESPACE_VERSION 7643ad841b2Smrg} // namespace std 7653ad841b2Smrg 7663ad841b2Smrg#include <bits/string_view.tcc> 7673ad841b2Smrg 7683ad841b2Smrg#endif // __cplusplus <= 201402L 7693ad841b2Smrg 7703ad841b2Smrg#endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW 771