xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/std/string_view (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
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