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