1b17d1066Smrg// Components for manipulating non-owning sequences of characters -*- C++ -*- 2b17d1066Smrg 3b1e83836Smrg// Copyright (C) 2013-2022 Free Software Foundation, Inc. 4b17d1066Smrg// 5b17d1066Smrg// This file is part of the GNU ISO C++ Library. This library is free 6b17d1066Smrg// software; you can redistribute it and/or modify it under the 7b17d1066Smrg// terms of the GNU General Public License as published by the 8b17d1066Smrg// Free Software Foundation; either version 3, or (at your option) 9b17d1066Smrg// any later version. 10b17d1066Smrg 11b17d1066Smrg// This library is distributed in the hope that it will be useful, 12b17d1066Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of 13b17d1066Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14b17d1066Smrg// GNU General Public License for more details. 15b17d1066Smrg 16b17d1066Smrg// Under Section 7 of GPL version 3, you are granted additional 17b17d1066Smrg// permissions described in the GCC Runtime Library Exception, version 18b17d1066Smrg// 3.1, as published by the Free Software Foundation. 19b17d1066Smrg 20b17d1066Smrg// You should have received a copy of the GNU General Public License and 21b17d1066Smrg// a copy of the GCC Runtime Library Exception along with this program; 22b17d1066Smrg// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23b17d1066Smrg// <http://www.gnu.org/licenses/>. 24b17d1066Smrg 25a448f87cSmrg/** @file include/string_view 26b17d1066Smrg * This is a Standard C++ Library header. 27b17d1066Smrg */ 28b17d1066Smrg 29b17d1066Smrg// 30b17d1066Smrg// N3762 basic_string_view library 31b17d1066Smrg// 32b17d1066Smrg 33b17d1066Smrg#ifndef _GLIBCXX_STRING_VIEW 34b17d1066Smrg#define _GLIBCXX_STRING_VIEW 1 35b17d1066Smrg 36b17d1066Smrg#pragma GCC system_header 37b17d1066Smrg 38b17d1066Smrg#if __cplusplus >= 201703L 39b17d1066Smrg 40b17d1066Smrg#include <iosfwd> 41b17d1066Smrg#include <bits/char_traits.h> 42b1e83836Smrg#include <bits/functexcept.h> 43b17d1066Smrg#include <bits/functional_hash.h> 44b17d1066Smrg#include <bits/range_access.h> 45fb8a8121Smrg#include <bits/ostream_insert.h> 46b1e83836Smrg#include <bits/stl_algobase.h> 47fb8a8121Smrg#include <ext/numeric_traits.h> 48b17d1066Smrg 49b1e83836Smrg#if __cplusplus >= 202002L 50b1e83836Smrg# include <bits/ranges_base.h> 51b1e83836Smrg#endif 52b1e83836Smrg 53b17d1066Smrgnamespace std _GLIBCXX_VISIBILITY(default) 54b17d1066Smrg{ 55b17d1066Smrg_GLIBCXX_BEGIN_NAMESPACE_VERSION 56b17d1066Smrg 57fb8a8121Smrg# define __cpp_lib_string_view 201803L 58fb8a8121Smrg#if __cplusplus > 201703L 59fb8a8121Smrg# define __cpp_lib_constexpr_string_view 201811L 60fb8a8121Smrg#endif 61b17d1066Smrg 62181254a7Smrg // Helper for basic_string and basic_string_view members. 63181254a7Smrg constexpr size_t 64181254a7Smrg __sv_check(size_t __size, size_t __pos, const char* __s) 65181254a7Smrg { 66181254a7Smrg if (__pos > __size) 67181254a7Smrg __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > __size " 68181254a7Smrg "(which is %zu)"), __s, __pos, __size); 69181254a7Smrg return __pos; 70181254a7Smrg } 71181254a7Smrg 72181254a7Smrg // Helper for basic_string members. 73181254a7Smrg // NB: __sv_limit doesn't check for a bad __pos value. 74181254a7Smrg constexpr size_t 75181254a7Smrg __sv_limit(size_t __size, size_t __pos, size_t __off) noexcept 76181254a7Smrg { 77181254a7Smrg const bool __testoff = __off < __size - __pos; 78181254a7Smrg return __testoff ? __off : __size - __pos; 79181254a7Smrg } 80181254a7Smrg 81b17d1066Smrg /** 82b17d1066Smrg * @class basic_string_view <string_view> 83b17d1066Smrg * @brief A non-owning reference to a string. 84b17d1066Smrg * 85b17d1066Smrg * @ingroup strings 86b17d1066Smrg * @ingroup sequences 87b17d1066Smrg * 88b17d1066Smrg * @tparam _CharT Type of character 89b17d1066Smrg * @tparam _Traits Traits for character type, defaults to 90b17d1066Smrg * char_traits<_CharT>. 91b17d1066Smrg * 92b17d1066Smrg * A basic_string_view looks like this: 93b17d1066Smrg * 94b17d1066Smrg * @code 95b17d1066Smrg * _CharT* _M_str 96b17d1066Smrg * size_t _M_len 97b17d1066Smrg * @endcode 98b17d1066Smrg */ 99b17d1066Smrg template<typename _CharT, typename _Traits = std::char_traits<_CharT>> 100b17d1066Smrg class basic_string_view 101b17d1066Smrg { 102181254a7Smrg static_assert(!is_array_v<_CharT>); 103181254a7Smrg static_assert(is_trivial_v<_CharT> && is_standard_layout_v<_CharT>); 104181254a7Smrg static_assert(is_same_v<_CharT, typename _Traits::char_type>); 105181254a7Smrg 106b17d1066Smrg public: 107b17d1066Smrg 108b17d1066Smrg // types 109b17d1066Smrg using traits_type = _Traits; 110b17d1066Smrg using value_type = _CharT; 111181254a7Smrg using pointer = value_type*; 112181254a7Smrg using const_pointer = const value_type*; 113181254a7Smrg using reference = value_type&; 114181254a7Smrg using const_reference = const value_type&; 115181254a7Smrg using const_iterator = const value_type*; 116b17d1066Smrg using iterator = const_iterator; 117b17d1066Smrg using const_reverse_iterator = std::reverse_iterator<const_iterator>; 118b17d1066Smrg using reverse_iterator = const_reverse_iterator; 119b17d1066Smrg using size_type = size_t; 120b17d1066Smrg using difference_type = ptrdiff_t; 121b17d1066Smrg static constexpr size_type npos = size_type(-1); 122b17d1066Smrg 123181254a7Smrg // [string.view.cons], construction and assignment 124b17d1066Smrg 125b17d1066Smrg constexpr 126b17d1066Smrg basic_string_view() noexcept 127b17d1066Smrg : _M_len{0}, _M_str{nullptr} 128b17d1066Smrg { } 129b17d1066Smrg 130b17d1066Smrg constexpr basic_string_view(const basic_string_view&) noexcept = default; 131b17d1066Smrg 132181254a7Smrg __attribute__((__nonnull__)) constexpr 133181254a7Smrg basic_string_view(const _CharT* __str) noexcept 134181254a7Smrg : _M_len{traits_type::length(__str)}, 135b17d1066Smrg _M_str{__str} 136b17d1066Smrg { } 137b17d1066Smrg 138a3e9eb18Smrg constexpr 139a3e9eb18Smrg basic_string_view(const _CharT* __str, size_type __len) noexcept 140a3e9eb18Smrg : _M_len{__len}, _M_str{__str} 141b17d1066Smrg { } 142b17d1066Smrg 143b1e83836Smrg#if __cplusplus >= 202002L && __cpp_lib_concepts 144fb8a8121Smrg template<contiguous_iterator _It, sized_sentinel_for<_It> _End> 145fb8a8121Smrg requires same_as<iter_value_t<_It>, _CharT> 146fb8a8121Smrg && (!convertible_to<_End, size_type>) 147fb8a8121Smrg constexpr 148fb8a8121Smrg basic_string_view(_It __first, _End __last) 149b1e83836Smrg noexcept(noexcept(__last - __first)) 150fb8a8121Smrg : _M_len(__last - __first), _M_str(std::to_address(__first)) 151fb8a8121Smrg { } 152b1e83836Smrg 153b1e83836Smrg#if __cplusplus > 202002L 154b1e83836Smrg template<typename _Range, typename _DRange = remove_cvref_t<_Range>> 155b1e83836Smrg requires (!is_same_v<_DRange, basic_string_view>) 156b1e83836Smrg && ranges::contiguous_range<_Range> 157b1e83836Smrg && ranges::sized_range<_Range> 158b1e83836Smrg && is_same_v<ranges::range_value_t<_Range>, _CharT> 159b1e83836Smrg && (!is_convertible_v<_Range, const _CharT*>) 160b1e83836Smrg && (!requires (_DRange& __d) { 161b1e83836Smrg __d.operator ::std::basic_string_view<_CharT, _Traits>(); 162b1e83836Smrg }) 163b1e83836Smrg constexpr explicit 164b1e83836Smrg basic_string_view(_Range&& __r) 165b1e83836Smrg noexcept(noexcept(ranges::size(__r)) && noexcept(ranges::data(__r))) 166b1e83836Smrg : _M_len(ranges::size(__r)), _M_str(ranges::data(__r)) 167b1e83836Smrg { } 168b1e83836Smrg 169b1e83836Smrg basic_string_view(nullptr_t) = delete; 170b1e83836Smrg#endif // C++23 171b1e83836Smrg#endif // C++20 172b1e83836Smrg 173fb8a8121Smrg 174b17d1066Smrg constexpr basic_string_view& 175b17d1066Smrg operator=(const basic_string_view&) noexcept = default; 176b17d1066Smrg 177181254a7Smrg // [string.view.iterators], iterator support 178b17d1066Smrg 179b17d1066Smrg constexpr const_iterator 180b17d1066Smrg begin() const noexcept 181b17d1066Smrg { return this->_M_str; } 182b17d1066Smrg 183b17d1066Smrg constexpr const_iterator 184b17d1066Smrg end() const noexcept 185b17d1066Smrg { return this->_M_str + this->_M_len; } 186b17d1066Smrg 187b17d1066Smrg constexpr const_iterator 188b17d1066Smrg cbegin() const noexcept 189b17d1066Smrg { return this->_M_str; } 190b17d1066Smrg 191b17d1066Smrg constexpr const_iterator 192b17d1066Smrg cend() const noexcept 193b17d1066Smrg { return this->_M_str + this->_M_len; } 194b17d1066Smrg 195b17d1066Smrg constexpr const_reverse_iterator 196b17d1066Smrg rbegin() const noexcept 197b17d1066Smrg { return const_reverse_iterator(this->end()); } 198b17d1066Smrg 199b17d1066Smrg constexpr const_reverse_iterator 200b17d1066Smrg rend() const noexcept 201b17d1066Smrg { return const_reverse_iterator(this->begin()); } 202b17d1066Smrg 203b17d1066Smrg constexpr const_reverse_iterator 204b17d1066Smrg crbegin() const noexcept 205b17d1066Smrg { return const_reverse_iterator(this->end()); } 206b17d1066Smrg 207b17d1066Smrg constexpr const_reverse_iterator 208b17d1066Smrg crend() const noexcept 209b17d1066Smrg { return const_reverse_iterator(this->begin()); } 210b17d1066Smrg 211b17d1066Smrg // [string.view.capacity], capacity 212b17d1066Smrg 213b17d1066Smrg constexpr size_type 214b17d1066Smrg size() const noexcept 215b17d1066Smrg { return this->_M_len; } 216b17d1066Smrg 217b17d1066Smrg constexpr size_type 218b17d1066Smrg length() const noexcept 219b17d1066Smrg { return _M_len; } 220b17d1066Smrg 221b17d1066Smrg constexpr size_type 222b17d1066Smrg max_size() const noexcept 223b17d1066Smrg { 224b17d1066Smrg return (npos - sizeof(size_type) - sizeof(void*)) 225b17d1066Smrg / sizeof(value_type) / 4; 226b17d1066Smrg } 227b17d1066Smrg 228a3e9eb18Smrg [[nodiscard]] constexpr bool 229b17d1066Smrg empty() const noexcept 230b17d1066Smrg { return this->_M_len == 0; } 231b17d1066Smrg 232b17d1066Smrg // [string.view.access], element access 233b17d1066Smrg 234181254a7Smrg constexpr const_reference 235b17d1066Smrg operator[](size_type __pos) const noexcept 236b17d1066Smrg { 237fb8a8121Smrg __glibcxx_assert(__pos < this->_M_len); 238b17d1066Smrg return *(this->_M_str + __pos); 239b17d1066Smrg } 240b17d1066Smrg 241181254a7Smrg constexpr const_reference 242b17d1066Smrg at(size_type __pos) const 243b17d1066Smrg { 244a3e9eb18Smrg if (__pos >= _M_len) 245a3e9eb18Smrg __throw_out_of_range_fmt(__N("basic_string_view::at: __pos " 246b17d1066Smrg "(which is %zu) >= this->size() " 247a3e9eb18Smrg "(which is %zu)"), __pos, this->size()); 248a3e9eb18Smrg return *(this->_M_str + __pos); 249b17d1066Smrg } 250b17d1066Smrg 251181254a7Smrg constexpr const_reference 252a3e9eb18Smrg front() const noexcept 253b17d1066Smrg { 254fb8a8121Smrg __glibcxx_assert(this->_M_len > 0); 255b17d1066Smrg return *this->_M_str; 256b17d1066Smrg } 257b17d1066Smrg 258181254a7Smrg constexpr const_reference 259a3e9eb18Smrg back() const noexcept 260b17d1066Smrg { 261fb8a8121Smrg __glibcxx_assert(this->_M_len > 0); 262b17d1066Smrg return *(this->_M_str + this->_M_len - 1); 263b17d1066Smrg } 264b17d1066Smrg 265181254a7Smrg constexpr const_pointer 266b17d1066Smrg data() const noexcept 267b17d1066Smrg { return this->_M_str; } 268b17d1066Smrg 269b17d1066Smrg // [string.view.modifiers], modifiers: 270b17d1066Smrg 271b17d1066Smrg constexpr void 272a3e9eb18Smrg remove_prefix(size_type __n) noexcept 273b17d1066Smrg { 274b17d1066Smrg __glibcxx_assert(this->_M_len >= __n); 275b17d1066Smrg this->_M_str += __n; 276b17d1066Smrg this->_M_len -= __n; 277b17d1066Smrg } 278b17d1066Smrg 279b17d1066Smrg constexpr void 280a3e9eb18Smrg remove_suffix(size_type __n) noexcept 281*0a307195Smrg { 282*0a307195Smrg __glibcxx_assert(this->_M_len >= __n); 283*0a307195Smrg this->_M_len -= __n; 284*0a307195Smrg } 285b17d1066Smrg 286b17d1066Smrg constexpr void 287b17d1066Smrg swap(basic_string_view& __sv) noexcept 288b17d1066Smrg { 289b17d1066Smrg auto __tmp = *this; 290b17d1066Smrg *this = __sv; 291b17d1066Smrg __sv = __tmp; 292b17d1066Smrg } 293b17d1066Smrg 294b17d1066Smrg // [string.view.ops], string operations: 295b17d1066Smrg 296fb8a8121Smrg _GLIBCXX20_CONSTEXPR 297b17d1066Smrg size_type 298b17d1066Smrg copy(_CharT* __str, size_type __n, size_type __pos = 0) const 299b17d1066Smrg { 300b17d1066Smrg __glibcxx_requires_string_len(__str, __n); 301181254a7Smrg __pos = std::__sv_check(size(), __pos, "basic_string_view::copy"); 302a3e9eb18Smrg const size_type __rlen = std::min(__n, _M_len - __pos); 303a3e9eb18Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 304a3e9eb18Smrg // 2777. basic_string_view::copy should use char_traits::copy 305a3e9eb18Smrg traits_type::copy(__str, data() + __pos, __rlen); 306b17d1066Smrg return __rlen; 307b17d1066Smrg } 308b17d1066Smrg 309b17d1066Smrg constexpr basic_string_view 310a3e9eb18Smrg substr(size_type __pos = 0, size_type __n = npos) const noexcept(false) 311b17d1066Smrg { 312181254a7Smrg __pos = std::__sv_check(size(), __pos, "basic_string_view::substr"); 313a3e9eb18Smrg const size_type __rlen = std::min(__n, _M_len - __pos); 314a3e9eb18Smrg return basic_string_view{_M_str + __pos, __rlen}; 315b17d1066Smrg } 316b17d1066Smrg 317b17d1066Smrg constexpr int 318b17d1066Smrg compare(basic_string_view __str) const noexcept 319b17d1066Smrg { 320a3e9eb18Smrg const size_type __rlen = std::min(this->_M_len, __str._M_len); 321a3e9eb18Smrg int __ret = traits_type::compare(this->_M_str, __str._M_str, __rlen); 322b17d1066Smrg if (__ret == 0) 323b17d1066Smrg __ret = _S_compare(this->_M_len, __str._M_len); 324b17d1066Smrg return __ret; 325b17d1066Smrg } 326b17d1066Smrg 327b17d1066Smrg constexpr int 328b17d1066Smrg compare(size_type __pos1, size_type __n1, basic_string_view __str) const 329b17d1066Smrg { return this->substr(__pos1, __n1).compare(__str); } 330b17d1066Smrg 331b17d1066Smrg constexpr int 332b17d1066Smrg compare(size_type __pos1, size_type __n1, 333b17d1066Smrg basic_string_view __str, size_type __pos2, size_type __n2) const 334a3e9eb18Smrg { 335a3e9eb18Smrg return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); 336a3e9eb18Smrg } 337b17d1066Smrg 338181254a7Smrg __attribute__((__nonnull__)) constexpr int 339b17d1066Smrg compare(const _CharT* __str) const noexcept 340b17d1066Smrg { return this->compare(basic_string_view{__str}); } 341b17d1066Smrg 342181254a7Smrg __attribute__((__nonnull__)) constexpr int 343b17d1066Smrg compare(size_type __pos1, size_type __n1, const _CharT* __str) const 344b17d1066Smrg { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); } 345b17d1066Smrg 346b17d1066Smrg constexpr int 347b17d1066Smrg compare(size_type __pos1, size_type __n1, 348a3e9eb18Smrg const _CharT* __str, size_type __n2) const noexcept(false) 349b17d1066Smrg { 350b17d1066Smrg return this->substr(__pos1, __n1) 351b17d1066Smrg .compare(basic_string_view(__str, __n2)); 352b17d1066Smrg } 353b17d1066Smrg 354181254a7Smrg#if __cplusplus > 201703L 355fb8a8121Smrg#define __cpp_lib_starts_ends_with 201711L 356181254a7Smrg constexpr bool 357181254a7Smrg starts_with(basic_string_view __x) const noexcept 358181254a7Smrg { return this->substr(0, __x.size()) == __x; } 359181254a7Smrg 360181254a7Smrg constexpr bool 361181254a7Smrg starts_with(_CharT __x) const noexcept 362181254a7Smrg { return !this->empty() && traits_type::eq(this->front(), __x); } 363181254a7Smrg 364181254a7Smrg constexpr bool 365181254a7Smrg starts_with(const _CharT* __x) const noexcept 366181254a7Smrg { return this->starts_with(basic_string_view(__x)); } 367181254a7Smrg 368181254a7Smrg constexpr bool 369181254a7Smrg ends_with(basic_string_view __x) const noexcept 370181254a7Smrg { 371a448f87cSmrg const auto __len = this->size(); 372a448f87cSmrg const auto __xlen = __x.size(); 373a448f87cSmrg return __len >= __xlen 374a448f87cSmrg && traits_type::compare(end() - __xlen, __x.data(), __xlen) == 0; 375181254a7Smrg } 376181254a7Smrg 377181254a7Smrg constexpr bool 378181254a7Smrg ends_with(_CharT __x) const noexcept 379181254a7Smrg { return !this->empty() && traits_type::eq(this->back(), __x); } 380181254a7Smrg 381181254a7Smrg constexpr bool 382181254a7Smrg ends_with(const _CharT* __x) const noexcept 383181254a7Smrg { return this->ends_with(basic_string_view(__x)); } 384181254a7Smrg#endif // C++20 385181254a7Smrg 386b1e83836Smrg#if __cplusplus > 202002L 387b1e83836Smrg#define __cpp_lib_string_contains 202011L 388b1e83836Smrg constexpr bool 389b1e83836Smrg contains(basic_string_view __x) const noexcept 390b1e83836Smrg { return this->find(__x) != npos; } 391b1e83836Smrg 392b1e83836Smrg constexpr bool 393b1e83836Smrg contains(_CharT __x) const noexcept 394b1e83836Smrg { return this->find(__x) != npos; } 395b1e83836Smrg 396b1e83836Smrg constexpr bool 397b1e83836Smrg contains(const _CharT* __x) const noexcept 398b1e83836Smrg { return this->find(__x) != npos; } 399b1e83836Smrg#endif // C++23 400b1e83836Smrg 401181254a7Smrg // [string.view.find], searching 402181254a7Smrg 403b17d1066Smrg constexpr size_type 404b17d1066Smrg find(basic_string_view __str, size_type __pos = 0) const noexcept 405b17d1066Smrg { return this->find(__str._M_str, __pos, __str._M_len); } 406b17d1066Smrg 407b17d1066Smrg constexpr size_type 408b17d1066Smrg find(_CharT __c, size_type __pos = 0) const noexcept; 409b17d1066Smrg 410b17d1066Smrg constexpr size_type 411b17d1066Smrg find(const _CharT* __str, size_type __pos, size_type __n) const noexcept; 412b17d1066Smrg 413181254a7Smrg __attribute__((__nonnull__)) constexpr size_type 414b17d1066Smrg find(const _CharT* __str, size_type __pos = 0) const noexcept 415b17d1066Smrg { return this->find(__str, __pos, traits_type::length(__str)); } 416b17d1066Smrg 417b17d1066Smrg constexpr size_type 418b17d1066Smrg rfind(basic_string_view __str, size_type __pos = npos) const noexcept 419b17d1066Smrg { return this->rfind(__str._M_str, __pos, __str._M_len); } 420b17d1066Smrg 421b17d1066Smrg constexpr size_type 422b17d1066Smrg rfind(_CharT __c, size_type __pos = npos) const noexcept; 423b17d1066Smrg 424b17d1066Smrg constexpr size_type 425b17d1066Smrg rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept; 426b17d1066Smrg 427181254a7Smrg __attribute__((__nonnull__)) constexpr size_type 428b17d1066Smrg rfind(const _CharT* __str, size_type __pos = npos) const noexcept 429b17d1066Smrg { return this->rfind(__str, __pos, traits_type::length(__str)); } 430b17d1066Smrg 431b17d1066Smrg constexpr size_type 432b17d1066Smrg find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept 433b17d1066Smrg { return this->find_first_of(__str._M_str, __pos, __str._M_len); } 434b17d1066Smrg 435b17d1066Smrg constexpr size_type 436b17d1066Smrg find_first_of(_CharT __c, size_type __pos = 0) const noexcept 437b17d1066Smrg { return this->find(__c, __pos); } 438b17d1066Smrg 439b17d1066Smrg constexpr size_type 440181254a7Smrg find_first_of(const _CharT* __str, size_type __pos, 441181254a7Smrg size_type __n) const noexcept; 442b17d1066Smrg 443181254a7Smrg __attribute__((__nonnull__)) constexpr size_type 444b17d1066Smrg find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept 445b17d1066Smrg { return this->find_first_of(__str, __pos, traits_type::length(__str)); } 446b17d1066Smrg 447b17d1066Smrg constexpr size_type 448b17d1066Smrg find_last_of(basic_string_view __str, 449b17d1066Smrg size_type __pos = npos) const noexcept 450b17d1066Smrg { return this->find_last_of(__str._M_str, __pos, __str._M_len); } 451b17d1066Smrg 452b17d1066Smrg constexpr size_type 453b17d1066Smrg find_last_of(_CharT __c, size_type __pos=npos) const noexcept 454b17d1066Smrg { return this->rfind(__c, __pos); } 455b17d1066Smrg 456b17d1066Smrg constexpr size_type 457a3e9eb18Smrg find_last_of(const _CharT* __str, size_type __pos, 458a3e9eb18Smrg size_type __n) const noexcept; 459b17d1066Smrg 460181254a7Smrg __attribute__((__nonnull__)) constexpr size_type 461b17d1066Smrg find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept 462b17d1066Smrg { return this->find_last_of(__str, __pos, traits_type::length(__str)); } 463b17d1066Smrg 464b17d1066Smrg constexpr size_type 465b17d1066Smrg find_first_not_of(basic_string_view __str, 466b17d1066Smrg size_type __pos = 0) const noexcept 467b17d1066Smrg { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); } 468b17d1066Smrg 469b17d1066Smrg constexpr size_type 470b17d1066Smrg find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept; 471b17d1066Smrg 472b17d1066Smrg constexpr size_type 473b17d1066Smrg find_first_not_of(const _CharT* __str, 474a3e9eb18Smrg size_type __pos, size_type __n) const noexcept; 475b17d1066Smrg 476181254a7Smrg __attribute__((__nonnull__)) constexpr size_type 477b17d1066Smrg find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept 478b17d1066Smrg { 479b17d1066Smrg return this->find_first_not_of(__str, __pos, 480b17d1066Smrg traits_type::length(__str)); 481b17d1066Smrg } 482b17d1066Smrg 483b17d1066Smrg constexpr size_type 484b17d1066Smrg find_last_not_of(basic_string_view __str, 485b17d1066Smrg size_type __pos = npos) const noexcept 486b17d1066Smrg { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); } 487b17d1066Smrg 488b17d1066Smrg constexpr size_type 489b17d1066Smrg find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept; 490b17d1066Smrg 491b17d1066Smrg constexpr size_type 492b17d1066Smrg find_last_not_of(const _CharT* __str, 493a3e9eb18Smrg size_type __pos, size_type __n) const noexcept; 494b17d1066Smrg 495181254a7Smrg __attribute__((__nonnull__)) constexpr size_type 496b17d1066Smrg find_last_not_of(const _CharT* __str, 497b17d1066Smrg size_type __pos = npos) const noexcept 498b17d1066Smrg { 499b17d1066Smrg return this->find_last_not_of(__str, __pos, 500b17d1066Smrg traits_type::length(__str)); 501b17d1066Smrg } 502b17d1066Smrg 503b17d1066Smrg private: 504b17d1066Smrg 505b17d1066Smrg static constexpr int 506b17d1066Smrg _S_compare(size_type __n1, size_type __n2) noexcept 507b17d1066Smrg { 508b1e83836Smrg using __limits = __gnu_cxx::__int_traits<int>; 509a3e9eb18Smrg const difference_type __diff = __n1 - __n2; 510b1e83836Smrg if (__diff > __limits::__max) 511b1e83836Smrg return __limits::__max; 512b1e83836Smrg if (__diff < __limits::__min) 513b1e83836Smrg return __limits::__min; 514a3e9eb18Smrg return static_cast<int>(__diff); 515b17d1066Smrg } 516b17d1066Smrg 517b17d1066Smrg size_t _M_len; 518b17d1066Smrg const _CharT* _M_str; 519b17d1066Smrg }; 520b17d1066Smrg 521fb8a8121Smrg#if __cplusplus > 201703L && __cpp_lib_concepts && __cpp_deduction_guides 522fb8a8121Smrg template<contiguous_iterator _It, sized_sentinel_for<_It> _End> 523fb8a8121Smrg basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>; 524b1e83836Smrg 525b1e83836Smrg#if __cplusplus > 202002L 526b1e83836Smrg template<ranges::contiguous_range _Range> 527b1e83836Smrg basic_string_view(_Range&&) 528b1e83836Smrg -> basic_string_view<ranges::range_value_t<_Range>>; 529b1e83836Smrg#endif 530fb8a8121Smrg#endif 531fb8a8121Smrg 532b17d1066Smrg // [string.view.comparison], non-member basic_string_view comparison function 533b17d1066Smrg 534fb8a8121Smrg // Several of these functions use type_identity_t to create a non-deduced 535fb8a8121Smrg // context, so that only one argument participates in template argument 536fb8a8121Smrg // deduction and the other argument gets implicitly converted to the deduced 537fb8a8121Smrg // type (see N3766). 538b17d1066Smrg 539b17d1066Smrg template<typename _CharT, typename _Traits> 540b17d1066Smrg constexpr bool 541b17d1066Smrg operator==(basic_string_view<_CharT, _Traits> __x, 542b17d1066Smrg basic_string_view<_CharT, _Traits> __y) noexcept 543b17d1066Smrg { return __x.size() == __y.size() && __x.compare(__y) == 0; } 544b17d1066Smrg 545b17d1066Smrg template<typename _CharT, typename _Traits> 546b17d1066Smrg constexpr bool 547b17d1066Smrg operator==(basic_string_view<_CharT, _Traits> __x, 548fb8a8121Smrg __type_identity_t<basic_string_view<_CharT, _Traits>> __y) 549fb8a8121Smrg noexcept 550b17d1066Smrg { return __x.size() == __y.size() && __x.compare(__y) == 0; } 551b17d1066Smrg 552fb8a8121Smrg#if __cpp_lib_three_way_comparison 553fb8a8121Smrg template<typename _CharT, typename _Traits> 554fb8a8121Smrg constexpr auto 555fb8a8121Smrg operator<=>(basic_string_view<_CharT, _Traits> __x, 556fb8a8121Smrg basic_string_view<_CharT, _Traits> __y) noexcept 557fb8a8121Smrg -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0)) 558fb8a8121Smrg { return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); } 559fb8a8121Smrg 560fb8a8121Smrg template<typename _CharT, typename _Traits> 561fb8a8121Smrg constexpr auto 562fb8a8121Smrg operator<=>(basic_string_view<_CharT, _Traits> __x, 563fb8a8121Smrg __type_identity_t<basic_string_view<_CharT, _Traits>> __y) 564fb8a8121Smrg noexcept 565fb8a8121Smrg -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0)) 566fb8a8121Smrg { return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); } 567fb8a8121Smrg#else 568b17d1066Smrg template<typename _CharT, typename _Traits> 569b17d1066Smrg constexpr bool 570fb8a8121Smrg operator==(__type_identity_t<basic_string_view<_CharT, _Traits>> __x, 571b17d1066Smrg basic_string_view<_CharT, _Traits> __y) noexcept 572b17d1066Smrg { return __x.size() == __y.size() && __x.compare(__y) == 0; } 573b17d1066Smrg 574b17d1066Smrg template<typename _CharT, typename _Traits> 575b17d1066Smrg constexpr bool 576b17d1066Smrg operator!=(basic_string_view<_CharT, _Traits> __x, 577b17d1066Smrg basic_string_view<_CharT, _Traits> __y) noexcept 578b17d1066Smrg { return !(__x == __y); } 579b17d1066Smrg 580b17d1066Smrg template<typename _CharT, typename _Traits> 581b17d1066Smrg constexpr bool 582b17d1066Smrg operator!=(basic_string_view<_CharT, _Traits> __x, 583fb8a8121Smrg __type_identity_t<basic_string_view<_CharT, _Traits>> __y) 584fb8a8121Smrg noexcept 585b17d1066Smrg { return !(__x == __y); } 586b17d1066Smrg 587b17d1066Smrg template<typename _CharT, typename _Traits> 588b17d1066Smrg constexpr bool 589fb8a8121Smrg operator!=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x, 590b17d1066Smrg basic_string_view<_CharT, _Traits> __y) noexcept 591b17d1066Smrg { return !(__x == __y); } 592b17d1066Smrg 593b17d1066Smrg template<typename _CharT, typename _Traits> 594b17d1066Smrg constexpr bool 595b17d1066Smrg operator< (basic_string_view<_CharT, _Traits> __x, 596b17d1066Smrg basic_string_view<_CharT, _Traits> __y) noexcept 597b17d1066Smrg { return __x.compare(__y) < 0; } 598b17d1066Smrg 599b17d1066Smrg template<typename _CharT, typename _Traits> 600b17d1066Smrg constexpr bool 601b17d1066Smrg operator< (basic_string_view<_CharT, _Traits> __x, 602fb8a8121Smrg __type_identity_t<basic_string_view<_CharT, _Traits>> __y) 603fb8a8121Smrg noexcept 604b17d1066Smrg { return __x.compare(__y) < 0; } 605b17d1066Smrg 606b17d1066Smrg template<typename _CharT, typename _Traits> 607b17d1066Smrg constexpr bool 608fb8a8121Smrg operator< (__type_identity_t<basic_string_view<_CharT, _Traits>> __x, 609b17d1066Smrg basic_string_view<_CharT, _Traits> __y) noexcept 610b17d1066Smrg { return __x.compare(__y) < 0; } 611b17d1066Smrg 612b17d1066Smrg template<typename _CharT, typename _Traits> 613b17d1066Smrg constexpr bool 614b17d1066Smrg operator> (basic_string_view<_CharT, _Traits> __x, 615b17d1066Smrg basic_string_view<_CharT, _Traits> __y) noexcept 616b17d1066Smrg { return __x.compare(__y) > 0; } 617b17d1066Smrg 618b17d1066Smrg template<typename _CharT, typename _Traits> 619b17d1066Smrg constexpr bool 620b17d1066Smrg operator> (basic_string_view<_CharT, _Traits> __x, 621fb8a8121Smrg __type_identity_t<basic_string_view<_CharT, _Traits>> __y) 622fb8a8121Smrg noexcept 623b17d1066Smrg { return __x.compare(__y) > 0; } 624b17d1066Smrg 625b17d1066Smrg template<typename _CharT, typename _Traits> 626b17d1066Smrg constexpr bool 627fb8a8121Smrg operator> (__type_identity_t<basic_string_view<_CharT, _Traits>> __x, 628b17d1066Smrg basic_string_view<_CharT, _Traits> __y) noexcept 629b17d1066Smrg { return __x.compare(__y) > 0; } 630b17d1066Smrg 631b17d1066Smrg template<typename _CharT, typename _Traits> 632b17d1066Smrg constexpr bool 633b17d1066Smrg operator<=(basic_string_view<_CharT, _Traits> __x, 634b17d1066Smrg basic_string_view<_CharT, _Traits> __y) noexcept 635b17d1066Smrg { return __x.compare(__y) <= 0; } 636b17d1066Smrg 637b17d1066Smrg template<typename _CharT, typename _Traits> 638b17d1066Smrg constexpr bool 639b17d1066Smrg operator<=(basic_string_view<_CharT, _Traits> __x, 640fb8a8121Smrg __type_identity_t<basic_string_view<_CharT, _Traits>> __y) 641fb8a8121Smrg noexcept 642b17d1066Smrg { return __x.compare(__y) <= 0; } 643b17d1066Smrg 644b17d1066Smrg template<typename _CharT, typename _Traits> 645b17d1066Smrg constexpr bool 646fb8a8121Smrg operator<=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x, 647b17d1066Smrg basic_string_view<_CharT, _Traits> __y) noexcept 648b17d1066Smrg { return __x.compare(__y) <= 0; } 649b17d1066Smrg 650b17d1066Smrg template<typename _CharT, typename _Traits> 651b17d1066Smrg constexpr bool 652b17d1066Smrg operator>=(basic_string_view<_CharT, _Traits> __x, 653b17d1066Smrg basic_string_view<_CharT, _Traits> __y) noexcept 654b17d1066Smrg { return __x.compare(__y) >= 0; } 655b17d1066Smrg 656b17d1066Smrg template<typename _CharT, typename _Traits> 657b17d1066Smrg constexpr bool 658b17d1066Smrg operator>=(basic_string_view<_CharT, _Traits> __x, 659fb8a8121Smrg __type_identity_t<basic_string_view<_CharT, _Traits>> __y) 660fb8a8121Smrg noexcept 661b17d1066Smrg { return __x.compare(__y) >= 0; } 662b17d1066Smrg 663b17d1066Smrg template<typename _CharT, typename _Traits> 664b17d1066Smrg constexpr bool 665fb8a8121Smrg operator>=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x, 666b17d1066Smrg basic_string_view<_CharT, _Traits> __y) noexcept 667b17d1066Smrg { return __x.compare(__y) >= 0; } 668fb8a8121Smrg#endif // three-way comparison 669b17d1066Smrg 670b17d1066Smrg // [string.view.io], Inserters and extractors 671b17d1066Smrg template<typename _CharT, typename _Traits> 672b17d1066Smrg inline basic_ostream<_CharT, _Traits>& 673b17d1066Smrg operator<<(basic_ostream<_CharT, _Traits>& __os, 674b17d1066Smrg basic_string_view<_CharT,_Traits> __str) 675b17d1066Smrg { return __ostream_insert(__os, __str.data(), __str.size()); } 676b17d1066Smrg 677b17d1066Smrg 678b17d1066Smrg // basic_string_view typedef names 679b17d1066Smrg 680b17d1066Smrg using string_view = basic_string_view<char>; 681b17d1066Smrg using wstring_view = basic_string_view<wchar_t>; 682181254a7Smrg#ifdef _GLIBCXX_USE_CHAR8_T 683181254a7Smrg using u8string_view = basic_string_view<char8_t>; 684181254a7Smrg#endif 685b17d1066Smrg using u16string_view = basic_string_view<char16_t>; 686b17d1066Smrg using u32string_view = basic_string_view<char32_t>; 687b17d1066Smrg 688b17d1066Smrg // [string.view.hash], hash support: 689b17d1066Smrg 690b17d1066Smrg template<typename _Tp> 691b17d1066Smrg struct hash; 692b17d1066Smrg 693b17d1066Smrg template<> 694b17d1066Smrg struct hash<string_view> 695b17d1066Smrg : public __hash_base<size_t, string_view> 696b17d1066Smrg { 697b17d1066Smrg size_t 698b17d1066Smrg operator()(const string_view& __str) const noexcept 699b17d1066Smrg { return std::_Hash_impl::hash(__str.data(), __str.length()); } 700b17d1066Smrg }; 701b17d1066Smrg 702b17d1066Smrg template<> 703b17d1066Smrg struct __is_fast_hash<hash<string_view>> : std::false_type 704b17d1066Smrg { }; 705b17d1066Smrg 706b17d1066Smrg template<> 707b17d1066Smrg struct hash<wstring_view> 708181254a7Smrg : public __hash_base<size_t, wstring_view> 709b17d1066Smrg { 710b17d1066Smrg size_t 711b17d1066Smrg operator()(const wstring_view& __s) const noexcept 712b17d1066Smrg { return std::_Hash_impl::hash(__s.data(), 713b17d1066Smrg __s.length() * sizeof(wchar_t)); } 714b17d1066Smrg }; 715b17d1066Smrg 716b17d1066Smrg template<> 717b17d1066Smrg struct __is_fast_hash<hash<wstring_view>> : std::false_type 718b17d1066Smrg { }; 719b17d1066Smrg 720181254a7Smrg#ifdef _GLIBCXX_USE_CHAR8_T 721181254a7Smrg template<> 722181254a7Smrg struct hash<u8string_view> 723181254a7Smrg : public __hash_base<size_t, u8string_view> 724181254a7Smrg { 725181254a7Smrg size_t 726181254a7Smrg operator()(const u8string_view& __str) const noexcept 727181254a7Smrg { return std::_Hash_impl::hash(__str.data(), __str.length()); } 728181254a7Smrg }; 729181254a7Smrg 730181254a7Smrg template<> 731181254a7Smrg struct __is_fast_hash<hash<u8string_view>> : std::false_type 732181254a7Smrg { }; 733181254a7Smrg#endif 734181254a7Smrg 735b17d1066Smrg template<> 736b17d1066Smrg struct hash<u16string_view> 737b17d1066Smrg : public __hash_base<size_t, u16string_view> 738b17d1066Smrg { 739b17d1066Smrg size_t 740b17d1066Smrg operator()(const u16string_view& __s) const noexcept 741b17d1066Smrg { return std::_Hash_impl::hash(__s.data(), 742b17d1066Smrg __s.length() * sizeof(char16_t)); } 743b17d1066Smrg }; 744b17d1066Smrg 745b17d1066Smrg template<> 746b17d1066Smrg struct __is_fast_hash<hash<u16string_view>> : std::false_type 747b17d1066Smrg { }; 748b17d1066Smrg 749b17d1066Smrg template<> 750b17d1066Smrg struct hash<u32string_view> 751b17d1066Smrg : public __hash_base<size_t, u32string_view> 752b17d1066Smrg { 753b17d1066Smrg size_t 754b17d1066Smrg operator()(const u32string_view& __s) const noexcept 755b17d1066Smrg { return std::_Hash_impl::hash(__s.data(), 756b17d1066Smrg __s.length() * sizeof(char32_t)); } 757b17d1066Smrg }; 758b17d1066Smrg 759b17d1066Smrg template<> 760b17d1066Smrg struct __is_fast_hash<hash<u32string_view>> : std::false_type 761b17d1066Smrg { }; 762b17d1066Smrg 763b17d1066Smrg inline namespace literals 764b17d1066Smrg { 765b17d1066Smrg inline namespace string_view_literals 766b17d1066Smrg { 767a3e9eb18Smrg#pragma GCC diagnostic push 768a3e9eb18Smrg#pragma GCC diagnostic ignored "-Wliteral-suffix" 769b17d1066Smrg inline constexpr basic_string_view<char> 770b17d1066Smrg operator""sv(const char* __str, size_t __len) noexcept 771b17d1066Smrg { return basic_string_view<char>{__str, __len}; } 772b17d1066Smrg 773b17d1066Smrg inline constexpr basic_string_view<wchar_t> 774b17d1066Smrg operator""sv(const wchar_t* __str, size_t __len) noexcept 775b17d1066Smrg { return basic_string_view<wchar_t>{__str, __len}; } 776b17d1066Smrg 777181254a7Smrg#ifdef _GLIBCXX_USE_CHAR8_T 778181254a7Smrg inline constexpr basic_string_view<char8_t> 779181254a7Smrg operator""sv(const char8_t* __str, size_t __len) noexcept 780181254a7Smrg { return basic_string_view<char8_t>{__str, __len}; } 781181254a7Smrg#endif 782181254a7Smrg 783b17d1066Smrg inline constexpr basic_string_view<char16_t> 784b17d1066Smrg operator""sv(const char16_t* __str, size_t __len) noexcept 785b17d1066Smrg { return basic_string_view<char16_t>{__str, __len}; } 786b17d1066Smrg 787b17d1066Smrg inline constexpr basic_string_view<char32_t> 788b17d1066Smrg operator""sv(const char32_t* __str, size_t __len) noexcept 789b17d1066Smrg { return basic_string_view<char32_t>{__str, __len}; } 790181254a7Smrg 791a3e9eb18Smrg#pragma GCC diagnostic pop 792b17d1066Smrg } // namespace string_literals 793b17d1066Smrg } // namespace literals 794b17d1066Smrg 795fb8a8121Smrg#if __cpp_lib_concepts 796fb8a8121Smrg namespace ranges 797fb8a8121Smrg { 798fb8a8121Smrg // Opt-in to borrowed_range concept 799fb8a8121Smrg template<typename _CharT, typename _Traits> 800fb8a8121Smrg inline constexpr bool 801fb8a8121Smrg enable_borrowed_range<basic_string_view<_CharT, _Traits>> = true; 802fb8a8121Smrg 803fb8a8121Smrg // Opt-in to view concept 804fb8a8121Smrg template<typename _CharT, typename _Traits> 805fb8a8121Smrg inline constexpr bool 806fb8a8121Smrg enable_view<basic_string_view<_CharT, _Traits>> = true; 807fb8a8121Smrg } 808fb8a8121Smrg#endif 809a3e9eb18Smrg_GLIBCXX_END_NAMESPACE_VERSION 810b17d1066Smrg} // namespace std 811b17d1066Smrg 812b17d1066Smrg#include <bits/string_view.tcc> 813b17d1066Smrg 814b17d1066Smrg#endif // __cplusplus <= 201402L 815b17d1066Smrg 816b17d1066Smrg#endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW 817