xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/std/string_view (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj// Components for manipulating non-owning sequences of characters -*- C++ -*-
238fd1498Szrj
338fd1498Szrj// Copyright (C) 2013-2018 Free Software Foundation, Inc.
438fd1498Szrj//
538fd1498Szrj// This file is part of the GNU ISO C++ Library.  This library is free
638fd1498Szrj// software; you can redistribute it and/or modify it under the
738fd1498Szrj// terms of the GNU General Public License as published by the
838fd1498Szrj// Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj// any later version.
1038fd1498Szrj
1138fd1498Szrj// This library is distributed in the hope that it will be useful,
1238fd1498Szrj// but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1438fd1498Szrj// GNU General Public License for more details.
1538fd1498Szrj
1638fd1498Szrj// Under Section 7 of GPL version 3, you are granted additional
1738fd1498Szrj// permissions described in the GCC Runtime Library Exception, version
1838fd1498Szrj// 3.1, as published by the Free Software Foundation.
1938fd1498Szrj
2038fd1498Szrj// You should have received a copy of the GNU General Public License and
2138fd1498Szrj// a copy of the GCC Runtime Library Exception along with this program;
2238fd1498Szrj// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2338fd1498Szrj// <http://www.gnu.org/licenses/>.
2438fd1498Szrj
2538fd1498Szrj/** @file string_view
2638fd1498Szrj *  This is a Standard C++ Library header.
2738fd1498Szrj */
2838fd1498Szrj
2938fd1498Szrj//
3038fd1498Szrj// N3762 basic_string_view library
3138fd1498Szrj//
3238fd1498Szrj
3338fd1498Szrj#ifndef _GLIBCXX_STRING_VIEW
3438fd1498Szrj#define _GLIBCXX_STRING_VIEW 1
3538fd1498Szrj
3638fd1498Szrj#pragma GCC system_header
3738fd1498Szrj
3838fd1498Szrj#if __cplusplus >= 201703L
3938fd1498Szrj
4038fd1498Szrj#include <limits>
4138fd1498Szrj#include <iosfwd>
4238fd1498Szrj#include <bits/char_traits.h>
4338fd1498Szrj#include <bits/functional_hash.h>
4438fd1498Szrj#include <bits/range_access.h>
4538fd1498Szrj
4638fd1498Szrjnamespace std _GLIBCXX_VISIBILITY(default)
4738fd1498Szrj{
4838fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_VERSION
4938fd1498Szrj
5038fd1498Szrj#define __cpp_lib_string_view 201603
5138fd1498Szrj
5238fd1498Szrj  /**
5338fd1498Szrj   *  @class basic_string_view <string_view>
5438fd1498Szrj   *  @brief  A non-owning reference to a string.
5538fd1498Szrj   *
5638fd1498Szrj   *  @ingroup strings
5738fd1498Szrj   *  @ingroup sequences
5838fd1498Szrj   *
5938fd1498Szrj   *  @tparam _CharT  Type of character
6038fd1498Szrj   *  @tparam _Traits  Traits for character type, defaults to
6138fd1498Szrj   *                   char_traits<_CharT>.
6238fd1498Szrj   *
6338fd1498Szrj   *  A basic_string_view looks like this:
6438fd1498Szrj   *
6538fd1498Szrj   *  @code
6638fd1498Szrj   *    _CharT*    _M_str
6738fd1498Szrj   *    size_t     _M_len
6838fd1498Szrj   *  @endcode
6938fd1498Szrj   */
7038fd1498Szrj  template<typename _CharT, typename _Traits = std::char_traits<_CharT>>
7138fd1498Szrj    class basic_string_view
7238fd1498Szrj    {
7338fd1498Szrj    public:
7438fd1498Szrj
7538fd1498Szrj      // types
7638fd1498Szrj      using traits_type = _Traits;
7738fd1498Szrj      using value_type = _CharT;
7838fd1498Szrj      using pointer = const _CharT*;
7938fd1498Szrj      using const_pointer = const _CharT*;
8038fd1498Szrj      using reference = const _CharT&;
8138fd1498Szrj      using const_reference = const _CharT&;
8238fd1498Szrj      using const_iterator = const _CharT*;
8338fd1498Szrj      using iterator = const_iterator;
8438fd1498Szrj      using const_reverse_iterator = std::reverse_iterator<const_iterator>;
8538fd1498Szrj      using reverse_iterator = const_reverse_iterator;
8638fd1498Szrj      using size_type = size_t;
8738fd1498Szrj      using difference_type = ptrdiff_t;
8838fd1498Szrj      static constexpr size_type npos = size_type(-1);
8938fd1498Szrj
9038fd1498Szrj      // [string.view.cons], construct/copy
9138fd1498Szrj
9238fd1498Szrj      constexpr
9338fd1498Szrj      basic_string_view() noexcept
9438fd1498Szrj      : _M_len{0}, _M_str{nullptr}
9538fd1498Szrj      { }
9638fd1498Szrj
9738fd1498Szrj      constexpr basic_string_view(const basic_string_view&) noexcept = default;
9838fd1498Szrj
9938fd1498Szrj      constexpr basic_string_view(const _CharT* __str) noexcept
10038fd1498Szrj      : _M_len{__str == nullptr ? 0 : traits_type::length(__str)},
10138fd1498Szrj	_M_str{__str}
10238fd1498Szrj      { }
10338fd1498Szrj
10438fd1498Szrj      constexpr
10538fd1498Szrj      basic_string_view(const _CharT* __str, size_type __len) noexcept
10638fd1498Szrj      : _M_len{__len}, _M_str{__str}
10738fd1498Szrj      { }
10838fd1498Szrj
10938fd1498Szrj      constexpr basic_string_view&
11038fd1498Szrj      operator=(const basic_string_view&) noexcept = default;
11138fd1498Szrj
11238fd1498Szrj      // [string.view.iterators], iterators
11338fd1498Szrj
11438fd1498Szrj      constexpr const_iterator
11538fd1498Szrj      begin() const noexcept
11638fd1498Szrj      { return this->_M_str; }
11738fd1498Szrj
11838fd1498Szrj      constexpr const_iterator
11938fd1498Szrj      end() const noexcept
12038fd1498Szrj      { return this->_M_str + this->_M_len; }
12138fd1498Szrj
12238fd1498Szrj      constexpr const_iterator
12338fd1498Szrj      cbegin() const noexcept
12438fd1498Szrj      { return this->_M_str; }
12538fd1498Szrj
12638fd1498Szrj      constexpr const_iterator
12738fd1498Szrj      cend() const noexcept
12838fd1498Szrj      { return this->_M_str + this->_M_len; }
12938fd1498Szrj
13038fd1498Szrj      constexpr const_reverse_iterator
13138fd1498Szrj      rbegin() const noexcept
13238fd1498Szrj      { return const_reverse_iterator(this->end()); }
13338fd1498Szrj
13438fd1498Szrj      constexpr const_reverse_iterator
13538fd1498Szrj      rend() const noexcept
13638fd1498Szrj      { return const_reverse_iterator(this->begin()); }
13738fd1498Szrj
13838fd1498Szrj      constexpr const_reverse_iterator
13938fd1498Szrj      crbegin() const noexcept
14038fd1498Szrj      { return const_reverse_iterator(this->end()); }
14138fd1498Szrj
14238fd1498Szrj      constexpr const_reverse_iterator
14338fd1498Szrj      crend() const noexcept
14438fd1498Szrj      { return const_reverse_iterator(this->begin()); }
14538fd1498Szrj
14638fd1498Szrj      // [string.view.capacity], capacity
14738fd1498Szrj
14838fd1498Szrj      constexpr size_type
14938fd1498Szrj      size() const noexcept
15038fd1498Szrj      { return this->_M_len; }
15138fd1498Szrj
15238fd1498Szrj      constexpr size_type
15338fd1498Szrj      length() const noexcept
15438fd1498Szrj      { return _M_len; }
15538fd1498Szrj
15638fd1498Szrj      constexpr size_type
15738fd1498Szrj      max_size() const noexcept
15838fd1498Szrj      {
15938fd1498Szrj	return (npos - sizeof(size_type) - sizeof(void*))
16038fd1498Szrj		/ sizeof(value_type) / 4;
16138fd1498Szrj      }
16238fd1498Szrj
16338fd1498Szrj      [[nodiscard]] constexpr bool
16438fd1498Szrj      empty() const noexcept
16538fd1498Szrj      { return this->_M_len == 0; }
16638fd1498Szrj
16738fd1498Szrj      // [string.view.access], element access
16838fd1498Szrj
16938fd1498Szrj      constexpr const _CharT&
17038fd1498Szrj      operator[](size_type __pos) const noexcept
17138fd1498Szrj      {
17238fd1498Szrj	// TODO: Assert to restore in a way compatible with the constexpr.
17338fd1498Szrj	// __glibcxx_assert(__pos < this->_M_len);
17438fd1498Szrj	return *(this->_M_str + __pos);
17538fd1498Szrj      }
17638fd1498Szrj
17738fd1498Szrj      constexpr const _CharT&
17838fd1498Szrj      at(size_type __pos) const
17938fd1498Szrj      {
18038fd1498Szrj	if (__pos >= _M_len)
18138fd1498Szrj	  __throw_out_of_range_fmt(__N("basic_string_view::at: __pos "
18238fd1498Szrj				       "(which is %zu) >= this->size() "
18338fd1498Szrj				       "(which is %zu)"), __pos, this->size());
18438fd1498Szrj	return *(this->_M_str + __pos);
18538fd1498Szrj      }
18638fd1498Szrj
18738fd1498Szrj      constexpr const _CharT&
18838fd1498Szrj      front() const noexcept
18938fd1498Szrj      {
19038fd1498Szrj	// TODO: Assert to restore in a way compatible with the constexpr.
19138fd1498Szrj	// __glibcxx_assert(this->_M_len > 0);
19238fd1498Szrj	return *this->_M_str;
19338fd1498Szrj      }
19438fd1498Szrj
19538fd1498Szrj      constexpr const _CharT&
19638fd1498Szrj      back() const noexcept
19738fd1498Szrj      {
19838fd1498Szrj	// TODO: Assert to restore in a way compatible with the constexpr.
19938fd1498Szrj	// __glibcxx_assert(this->_M_len > 0);
20038fd1498Szrj	return *(this->_M_str + this->_M_len - 1);
20138fd1498Szrj      }
20238fd1498Szrj
20338fd1498Szrj      constexpr const _CharT*
20438fd1498Szrj      data() const noexcept
20538fd1498Szrj      { return this->_M_str; }
20638fd1498Szrj
20738fd1498Szrj      // [string.view.modifiers], modifiers:
20838fd1498Szrj
20938fd1498Szrj      constexpr void
21038fd1498Szrj      remove_prefix(size_type __n) noexcept
21138fd1498Szrj      {
21238fd1498Szrj	__glibcxx_assert(this->_M_len >= __n);
21338fd1498Szrj	this->_M_str += __n;
21438fd1498Szrj	this->_M_len -= __n;
21538fd1498Szrj      }
21638fd1498Szrj
21738fd1498Szrj      constexpr void
21838fd1498Szrj      remove_suffix(size_type __n) noexcept
21938fd1498Szrj      { this->_M_len -= __n; }
22038fd1498Szrj
22138fd1498Szrj      constexpr void
22238fd1498Szrj      swap(basic_string_view& __sv) noexcept
22338fd1498Szrj      {
22438fd1498Szrj	auto __tmp = *this;
22538fd1498Szrj	*this = __sv;
22638fd1498Szrj	__sv = __tmp;
22738fd1498Szrj      }
22838fd1498Szrj
22938fd1498Szrj
23038fd1498Szrj      // [string.view.ops], string operations:
23138fd1498Szrj
23238fd1498Szrj      size_type
23338fd1498Szrj      copy(_CharT* __str, size_type __n, size_type __pos = 0) const
23438fd1498Szrj      {
23538fd1498Szrj	__glibcxx_requires_string_len(__str, __n);
23638fd1498Szrj	__pos = _M_check(__pos, "basic_string_view::copy");
23738fd1498Szrj	const size_type __rlen = std::min(__n, _M_len - __pos);
238*58e805e6Szrj	// _GLIBCXX_RESOLVE_LIB_DEFECTS
239*58e805e6Szrj	// 2777. basic_string_view::copy should use char_traits::copy
240*58e805e6Szrj	traits_type::copy(__str, data() + __pos, __rlen);
24138fd1498Szrj	return __rlen;
24238fd1498Szrj      }
24338fd1498Szrj
24438fd1498Szrj      constexpr basic_string_view
245*58e805e6Szrj      substr(size_type __pos = 0, size_type __n = npos) const noexcept(false)
24638fd1498Szrj      {
24738fd1498Szrj	__pos = _M_check(__pos, "basic_string_view::substr");
24838fd1498Szrj	const size_type __rlen = std::min(__n, _M_len - __pos);
24938fd1498Szrj	return basic_string_view{_M_str + __pos, __rlen};
25038fd1498Szrj      }
25138fd1498Szrj
25238fd1498Szrj      constexpr int
25338fd1498Szrj      compare(basic_string_view __str) const noexcept
25438fd1498Szrj      {
25538fd1498Szrj	const size_type __rlen = std::min(this->_M_len, __str._M_len);
25638fd1498Szrj	int __ret = traits_type::compare(this->_M_str, __str._M_str, __rlen);
25738fd1498Szrj	if (__ret == 0)
25838fd1498Szrj	  __ret = _S_compare(this->_M_len, __str._M_len);
25938fd1498Szrj	return __ret;
26038fd1498Szrj      }
26138fd1498Szrj
26238fd1498Szrj      constexpr int
26338fd1498Szrj      compare(size_type __pos1, size_type __n1, basic_string_view __str) const
26438fd1498Szrj      { return this->substr(__pos1, __n1).compare(__str); }
26538fd1498Szrj
26638fd1498Szrj      constexpr int
26738fd1498Szrj      compare(size_type __pos1, size_type __n1,
26838fd1498Szrj	      basic_string_view __str, size_type __pos2, size_type __n2) const
26938fd1498Szrj      {
27038fd1498Szrj	return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2));
27138fd1498Szrj      }
27238fd1498Szrj
27338fd1498Szrj      constexpr int
27438fd1498Szrj      compare(const _CharT* __str) const noexcept
27538fd1498Szrj      { return this->compare(basic_string_view{__str}); }
27638fd1498Szrj
27738fd1498Szrj      constexpr int
27838fd1498Szrj      compare(size_type __pos1, size_type __n1, const _CharT* __str) const
27938fd1498Szrj      { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
28038fd1498Szrj
28138fd1498Szrj      constexpr int
28238fd1498Szrj      compare(size_type __pos1, size_type __n1,
28338fd1498Szrj	      const _CharT* __str, size_type __n2) const noexcept(false)
28438fd1498Szrj      {
28538fd1498Szrj	return this->substr(__pos1, __n1)
28638fd1498Szrj		   .compare(basic_string_view(__str, __n2));
28738fd1498Szrj      }
28838fd1498Szrj
28938fd1498Szrj      constexpr size_type
29038fd1498Szrj      find(basic_string_view __str, size_type __pos = 0) const noexcept
29138fd1498Szrj      { return this->find(__str._M_str, __pos, __str._M_len); }
29238fd1498Szrj
29338fd1498Szrj      constexpr size_type
29438fd1498Szrj      find(_CharT __c, size_type __pos = 0) const noexcept;
29538fd1498Szrj
29638fd1498Szrj      constexpr size_type
29738fd1498Szrj      find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
29838fd1498Szrj
29938fd1498Szrj      constexpr size_type
30038fd1498Szrj      find(const _CharT* __str, size_type __pos = 0) const noexcept
30138fd1498Szrj      { return this->find(__str, __pos, traits_type::length(__str)); }
30238fd1498Szrj
30338fd1498Szrj      constexpr size_type
30438fd1498Szrj      rfind(basic_string_view __str, size_type __pos = npos) const noexcept
30538fd1498Szrj      { return this->rfind(__str._M_str, __pos, __str._M_len); }
30638fd1498Szrj
30738fd1498Szrj      constexpr size_type
30838fd1498Szrj      rfind(_CharT __c, size_type __pos = npos) const noexcept;
30938fd1498Szrj
31038fd1498Szrj      constexpr size_type
31138fd1498Szrj      rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
31238fd1498Szrj
31338fd1498Szrj      constexpr size_type
31438fd1498Szrj      rfind(const _CharT* __str, size_type __pos = npos) const noexcept
31538fd1498Szrj      { return this->rfind(__str, __pos, traits_type::length(__str)); }
31638fd1498Szrj
31738fd1498Szrj      constexpr size_type
31838fd1498Szrj      find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept
31938fd1498Szrj      { return this->find_first_of(__str._M_str, __pos, __str._M_len); }
32038fd1498Szrj
32138fd1498Szrj      constexpr size_type
32238fd1498Szrj      find_first_of(_CharT __c, size_type __pos = 0) const noexcept
32338fd1498Szrj      { return this->find(__c, __pos); }
32438fd1498Szrj
32538fd1498Szrj      constexpr size_type
32638fd1498Szrj      find_first_of(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
32738fd1498Szrj
32838fd1498Szrj      constexpr size_type
32938fd1498Szrj      find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept
33038fd1498Szrj      { return this->find_first_of(__str, __pos, traits_type::length(__str)); }
33138fd1498Szrj
33238fd1498Szrj      constexpr size_type
33338fd1498Szrj      find_last_of(basic_string_view __str,
33438fd1498Szrj		   size_type __pos = npos) const noexcept
33538fd1498Szrj      { return this->find_last_of(__str._M_str, __pos, __str._M_len); }
33638fd1498Szrj
33738fd1498Szrj      constexpr size_type
33838fd1498Szrj      find_last_of(_CharT __c, size_type __pos=npos) const noexcept
33938fd1498Szrj      { return this->rfind(__c, __pos); }
34038fd1498Szrj
34138fd1498Szrj      constexpr size_type
34238fd1498Szrj      find_last_of(const _CharT* __str, size_type __pos,
34338fd1498Szrj		   size_type __n) const noexcept;
34438fd1498Szrj
34538fd1498Szrj      constexpr size_type
34638fd1498Szrj      find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
34738fd1498Szrj      { return this->find_last_of(__str, __pos, traits_type::length(__str)); }
34838fd1498Szrj
34938fd1498Szrj      constexpr size_type
35038fd1498Szrj      find_first_not_of(basic_string_view __str,
35138fd1498Szrj			size_type __pos = 0) const noexcept
35238fd1498Szrj      { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); }
35338fd1498Szrj
35438fd1498Szrj      constexpr size_type
35538fd1498Szrj      find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept;
35638fd1498Szrj
35738fd1498Szrj      constexpr size_type
35838fd1498Szrj      find_first_not_of(const _CharT* __str,
35938fd1498Szrj			size_type __pos, size_type __n) const noexcept;
36038fd1498Szrj
36138fd1498Szrj      constexpr size_type
36238fd1498Szrj      find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept
36338fd1498Szrj      {
36438fd1498Szrj	return this->find_first_not_of(__str, __pos,
36538fd1498Szrj				       traits_type::length(__str));
36638fd1498Szrj      }
36738fd1498Szrj
36838fd1498Szrj      constexpr size_type
36938fd1498Szrj      find_last_not_of(basic_string_view __str,
37038fd1498Szrj		       size_type __pos = npos) const noexcept
37138fd1498Szrj      { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); }
37238fd1498Szrj
37338fd1498Szrj      constexpr size_type
37438fd1498Szrj      find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept;
37538fd1498Szrj
37638fd1498Szrj      constexpr size_type
37738fd1498Szrj      find_last_not_of(const _CharT* __str,
37838fd1498Szrj		       size_type __pos, size_type __n) const noexcept;
37938fd1498Szrj
38038fd1498Szrj      constexpr size_type
38138fd1498Szrj      find_last_not_of(const _CharT* __str,
38238fd1498Szrj		       size_type __pos = npos) const noexcept
38338fd1498Szrj      {
38438fd1498Szrj	return this->find_last_not_of(__str, __pos,
38538fd1498Szrj				      traits_type::length(__str));
38638fd1498Szrj      }
38738fd1498Szrj
38838fd1498Szrj      constexpr size_type
38938fd1498Szrj      _M_check(size_type __pos, const char* __s) const noexcept(false)
39038fd1498Szrj      {
39138fd1498Szrj	if (__pos > this->size())
39238fd1498Szrj	  __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "
39338fd1498Szrj				       "this->size() (which is %zu)"),
39438fd1498Szrj				   __s, __pos, this->size());
39538fd1498Szrj	return __pos;
39638fd1498Szrj      }
39738fd1498Szrj
39838fd1498Szrj      // NB: _M_limit doesn't check for a bad __pos value.
39938fd1498Szrj      constexpr size_type
40038fd1498Szrj      _M_limit(size_type __pos, size_type __off) const noexcept
40138fd1498Szrj      {
40238fd1498Szrj	const bool __testoff =  __off < this->size() - __pos;
40338fd1498Szrj	return __testoff ? __off : this->size() - __pos;
40438fd1498Szrj      }
40538fd1498Szrj
40638fd1498Szrj    private:
40738fd1498Szrj
40838fd1498Szrj      static constexpr int
40938fd1498Szrj      _S_compare(size_type __n1, size_type __n2) noexcept
41038fd1498Szrj      {
41138fd1498Szrj	const difference_type __diff = __n1 - __n2;
41238fd1498Szrj	if (__diff > std::numeric_limits<int>::max())
41338fd1498Szrj	  return std::numeric_limits<int>::max();
41438fd1498Szrj	if (__diff < std::numeric_limits<int>::min())
41538fd1498Szrj	  return std::numeric_limits<int>::min();
41638fd1498Szrj	return static_cast<int>(__diff);
41738fd1498Szrj      }
41838fd1498Szrj
41938fd1498Szrj      size_t	    _M_len;
42038fd1498Szrj      const _CharT* _M_str;
42138fd1498Szrj    };
42238fd1498Szrj
42338fd1498Szrj  // [string.view.comparison], non-member basic_string_view comparison function
42438fd1498Szrj
42538fd1498Szrj  namespace __detail
42638fd1498Szrj  {
42738fd1498Szrj    // Identity transform to create a non-deduced context, so that only one
42838fd1498Szrj    // argument participates in template argument deduction and the other
42938fd1498Szrj    // argument gets implicitly converted to the deduced type. See n3766.html.
43038fd1498Szrj    template<typename _Tp>
43138fd1498Szrj      using __idt = common_type_t<_Tp>;
43238fd1498Szrj  }
43338fd1498Szrj
43438fd1498Szrj  template<typename _CharT, typename _Traits>
43538fd1498Szrj    constexpr bool
43638fd1498Szrj    operator==(basic_string_view<_CharT, _Traits> __x,
43738fd1498Szrj               basic_string_view<_CharT, _Traits> __y) noexcept
43838fd1498Szrj    { return __x.size() == __y.size() && __x.compare(__y) == 0; }
43938fd1498Szrj
44038fd1498Szrj  template<typename _CharT, typename _Traits>
44138fd1498Szrj    constexpr bool
44238fd1498Szrj    operator==(basic_string_view<_CharT, _Traits> __x,
44338fd1498Szrj               __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
44438fd1498Szrj    { return __x.size() == __y.size() && __x.compare(__y) == 0; }
44538fd1498Szrj
44638fd1498Szrj  template<typename _CharT, typename _Traits>
44738fd1498Szrj    constexpr bool
44838fd1498Szrj    operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
44938fd1498Szrj               basic_string_view<_CharT, _Traits> __y) noexcept
45038fd1498Szrj    { return __x.size() == __y.size() && __x.compare(__y) == 0; }
45138fd1498Szrj
45238fd1498Szrj  template<typename _CharT, typename _Traits>
45338fd1498Szrj    constexpr bool
45438fd1498Szrj    operator!=(basic_string_view<_CharT, _Traits> __x,
45538fd1498Szrj               basic_string_view<_CharT, _Traits> __y) noexcept
45638fd1498Szrj    { return !(__x == __y); }
45738fd1498Szrj
45838fd1498Szrj  template<typename _CharT, typename _Traits>
45938fd1498Szrj    constexpr bool
46038fd1498Szrj    operator!=(basic_string_view<_CharT, _Traits> __x,
46138fd1498Szrj               __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
46238fd1498Szrj    { return !(__x == __y); }
46338fd1498Szrj
46438fd1498Szrj  template<typename _CharT, typename _Traits>
46538fd1498Szrj    constexpr bool
46638fd1498Szrj    operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
46738fd1498Szrj               basic_string_view<_CharT, _Traits> __y) noexcept
46838fd1498Szrj    { return !(__x == __y); }
46938fd1498Szrj
47038fd1498Szrj  template<typename _CharT, typename _Traits>
47138fd1498Szrj    constexpr bool
47238fd1498Szrj    operator< (basic_string_view<_CharT, _Traits> __x,
47338fd1498Szrj               basic_string_view<_CharT, _Traits> __y) noexcept
47438fd1498Szrj    { return __x.compare(__y) < 0; }
47538fd1498Szrj
47638fd1498Szrj  template<typename _CharT, typename _Traits>
47738fd1498Szrj    constexpr bool
47838fd1498Szrj    operator< (basic_string_view<_CharT, _Traits> __x,
47938fd1498Szrj               __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
48038fd1498Szrj    { return __x.compare(__y) < 0; }
48138fd1498Szrj
48238fd1498Szrj  template<typename _CharT, typename _Traits>
48338fd1498Szrj    constexpr bool
48438fd1498Szrj    operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
48538fd1498Szrj               basic_string_view<_CharT, _Traits> __y) noexcept
48638fd1498Szrj    { return __x.compare(__y) < 0; }
48738fd1498Szrj
48838fd1498Szrj  template<typename _CharT, typename _Traits>
48938fd1498Szrj    constexpr bool
49038fd1498Szrj    operator> (basic_string_view<_CharT, _Traits> __x,
49138fd1498Szrj               basic_string_view<_CharT, _Traits> __y) noexcept
49238fd1498Szrj    { return __x.compare(__y) > 0; }
49338fd1498Szrj
49438fd1498Szrj  template<typename _CharT, typename _Traits>
49538fd1498Szrj    constexpr bool
49638fd1498Szrj    operator> (basic_string_view<_CharT, _Traits> __x,
49738fd1498Szrj               __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
49838fd1498Szrj    { return __x.compare(__y) > 0; }
49938fd1498Szrj
50038fd1498Szrj  template<typename _CharT, typename _Traits>
50138fd1498Szrj    constexpr bool
50238fd1498Szrj    operator> (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
50338fd1498Szrj               basic_string_view<_CharT, _Traits> __y) noexcept
50438fd1498Szrj    { return __x.compare(__y) > 0; }
50538fd1498Szrj
50638fd1498Szrj  template<typename _CharT, typename _Traits>
50738fd1498Szrj    constexpr bool
50838fd1498Szrj    operator<=(basic_string_view<_CharT, _Traits> __x,
50938fd1498Szrj               basic_string_view<_CharT, _Traits> __y) noexcept
51038fd1498Szrj    { return __x.compare(__y) <= 0; }
51138fd1498Szrj
51238fd1498Szrj  template<typename _CharT, typename _Traits>
51338fd1498Szrj    constexpr bool
51438fd1498Szrj    operator<=(basic_string_view<_CharT, _Traits> __x,
51538fd1498Szrj               __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
51638fd1498Szrj    { return __x.compare(__y) <= 0; }
51738fd1498Szrj
51838fd1498Szrj  template<typename _CharT, typename _Traits>
51938fd1498Szrj    constexpr bool
52038fd1498Szrj    operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
52138fd1498Szrj               basic_string_view<_CharT, _Traits> __y) noexcept
52238fd1498Szrj    { return __x.compare(__y) <= 0; }
52338fd1498Szrj
52438fd1498Szrj  template<typename _CharT, typename _Traits>
52538fd1498Szrj    constexpr bool
52638fd1498Szrj    operator>=(basic_string_view<_CharT, _Traits> __x,
52738fd1498Szrj               basic_string_view<_CharT, _Traits> __y) noexcept
52838fd1498Szrj    { return __x.compare(__y) >= 0; }
52938fd1498Szrj
53038fd1498Szrj  template<typename _CharT, typename _Traits>
53138fd1498Szrj    constexpr bool
53238fd1498Szrj    operator>=(basic_string_view<_CharT, _Traits> __x,
53338fd1498Szrj               __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
53438fd1498Szrj    { return __x.compare(__y) >= 0; }
53538fd1498Szrj
53638fd1498Szrj  template<typename _CharT, typename _Traits>
53738fd1498Szrj    constexpr bool
53838fd1498Szrj    operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
53938fd1498Szrj               basic_string_view<_CharT, _Traits> __y) noexcept
54038fd1498Szrj    { return __x.compare(__y) >= 0; }
54138fd1498Szrj
54238fd1498Szrj  // [string.view.io], Inserters and extractors
54338fd1498Szrj  template<typename _CharT, typename _Traits>
54438fd1498Szrj    inline basic_ostream<_CharT, _Traits>&
54538fd1498Szrj    operator<<(basic_ostream<_CharT, _Traits>& __os,
54638fd1498Szrj	       basic_string_view<_CharT,_Traits> __str)
54738fd1498Szrj    { return __ostream_insert(__os, __str.data(), __str.size()); }
54838fd1498Szrj
54938fd1498Szrj
55038fd1498Szrj  // basic_string_view typedef names
55138fd1498Szrj
55238fd1498Szrj  using string_view = basic_string_view<char>;
55338fd1498Szrj#ifdef _GLIBCXX_USE_WCHAR_T
55438fd1498Szrj  using wstring_view = basic_string_view<wchar_t>;
55538fd1498Szrj#endif
55638fd1498Szrj#ifdef _GLIBCXX_USE_C99_STDINT_TR1
55738fd1498Szrj  using u16string_view = basic_string_view<char16_t>;
55838fd1498Szrj  using u32string_view = basic_string_view<char32_t>;
55938fd1498Szrj#endif
56038fd1498Szrj
56138fd1498Szrj  // [string.view.hash], hash support:
56238fd1498Szrj
56338fd1498Szrj  template<typename _Tp>
56438fd1498Szrj    struct hash;
56538fd1498Szrj
56638fd1498Szrj  template<>
56738fd1498Szrj    struct hash<string_view>
56838fd1498Szrj    : public __hash_base<size_t, string_view>
56938fd1498Szrj    {
57038fd1498Szrj      size_t
57138fd1498Szrj      operator()(const string_view& __str) const noexcept
57238fd1498Szrj      { return std::_Hash_impl::hash(__str.data(), __str.length()); }
57338fd1498Szrj    };
57438fd1498Szrj
57538fd1498Szrj  template<>
57638fd1498Szrj    struct __is_fast_hash<hash<string_view>> : std::false_type
57738fd1498Szrj    { };
57838fd1498Szrj
57938fd1498Szrj#ifdef _GLIBCXX_USE_WCHAR_T
58038fd1498Szrj  template<>
58138fd1498Szrj    struct hash<wstring_view>
58238fd1498Szrj    : public __hash_base<size_t, wstring>
58338fd1498Szrj    {
58438fd1498Szrj      size_t
58538fd1498Szrj      operator()(const wstring_view& __s) const noexcept
58638fd1498Szrj      { return std::_Hash_impl::hash(__s.data(),
58738fd1498Szrj                                     __s.length() * sizeof(wchar_t)); }
58838fd1498Szrj    };
58938fd1498Szrj
59038fd1498Szrj  template<>
59138fd1498Szrj    struct __is_fast_hash<hash<wstring_view>> : std::false_type
59238fd1498Szrj    { };
59338fd1498Szrj#endif
59438fd1498Szrj
59538fd1498Szrj#ifdef _GLIBCXX_USE_C99_STDINT_TR1
59638fd1498Szrj  template<>
59738fd1498Szrj    struct hash<u16string_view>
59838fd1498Szrj    : public __hash_base<size_t, u16string_view>
59938fd1498Szrj    {
60038fd1498Szrj      size_t
60138fd1498Szrj      operator()(const u16string_view& __s) const noexcept
60238fd1498Szrj      { return std::_Hash_impl::hash(__s.data(),
60338fd1498Szrj                                     __s.length() * sizeof(char16_t)); }
60438fd1498Szrj    };
60538fd1498Szrj
60638fd1498Szrj  template<>
60738fd1498Szrj    struct __is_fast_hash<hash<u16string_view>> : std::false_type
60838fd1498Szrj    { };
60938fd1498Szrj
61038fd1498Szrj  template<>
61138fd1498Szrj    struct hash<u32string_view>
61238fd1498Szrj    : public __hash_base<size_t, u32string_view>
61338fd1498Szrj    {
61438fd1498Szrj      size_t
61538fd1498Szrj      operator()(const u32string_view& __s) const noexcept
61638fd1498Szrj      { return std::_Hash_impl::hash(__s.data(),
61738fd1498Szrj                                     __s.length() * sizeof(char32_t)); }
61838fd1498Szrj    };
61938fd1498Szrj
62038fd1498Szrj  template<>
62138fd1498Szrj    struct __is_fast_hash<hash<u32string_view>> : std::false_type
62238fd1498Szrj    { };
62338fd1498Szrj#endif
62438fd1498Szrj
62538fd1498Szrj  inline namespace literals
62638fd1498Szrj  {
62738fd1498Szrj  inline namespace string_view_literals
62838fd1498Szrj  {
62938fd1498Szrj#pragma GCC diagnostic push
63038fd1498Szrj#pragma GCC diagnostic ignored "-Wliteral-suffix"
63138fd1498Szrj    inline constexpr basic_string_view<char>
63238fd1498Szrj    operator""sv(const char* __str, size_t __len) noexcept
63338fd1498Szrj    { return basic_string_view<char>{__str, __len}; }
63438fd1498Szrj
63538fd1498Szrj#ifdef _GLIBCXX_USE_WCHAR_T
63638fd1498Szrj    inline constexpr basic_string_view<wchar_t>
63738fd1498Szrj    operator""sv(const wchar_t* __str, size_t __len) noexcept
63838fd1498Szrj    { return basic_string_view<wchar_t>{__str, __len}; }
63938fd1498Szrj#endif
64038fd1498Szrj
64138fd1498Szrj#ifdef _GLIBCXX_USE_C99_STDINT_TR1
64238fd1498Szrj    inline constexpr basic_string_view<char16_t>
64338fd1498Szrj    operator""sv(const char16_t* __str, size_t __len) noexcept
64438fd1498Szrj    { return basic_string_view<char16_t>{__str, __len}; }
64538fd1498Szrj
64638fd1498Szrj    inline constexpr basic_string_view<char32_t>
64738fd1498Szrj    operator""sv(const char32_t* __str, size_t __len) noexcept
64838fd1498Szrj    { return basic_string_view<char32_t>{__str, __len}; }
64938fd1498Szrj#endif
65038fd1498Szrj#pragma GCC diagnostic pop
65138fd1498Szrj  } // namespace string_literals
65238fd1498Szrj  } // namespace literals
65338fd1498Szrj
65438fd1498Szrj_GLIBCXX_END_NAMESPACE_VERSION
65538fd1498Szrj} // namespace std
65638fd1498Szrj
65738fd1498Szrj#include <bits/string_view.tcc>
65838fd1498Szrj
65938fd1498Szrj#endif // __cplusplus <= 201402L
66038fd1498Szrj
66138fd1498Szrj#endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW
662