1aed8d94eSDimitry Andric// -*- C++ -*-
2aed8d94eSDimitry Andric//===------------------------ string_view ---------------------------------===//
3aed8d94eSDimitry Andric//
4aed8d94eSDimitry Andric//                     The LLVM Compiler Infrastructure
5aed8d94eSDimitry Andric//
6aed8d94eSDimitry Andric// This file is distributed under the University of Illinois Open Source
7aed8d94eSDimitry Andric// License. See LICENSE.TXT for details.
8aed8d94eSDimitry Andric//
9aed8d94eSDimitry Andric//===----------------------------------------------------------------------===//
10aed8d94eSDimitry Andric
11aed8d94eSDimitry Andric#ifndef _LIBCPP_STRING_VIEW
12aed8d94eSDimitry Andric#define _LIBCPP_STRING_VIEW
13aed8d94eSDimitry Andric
14aed8d94eSDimitry Andric/*
15aed8d94eSDimitry Andricstring_view synopsis
16aed8d94eSDimitry Andric
17aed8d94eSDimitry Andricnamespace std {
18aed8d94eSDimitry Andric
19aed8d94eSDimitry Andric    // 7.2, Class template basic_string_view
20aed8d94eSDimitry Andric    template<class charT, class traits = char_traits<charT>>
21aed8d94eSDimitry Andric        class basic_string_view;
22aed8d94eSDimitry Andric
23aed8d94eSDimitry Andric    // 7.9, basic_string_view non-member comparison functions
24aed8d94eSDimitry Andric    template<class charT, class traits>
25aed8d94eSDimitry Andric    constexpr bool operator==(basic_string_view<charT, traits> x,
26aed8d94eSDimitry Andric                              basic_string_view<charT, traits> y) noexcept;
27aed8d94eSDimitry Andric    template<class charT, class traits>
28aed8d94eSDimitry Andric    constexpr bool operator!=(basic_string_view<charT, traits> x,
29aed8d94eSDimitry Andric                              basic_string_view<charT, traits> y) noexcept;
30aed8d94eSDimitry Andric    template<class charT, class traits>
31aed8d94eSDimitry Andric    constexpr bool operator< (basic_string_view<charT, traits> x,
32aed8d94eSDimitry Andric                                 basic_string_view<charT, traits> y) noexcept;
33aed8d94eSDimitry Andric    template<class charT, class traits>
34aed8d94eSDimitry Andric    constexpr bool operator> (basic_string_view<charT, traits> x,
35aed8d94eSDimitry Andric                              basic_string_view<charT, traits> y) noexcept;
36aed8d94eSDimitry Andric    template<class charT, class traits>
37aed8d94eSDimitry Andric    constexpr bool operator<=(basic_string_view<charT, traits> x,
38aed8d94eSDimitry Andric                                 basic_string_view<charT, traits> y) noexcept;
39aed8d94eSDimitry Andric    template<class charT, class traits>
40aed8d94eSDimitry Andric    constexpr bool operator>=(basic_string_view<charT, traits> x,
41aed8d94eSDimitry Andric                              basic_string_view<charT, traits> y) noexcept;
42aed8d94eSDimitry Andric    // see below, sufficient additional overloads of comparison functions
43aed8d94eSDimitry Andric
44aed8d94eSDimitry Andric    // 7.10, Inserters and extractors
45aed8d94eSDimitry Andric    template<class charT, class traits>
46aed8d94eSDimitry Andric      basic_ostream<charT, traits>&
47aed8d94eSDimitry Andric        operator<<(basic_ostream<charT, traits>& os,
48aed8d94eSDimitry Andric                   basic_string_view<charT, traits> str);
49aed8d94eSDimitry Andric
50aed8d94eSDimitry Andric    // basic_string_view typedef names
51aed8d94eSDimitry Andric    typedef basic_string_view<char> string_view;
52aed8d94eSDimitry Andric    typedef basic_string_view<char16_t> u16string_view;
53aed8d94eSDimitry Andric    typedef basic_string_view<char32_t> u32string_view;
54aed8d94eSDimitry Andric    typedef basic_string_view<wchar_t> wstring_view;
55aed8d94eSDimitry Andric
56aed8d94eSDimitry Andric    template<class charT, class traits = char_traits<charT>>
57aed8d94eSDimitry Andric    class basic_string_view {
58aed8d94eSDimitry Andric      public:
59aed8d94eSDimitry Andric      // types
60aed8d94eSDimitry Andric      typedef traits traits_type;
61aed8d94eSDimitry Andric      typedef charT value_type;
62aed8d94eSDimitry Andric      typedef charT* pointer;
63aed8d94eSDimitry Andric      typedef const charT* const_pointer;
64aed8d94eSDimitry Andric      typedef charT& reference;
65aed8d94eSDimitry Andric      typedef const charT& const_reference;
66aed8d94eSDimitry Andric      typedef implementation-defined const_iterator;
67aed8d94eSDimitry Andric      typedef const_iterator iterator;
68aed8d94eSDimitry Andric      typedef reverse_iterator<const_iterator> const_reverse_iterator;
69aed8d94eSDimitry Andric      typedef const_reverse_iterator reverse_iterator;
70aed8d94eSDimitry Andric      typedef size_t size_type;
71aed8d94eSDimitry Andric      typedef ptrdiff_t difference_type;
72aed8d94eSDimitry Andric      static constexpr size_type npos = size_type(-1);
73aed8d94eSDimitry Andric
74aed8d94eSDimitry Andric      // 7.3, basic_string_view constructors and assignment operators
75aed8d94eSDimitry Andric      constexpr basic_string_view() noexcept;
76aed8d94eSDimitry Andric      constexpr basic_string_view(const basic_string_view&) noexcept = default;
77aed8d94eSDimitry Andric      basic_string_view& operator=(const basic_string_view&) noexcept = default;
78aed8d94eSDimitry Andric      template<class Allocator>
79aed8d94eSDimitry Andric      constexpr basic_string_view(const charT* str);
80aed8d94eSDimitry Andric      constexpr basic_string_view(const charT* str, size_type len);
81aed8d94eSDimitry Andric
82aed8d94eSDimitry Andric      // 7.4, basic_string_view iterator support
83aed8d94eSDimitry Andric      constexpr const_iterator begin() const noexcept;
84aed8d94eSDimitry Andric      constexpr const_iterator end() const noexcept;
85aed8d94eSDimitry Andric      constexpr const_iterator cbegin() const noexcept;
86aed8d94eSDimitry Andric      constexpr const_iterator cend() const noexcept;
87aed8d94eSDimitry Andric      const_reverse_iterator rbegin() const noexcept;
88aed8d94eSDimitry Andric      const_reverse_iterator rend() const noexcept;
89aed8d94eSDimitry Andric      const_reverse_iterator crbegin() const noexcept;
90aed8d94eSDimitry Andric      const_reverse_iterator crend() const noexcept;
91aed8d94eSDimitry Andric
92aed8d94eSDimitry Andric      // 7.5, basic_string_view capacity
93aed8d94eSDimitry Andric      constexpr size_type size() const noexcept;
94aed8d94eSDimitry Andric      constexpr size_type length() const noexcept;
95aed8d94eSDimitry Andric      constexpr size_type max_size() const noexcept;
96aed8d94eSDimitry Andric      constexpr bool empty() const noexcept;
97aed8d94eSDimitry Andric
98aed8d94eSDimitry Andric      // 7.6, basic_string_view element access
99aed8d94eSDimitry Andric      constexpr const_reference operator[](size_type pos) const;
100aed8d94eSDimitry Andric      constexpr const_reference at(size_type pos) const;
101aed8d94eSDimitry Andric      constexpr const_reference front() const;
102aed8d94eSDimitry Andric      constexpr const_reference back() const;
103aed8d94eSDimitry Andric      constexpr const_pointer data() const noexcept;
104aed8d94eSDimitry Andric
105aed8d94eSDimitry Andric      // 7.7, basic_string_view modifiers
106aed8d94eSDimitry Andric      constexpr void remove_prefix(size_type n);
107aed8d94eSDimitry Andric      constexpr void remove_suffix(size_type n);
108aed8d94eSDimitry Andric      constexpr void swap(basic_string_view& s) noexcept;
109aed8d94eSDimitry Andric
110aed8d94eSDimitry Andric      size_type copy(charT* s, size_type n, size_type pos = 0) const;
111aed8d94eSDimitry Andric
112aed8d94eSDimitry Andric      constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
113aed8d94eSDimitry Andric      constexpr int compare(basic_string_view s) const noexcept;
114aed8d94eSDimitry Andric      constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;
115aed8d94eSDimitry Andric      constexpr int compare(size_type pos1, size_type n1,
116aed8d94eSDimitry Andric                            basic_string_view s, size_type pos2, size_type n2) const;
117aed8d94eSDimitry Andric      constexpr int compare(const charT* s) const;
118aed8d94eSDimitry Andric      constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
119aed8d94eSDimitry Andric      constexpr int compare(size_type pos1, size_type n1,
120aed8d94eSDimitry Andric                            const charT* s, size_type n2) const;
121aed8d94eSDimitry Andric      constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;
122aed8d94eSDimitry Andric      constexpr size_type find(charT c, size_type pos = 0) const noexcept;
123aed8d94eSDimitry Andric      constexpr size_type find(const charT* s, size_type pos, size_type n) const;
124aed8d94eSDimitry Andric      constexpr size_type find(const charT* s, size_type pos = 0) const;
125aed8d94eSDimitry Andric      constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;
126aed8d94eSDimitry Andric      constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;
127aed8d94eSDimitry Andric      constexpr size_type rfind(const charT* s, size_type pos, size_type n) const;
128aed8d94eSDimitry Andric      constexpr size_type rfind(const charT* s, size_type pos = npos) const;
129aed8d94eSDimitry Andric      constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;
130aed8d94eSDimitry Andric      constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;
131aed8d94eSDimitry Andric      constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const;
132aed8d94eSDimitry Andric      constexpr size_type find_first_of(const charT* s, size_type pos = 0) const;
133aed8d94eSDimitry Andric      constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;
134aed8d94eSDimitry Andric      constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;
135aed8d94eSDimitry Andric      constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const;
136aed8d94eSDimitry Andric      constexpr size_type find_last_of(const charT* s, size_type pos = npos) const;
137aed8d94eSDimitry Andric      constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;
138aed8d94eSDimitry Andric      constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;
139aed8d94eSDimitry Andric      constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const;
140aed8d94eSDimitry Andric      constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const;
141aed8d94eSDimitry Andric      constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept;
142aed8d94eSDimitry Andric      constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;
143aed8d94eSDimitry Andric      constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const;
144aed8d94eSDimitry Andric      constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const;
145aed8d94eSDimitry Andric
146b2c7081bSDimitry Andric      constexpr bool starts_with(basic_string_view s) const noexcept; // C++2a
147b2c7081bSDimitry Andric      constexpr bool starts_with(charT c) const noexcept;             // C++2a
148b2c7081bSDimitry Andric      constexpr bool starts_with(const charT* s) const;               // C++2a
149b2c7081bSDimitry Andric      constexpr bool ends_with(basic_string_view s) const noexcept;   // C++2a
150b2c7081bSDimitry Andric      constexpr bool ends_with(charT c) const noexcept;               // C++2a
151b2c7081bSDimitry Andric      constexpr bool ends_with(const charT* s) const;                 // C++2a
152b2c7081bSDimitry Andric
153aed8d94eSDimitry Andric     private:
154aed8d94eSDimitry Andric      const_pointer data_;  // exposition only
155aed8d94eSDimitry Andric      size_type     size_;  // exposition only
156aed8d94eSDimitry Andric    };
157aed8d94eSDimitry Andric
158aed8d94eSDimitry Andric  // 7.11, Hash support
159aed8d94eSDimitry Andric  template <class T> struct hash;
160aed8d94eSDimitry Andric  template <> struct hash<string_view>;
161aed8d94eSDimitry Andric  template <> struct hash<u16string_view>;
162aed8d94eSDimitry Andric  template <> struct hash<u32string_view>;
163aed8d94eSDimitry Andric  template <> struct hash<wstring_view>;
164aed8d94eSDimitry Andric
165b2c7081bSDimitry Andric  constexpr basic_string_view<char>     operator "" sv( const char *str,     size_t len ) noexcept;
166b2c7081bSDimitry Andric  constexpr basic_string_view<wchar_t>  operator "" sv( const wchar_t *str,  size_t len ) noexcept;
167b2c7081bSDimitry Andric  constexpr basic_string_view<char16_t> operator "" sv( const char16_t *str, size_t len ) noexcept;
168b2c7081bSDimitry Andric  constexpr basic_string_view<char32_t> operator "" sv( const char32_t *str, size_t len ) noexcept;
16980779b37SDimitry Andric
170aed8d94eSDimitry Andric}  // namespace std
171aed8d94eSDimitry Andric
172aed8d94eSDimitry Andric
173aed8d94eSDimitry Andric*/
174aed8d94eSDimitry Andric
175aed8d94eSDimitry Andric#include <__config>
176aed8d94eSDimitry Andric#include <__string>
177aed8d94eSDimitry Andric#include <algorithm>
178aed8d94eSDimitry Andric#include <iterator>
179aed8d94eSDimitry Andric#include <limits>
180aed8d94eSDimitry Andric#include <stdexcept>
181*b5893f02SDimitry Andric#include <version>
182aed8d94eSDimitry Andric#include <__debug>
183aed8d94eSDimitry Andric
184aed8d94eSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
185aed8d94eSDimitry Andric#pragma GCC system_header
186aed8d94eSDimitry Andric#endif
187aed8d94eSDimitry Andric
188f9448bf3SDimitry Andric_LIBCPP_PUSH_MACROS
189f9448bf3SDimitry Andric#include <__undef_macros>
190f9448bf3SDimitry Andric
191f9448bf3SDimitry Andric
192aed8d94eSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
193aed8d94eSDimitry Andric
194aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits = char_traits<_CharT> >
195aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS basic_string_view {
196aed8d94eSDimitry Andricpublic:
197aed8d94eSDimitry Andric    // types
198aed8d94eSDimitry Andric    typedef _Traits                                    traits_type;
199aed8d94eSDimitry Andric    typedef _CharT                                     value_type;
20039f349c2SDimitry Andric    typedef _CharT*                                    pointer;
201aed8d94eSDimitry Andric    typedef const _CharT*                              const_pointer;
20239f349c2SDimitry Andric    typedef _CharT&                                    reference;
203aed8d94eSDimitry Andric    typedef const _CharT&                              const_reference;
204aed8d94eSDimitry Andric    typedef const_pointer                              const_iterator; // See [string.view.iterators]
205aed8d94eSDimitry Andric    typedef const_iterator                             iterator;
206aed8d94eSDimitry Andric    typedef _VSTD::reverse_iterator<const_iterator>    const_reverse_iterator;
207aed8d94eSDimitry Andric    typedef const_reverse_iterator                     reverse_iterator;
208aed8d94eSDimitry Andric    typedef size_t                                     size_type;
209aed8d94eSDimitry Andric    typedef ptrdiff_t                                  difference_type;
210aed8d94eSDimitry Andric    static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1);
211aed8d94eSDimitry Andric
2124ba319b5SDimitry Andric    static_assert((!is_array<value_type>::value), "Character type of basic_string_view must not be an array");
2134ba319b5SDimitry Andric    static_assert(( is_standard_layout<value_type>::value), "Character type of basic_string_view must be standard-layout");
2144ba319b5SDimitry Andric    static_assert(( is_trivial<value_type>::value), "Character type of basic_string_view must be trivial");
215540d2a8bSDimitry Andric    static_assert((is_same<_CharT, typename traits_type::char_type>::value),
216540d2a8bSDimitry Andric                  "traits_type::char_type must be the same type as CharT");
217540d2a8bSDimitry Andric
218aed8d94eSDimitry Andric    // [string.view.cons], construct/copy
219aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
220aed8d94eSDimitry Andric    basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {}
221aed8d94eSDimitry Andric
222aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
223aed8d94eSDimitry Andric    basic_string_view(const basic_string_view&) _NOEXCEPT = default;
224aed8d94eSDimitry Andric
225540d2a8bSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
226aed8d94eSDimitry Andric    basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
227aed8d94eSDimitry Andric
228aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
229b2c7081bSDimitry Andric    basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT
230aed8d94eSDimitry Andric        : __data(__s), __size(__len)
231aed8d94eSDimitry Andric    {
232aed8d94eSDimitry Andric// #if _LIBCPP_STD_VER > 11
233aed8d94eSDimitry Andric//         _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr");
234aed8d94eSDimitry Andric// #endif
235aed8d94eSDimitry Andric    }
236aed8d94eSDimitry Andric
237aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
238aed8d94eSDimitry Andric    basic_string_view(const _CharT* __s)
239aed8d94eSDimitry Andric        : __data(__s), __size(_Traits::length(__s)) {}
240aed8d94eSDimitry Andric
241aed8d94eSDimitry Andric    // [string.view.iterators], iterators
242aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
243aed8d94eSDimitry Andric    const_iterator begin()  const _NOEXCEPT { return cbegin(); }
244aed8d94eSDimitry Andric
245aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
246aed8d94eSDimitry Andric    const_iterator end()    const _NOEXCEPT { return cend(); }
247aed8d94eSDimitry Andric
248aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
249aed8d94eSDimitry Andric    const_iterator cbegin() const _NOEXCEPT { return __data; }
250aed8d94eSDimitry Andric
251aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
252aed8d94eSDimitry Andric    const_iterator cend()   const _NOEXCEPT { return __data + __size; }
253aed8d94eSDimitry Andric
254540d2a8bSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
255aed8d94eSDimitry Andric    const_reverse_iterator rbegin()   const _NOEXCEPT { return const_reverse_iterator(cend()); }
256aed8d94eSDimitry Andric
257540d2a8bSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
258aed8d94eSDimitry Andric    const_reverse_iterator rend()     const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
259aed8d94eSDimitry Andric
260540d2a8bSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
261aed8d94eSDimitry Andric    const_reverse_iterator crbegin()  const _NOEXCEPT { return const_reverse_iterator(cend()); }
262aed8d94eSDimitry Andric
263540d2a8bSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
264aed8d94eSDimitry Andric    const_reverse_iterator crend()    const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
265aed8d94eSDimitry Andric
266aed8d94eSDimitry Andric    // [string.view.capacity], capacity
267aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
268aed8d94eSDimitry Andric    size_type size()     const _NOEXCEPT { return __size; }
269aed8d94eSDimitry Andric
270aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
271aed8d94eSDimitry Andric    size_type length()   const _NOEXCEPT { return __size; }
272aed8d94eSDimitry Andric
273aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
274aed8d94eSDimitry Andric    size_type max_size() const _NOEXCEPT { return numeric_limits<size_type>::max(); }
275aed8d94eSDimitry Andric
276b2c7081bSDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
277b2c7081bSDimitry Andric    bool empty()         const _NOEXCEPT { return __size == 0; }
278aed8d94eSDimitry Andric
279aed8d94eSDimitry Andric    // [string.view.access], element access
280aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
281aed8d94eSDimitry Andric    const_reference operator[](size_type __pos) const _NOEXCEPT { return __data[__pos]; }
282aed8d94eSDimitry Andric
283aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
284aed8d94eSDimitry Andric    const_reference at(size_type __pos) const
285aed8d94eSDimitry Andric    {
286aed8d94eSDimitry Andric        return __pos >= size()
287aed8d94eSDimitry Andric            ? (__throw_out_of_range("string_view::at"), __data[0])
288aed8d94eSDimitry Andric            : __data[__pos];
289aed8d94eSDimitry Andric    }
290aed8d94eSDimitry Andric
291aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
292aed8d94eSDimitry Andric    const_reference front() const
293aed8d94eSDimitry Andric    {
294aed8d94eSDimitry Andric        return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data[0];
295aed8d94eSDimitry Andric    }
296aed8d94eSDimitry Andric
297aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
298aed8d94eSDimitry Andric    const_reference back() const
299aed8d94eSDimitry Andric    {
300aed8d94eSDimitry Andric        return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data[__size-1];
301aed8d94eSDimitry Andric    }
302aed8d94eSDimitry Andric
303aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
304aed8d94eSDimitry Andric    const_pointer data() const _NOEXCEPT { return __data; }
305aed8d94eSDimitry Andric
306aed8d94eSDimitry Andric    // [string.view.modifiers], modifiers:
307aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
308aed8d94eSDimitry Andric    void remove_prefix(size_type __n) _NOEXCEPT
309aed8d94eSDimitry Andric    {
310aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()");
311aed8d94eSDimitry Andric        __data += __n;
312aed8d94eSDimitry Andric        __size -= __n;
313aed8d94eSDimitry Andric    }
314aed8d94eSDimitry Andric
315aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
316aed8d94eSDimitry Andric    void remove_suffix(size_type __n) _NOEXCEPT
317aed8d94eSDimitry Andric    {
318aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()");
319aed8d94eSDimitry Andric        __size -= __n;
320aed8d94eSDimitry Andric    }
321aed8d94eSDimitry Andric
322aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
323aed8d94eSDimitry Andric    void swap(basic_string_view& __other) _NOEXCEPT
324aed8d94eSDimitry Andric    {
325aed8d94eSDimitry Andric        const value_type *__p = __data;
326aed8d94eSDimitry Andric        __data = __other.__data;
327aed8d94eSDimitry Andric        __other.__data = __p;
328aed8d94eSDimitry Andric
329aed8d94eSDimitry Andric        size_type __sz = __size;
330aed8d94eSDimitry Andric        __size = __other.__size;
331aed8d94eSDimitry Andric        __other.__size = __sz;
332aed8d94eSDimitry Andric    }
333aed8d94eSDimitry Andric
334aed8d94eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
335aed8d94eSDimitry Andric    size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
336aed8d94eSDimitry Andric    {
337aed8d94eSDimitry Andric        if (__pos > size())
338aed8d94eSDimitry Andric            __throw_out_of_range("string_view::copy");
339aed8d94eSDimitry Andric        size_type __rlen = _VSTD::min(__n, size() - __pos);
340aed8d94eSDimitry Andric        _Traits::copy(__s, data() + __pos, __rlen);
341aed8d94eSDimitry Andric        return __rlen;
342aed8d94eSDimitry Andric    }
343aed8d94eSDimitry Andric
344aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
345aed8d94eSDimitry Andric    basic_string_view substr(size_type __pos = 0, size_type __n = npos) const
346aed8d94eSDimitry Andric    {
347aed8d94eSDimitry Andric        return __pos > size()
348aed8d94eSDimitry Andric            ? (__throw_out_of_range("string_view::substr"), basic_string_view())
349aed8d94eSDimitry Andric            : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos));
350aed8d94eSDimitry Andric    }
351aed8d94eSDimitry Andric
352aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT
353aed8d94eSDimitry Andric    {
354aed8d94eSDimitry Andric        size_type __rlen = _VSTD::min( size(), __sv.size());
355aed8d94eSDimitry Andric        int __retval = _Traits::compare(data(), __sv.data(), __rlen);
356aed8d94eSDimitry Andric        if ( __retval == 0 ) // first __rlen chars matched
357aed8d94eSDimitry Andric            __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 );
358aed8d94eSDimitry Andric        return __retval;
359aed8d94eSDimitry Andric    }
360aed8d94eSDimitry Andric
361aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
362aed8d94eSDimitry Andric    int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const
363aed8d94eSDimitry Andric    {
364aed8d94eSDimitry Andric        return substr(__pos1, __n1).compare(__sv);
365aed8d94eSDimitry Andric    }
366aed8d94eSDimitry Andric
367aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
368aed8d94eSDimitry Andric    int compare(                       size_type __pos1, size_type __n1,
369f9448bf3SDimitry Andric                basic_string_view __sv, size_type __pos2, size_type __n2) const
370aed8d94eSDimitry Andric    {
371f9448bf3SDimitry Andric        return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
372aed8d94eSDimitry Andric    }
373aed8d94eSDimitry Andric
374aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
375aed8d94eSDimitry Andric    int compare(const _CharT* __s) const _NOEXCEPT
376aed8d94eSDimitry Andric    {
377aed8d94eSDimitry Andric        return compare(basic_string_view(__s));
378aed8d94eSDimitry Andric    }
379aed8d94eSDimitry Andric
380aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
381aed8d94eSDimitry Andric    int compare(size_type __pos1, size_type __n1, const _CharT* __s) const
382aed8d94eSDimitry Andric    {
383aed8d94eSDimitry Andric        return substr(__pos1, __n1).compare(basic_string_view(__s));
384aed8d94eSDimitry Andric    }
385aed8d94eSDimitry Andric
386aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
387aed8d94eSDimitry Andric    int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
388aed8d94eSDimitry Andric    {
389aed8d94eSDimitry Andric        return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
390aed8d94eSDimitry Andric    }
391aed8d94eSDimitry Andric
392aed8d94eSDimitry Andric    // find
393aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
394aed8d94eSDimitry Andric    size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
395aed8d94eSDimitry Andric    {
396aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
397aed8d94eSDimitry Andric        return __str_find<value_type, size_type, traits_type, npos>
398aed8d94eSDimitry Andric            (data(), size(), __s.data(), __pos, __s.size());
399aed8d94eSDimitry Andric    }
400aed8d94eSDimitry Andric
401aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
402aed8d94eSDimitry Andric    size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT
403aed8d94eSDimitry Andric    {
404aed8d94eSDimitry Andric        return __str_find<value_type, size_type, traits_type, npos>
405aed8d94eSDimitry Andric            (data(), size(), __c, __pos);
406aed8d94eSDimitry Andric    }
407aed8d94eSDimitry Andric
408aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
409aed8d94eSDimitry Andric    size_type find(const _CharT* __s, size_type __pos, size_type __n) const
410aed8d94eSDimitry Andric    {
411aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
412aed8d94eSDimitry Andric        return __str_find<value_type, size_type, traits_type, npos>
413aed8d94eSDimitry Andric            (data(), size(), __s, __pos, __n);
414aed8d94eSDimitry Andric    }
415aed8d94eSDimitry Andric
416aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
417aed8d94eSDimitry Andric    size_type find(const _CharT* __s, size_type __pos = 0) const
418aed8d94eSDimitry Andric    {
419aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr");
420aed8d94eSDimitry Andric        return __str_find<value_type, size_type, traits_type, npos>
421aed8d94eSDimitry Andric            (data(), size(), __s, __pos, traits_type::length(__s));
422aed8d94eSDimitry Andric    }
423aed8d94eSDimitry Andric
424aed8d94eSDimitry Andric    // rfind
425aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
426aed8d94eSDimitry Andric    size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT
427aed8d94eSDimitry Andric    {
428aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
429aed8d94eSDimitry Andric        return __str_rfind<value_type, size_type, traits_type, npos>
430aed8d94eSDimitry Andric            (data(), size(), __s.data(), __pos, __s.size());
431aed8d94eSDimitry Andric    }
432aed8d94eSDimitry Andric
433aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
434aed8d94eSDimitry Andric    size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT
435aed8d94eSDimitry Andric    {
436aed8d94eSDimitry Andric        return __str_rfind<value_type, size_type, traits_type, npos>
437aed8d94eSDimitry Andric            (data(), size(), __c, __pos);
438aed8d94eSDimitry Andric    }
439aed8d94eSDimitry Andric
440aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
441aed8d94eSDimitry Andric    size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const
442aed8d94eSDimitry Andric    {
443aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
444aed8d94eSDimitry Andric        return __str_rfind<value_type, size_type, traits_type, npos>
445aed8d94eSDimitry Andric            (data(), size(), __s, __pos, __n);
446aed8d94eSDimitry Andric    }
447aed8d94eSDimitry Andric
448aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
449aed8d94eSDimitry Andric    size_type rfind(const _CharT* __s, size_type __pos=npos) const
450aed8d94eSDimitry Andric    {
451aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr");
452aed8d94eSDimitry Andric        return __str_rfind<value_type, size_type, traits_type, npos>
453aed8d94eSDimitry Andric            (data(), size(), __s, __pos, traits_type::length(__s));
454aed8d94eSDimitry Andric    }
455aed8d94eSDimitry Andric
456aed8d94eSDimitry Andric    // find_first_of
457aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
458aed8d94eSDimitry Andric    size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
459aed8d94eSDimitry Andric    {
460aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
461aed8d94eSDimitry Andric        return __str_find_first_of<value_type, size_type, traits_type, npos>
462aed8d94eSDimitry Andric            (data(), size(), __s.data(), __pos, __s.size());
463aed8d94eSDimitry Andric    }
464aed8d94eSDimitry Andric
465aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
466aed8d94eSDimitry Andric    size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT
467aed8d94eSDimitry Andric    { return find(__c, __pos); }
468aed8d94eSDimitry Andric
469aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
470aed8d94eSDimitry Andric    size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
471aed8d94eSDimitry Andric    {
472aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
473aed8d94eSDimitry Andric        return __str_find_first_of<value_type, size_type, traits_type, npos>
474aed8d94eSDimitry Andric            (data(), size(), __s, __pos, __n);
475aed8d94eSDimitry Andric    }
476aed8d94eSDimitry Andric
477aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
478aed8d94eSDimitry Andric    size_type find_first_of(const _CharT* __s, size_type __pos=0) const
479aed8d94eSDimitry Andric    {
480aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr");
481aed8d94eSDimitry Andric        return __str_find_first_of<value_type, size_type, traits_type, npos>
482aed8d94eSDimitry Andric            (data(), size(), __s, __pos, traits_type::length(__s));
483aed8d94eSDimitry Andric    }
484aed8d94eSDimitry Andric
485aed8d94eSDimitry Andric    // find_last_of
486aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
487aed8d94eSDimitry Andric    size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
488aed8d94eSDimitry Andric    {
489aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
490aed8d94eSDimitry Andric        return __str_find_last_of<value_type, size_type, traits_type, npos>
491aed8d94eSDimitry Andric            (data(), size(), __s.data(), __pos, __s.size());
492aed8d94eSDimitry Andric    }
493aed8d94eSDimitry Andric
494aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
495aed8d94eSDimitry Andric    size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT
496aed8d94eSDimitry Andric    { return rfind(__c, __pos); }
497aed8d94eSDimitry Andric
498aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
499aed8d94eSDimitry Andric    size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
500aed8d94eSDimitry Andric    {
501aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
502aed8d94eSDimitry Andric        return __str_find_last_of<value_type, size_type, traits_type, npos>
503aed8d94eSDimitry Andric            (data(), size(), __s, __pos, __n);
504aed8d94eSDimitry Andric    }
505aed8d94eSDimitry Andric
506aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
507aed8d94eSDimitry Andric    size_type find_last_of(const _CharT* __s, size_type __pos=npos) const
508aed8d94eSDimitry Andric    {
509aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr");
510aed8d94eSDimitry Andric        return __str_find_last_of<value_type, size_type, traits_type, npos>
511aed8d94eSDimitry Andric            (data(), size(), __s, __pos, traits_type::length(__s));
512aed8d94eSDimitry Andric    }
513aed8d94eSDimitry Andric
514aed8d94eSDimitry Andric    // find_first_not_of
515aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
516aed8d94eSDimitry Andric    size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT
517aed8d94eSDimitry Andric    {
518aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
519aed8d94eSDimitry Andric        return __str_find_first_not_of<value_type, size_type, traits_type, npos>
520aed8d94eSDimitry Andric            (data(), size(), __s.data(), __pos, __s.size());
521aed8d94eSDimitry Andric    }
522aed8d94eSDimitry Andric
523aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
524aed8d94eSDimitry Andric    size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT
525aed8d94eSDimitry Andric    {
526aed8d94eSDimitry Andric        return __str_find_first_not_of<value_type, size_type, traits_type, npos>
527aed8d94eSDimitry Andric            (data(), size(), __c, __pos);
528aed8d94eSDimitry Andric    }
529aed8d94eSDimitry Andric
530aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
531aed8d94eSDimitry Andric    size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
532aed8d94eSDimitry Andric    {
533aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
534aed8d94eSDimitry Andric        return __str_find_first_not_of<value_type, size_type, traits_type, npos>
535aed8d94eSDimitry Andric            (data(), size(), __s, __pos, __n);
536aed8d94eSDimitry Andric    }
537aed8d94eSDimitry Andric
538aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
539aed8d94eSDimitry Andric    size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const
540aed8d94eSDimitry Andric    {
541aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
542aed8d94eSDimitry Andric        return __str_find_first_not_of<value_type, size_type, traits_type, npos>
543aed8d94eSDimitry Andric            (data(), size(), __s, __pos, traits_type::length(__s));
544aed8d94eSDimitry Andric    }
545aed8d94eSDimitry Andric
546aed8d94eSDimitry Andric    // find_last_not_of
547aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
548aed8d94eSDimitry Andric    size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
549aed8d94eSDimitry Andric    {
550aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
551aed8d94eSDimitry Andric        return __str_find_last_not_of<value_type, size_type, traits_type, npos>
552aed8d94eSDimitry Andric            (data(), size(), __s.data(), __pos, __s.size());
553aed8d94eSDimitry Andric    }
554aed8d94eSDimitry Andric
555aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
556aed8d94eSDimitry Andric    size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT
557aed8d94eSDimitry Andric    {
558aed8d94eSDimitry Andric        return __str_find_last_not_of<value_type, size_type, traits_type, npos>
559aed8d94eSDimitry Andric            (data(), size(), __c, __pos);
560aed8d94eSDimitry Andric    }
561aed8d94eSDimitry Andric
562aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
563aed8d94eSDimitry Andric    size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
564aed8d94eSDimitry Andric    {
565aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
566aed8d94eSDimitry Andric        return __str_find_last_not_of<value_type, size_type, traits_type, npos>
567aed8d94eSDimitry Andric            (data(), size(), __s, __pos, __n);
568aed8d94eSDimitry Andric    }
569aed8d94eSDimitry Andric
570aed8d94eSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
571aed8d94eSDimitry Andric    size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const
572aed8d94eSDimitry Andric    {
573aed8d94eSDimitry Andric        _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
574aed8d94eSDimitry Andric        return __str_find_last_not_of<value_type, size_type, traits_type, npos>
575aed8d94eSDimitry Andric            (data(), size(), __s, __pos, traits_type::length(__s));
576aed8d94eSDimitry Andric    }
577aed8d94eSDimitry Andric
578b2c7081bSDimitry Andric#if _LIBCPP_STD_VER > 17
579b2c7081bSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
580b2c7081bSDimitry Andric    bool starts_with(basic_string_view __s) const _NOEXCEPT
581b2c7081bSDimitry Andric    { return size() >= __s.size() && compare(0, __s.size(), __s) == 0; }
582b2c7081bSDimitry Andric
583b2c7081bSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
584b2c7081bSDimitry Andric    bool starts_with(value_type __c) const _NOEXCEPT
585b2c7081bSDimitry Andric    { return !empty() && _Traits::eq(front(), __c); }
586b2c7081bSDimitry Andric
587b2c7081bSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
588b2c7081bSDimitry Andric    bool starts_with(const value_type* __s) const _NOEXCEPT
589b2c7081bSDimitry Andric    { return starts_with(basic_string_view(__s)); }
590b2c7081bSDimitry Andric
591b2c7081bSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
592b2c7081bSDimitry Andric    bool ends_with(basic_string_view __s) const _NOEXCEPT
593b2c7081bSDimitry Andric    { return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0; }
594b2c7081bSDimitry Andric
595b2c7081bSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
596b2c7081bSDimitry Andric    bool ends_with(value_type __c) const _NOEXCEPT
597b2c7081bSDimitry Andric    { return !empty() && _Traits::eq(back(), __c); }
598b2c7081bSDimitry Andric
599b2c7081bSDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
600b2c7081bSDimitry Andric    bool ends_with(const value_type* __s) const _NOEXCEPT
601b2c7081bSDimitry Andric    { return ends_with(basic_string_view(__s)); }
602b2c7081bSDimitry Andric#endif
603b2c7081bSDimitry Andric
604aed8d94eSDimitry Andricprivate:
605aed8d94eSDimitry Andric    const   value_type* __data;
606aed8d94eSDimitry Andric    size_type           __size;
607aed8d94eSDimitry Andric};
608aed8d94eSDimitry Andric
609aed8d94eSDimitry Andric
610aed8d94eSDimitry Andric// [string.view.comparison]
611aed8d94eSDimitry Andric// operator ==
612aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
613aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
614aed8d94eSDimitry Andricbool operator==(basic_string_view<_CharT, _Traits> __lhs,
615aed8d94eSDimitry Andric                basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
616aed8d94eSDimitry Andric{
617aed8d94eSDimitry Andric    if ( __lhs.size() != __rhs.size()) return false;
618aed8d94eSDimitry Andric    return __lhs.compare(__rhs) == 0;
619aed8d94eSDimitry Andric}
620aed8d94eSDimitry Andric
621aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
622aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
623aed8d94eSDimitry Andricbool operator==(basic_string_view<_CharT, _Traits> __lhs,
624aed8d94eSDimitry Andric                typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
625aed8d94eSDimitry Andric{
626aed8d94eSDimitry Andric    if ( __lhs.size() != __rhs.size()) return false;
627aed8d94eSDimitry Andric    return __lhs.compare(__rhs) == 0;
628aed8d94eSDimitry Andric}
629aed8d94eSDimitry Andric
630aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
631aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
632aed8d94eSDimitry Andricbool operator==(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
633aed8d94eSDimitry Andric                basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
634aed8d94eSDimitry Andric{
635aed8d94eSDimitry Andric    if ( __lhs.size() != __rhs.size()) return false;
636aed8d94eSDimitry Andric    return __lhs.compare(__rhs) == 0;
637aed8d94eSDimitry Andric}
638aed8d94eSDimitry Andric
639aed8d94eSDimitry Andric
640aed8d94eSDimitry Andric// operator !=
641aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
642aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
643aed8d94eSDimitry Andricbool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
644aed8d94eSDimitry Andric{
645aed8d94eSDimitry Andric    if ( __lhs.size() != __rhs.size())
646aed8d94eSDimitry Andric        return true;
647aed8d94eSDimitry Andric    return __lhs.compare(__rhs) != 0;
648aed8d94eSDimitry Andric}
649aed8d94eSDimitry Andric
650aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
651aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
652aed8d94eSDimitry Andricbool operator!=(basic_string_view<_CharT, _Traits> __lhs,
653aed8d94eSDimitry Andric                typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
654aed8d94eSDimitry Andric{
655aed8d94eSDimitry Andric    if ( __lhs.size() != __rhs.size())
656aed8d94eSDimitry Andric        return true;
657aed8d94eSDimitry Andric    return __lhs.compare(__rhs) != 0;
658aed8d94eSDimitry Andric}
659aed8d94eSDimitry Andric
660aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
661aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
662aed8d94eSDimitry Andricbool operator!=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
663aed8d94eSDimitry Andric                basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
664aed8d94eSDimitry Andric{
665aed8d94eSDimitry Andric    if ( __lhs.size() != __rhs.size())
666aed8d94eSDimitry Andric        return true;
667aed8d94eSDimitry Andric    return __lhs.compare(__rhs) != 0;
668aed8d94eSDimitry Andric}
669aed8d94eSDimitry Andric
670aed8d94eSDimitry Andric
671aed8d94eSDimitry Andric// operator <
672aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
673aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
674aed8d94eSDimitry Andricbool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
675aed8d94eSDimitry Andric{
676aed8d94eSDimitry Andric    return __lhs.compare(__rhs) < 0;
677aed8d94eSDimitry Andric}
678aed8d94eSDimitry Andric
679aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
680aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
681aed8d94eSDimitry Andricbool operator<(basic_string_view<_CharT, _Traits> __lhs,
682aed8d94eSDimitry Andric                typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
683aed8d94eSDimitry Andric{
684aed8d94eSDimitry Andric    return __lhs.compare(__rhs) < 0;
685aed8d94eSDimitry Andric}
686aed8d94eSDimitry Andric
687aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
688aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
689aed8d94eSDimitry Andricbool operator<(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
690aed8d94eSDimitry Andric                basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
691aed8d94eSDimitry Andric{
692aed8d94eSDimitry Andric    return __lhs.compare(__rhs) < 0;
693aed8d94eSDimitry Andric}
694aed8d94eSDimitry Andric
695aed8d94eSDimitry Andric
696aed8d94eSDimitry Andric// operator >
697aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
698aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
699aed8d94eSDimitry Andricbool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
700aed8d94eSDimitry Andric{
701aed8d94eSDimitry Andric    return __lhs.compare(__rhs) > 0;
702aed8d94eSDimitry Andric}
703aed8d94eSDimitry Andric
704aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
705aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
706aed8d94eSDimitry Andricbool operator>(basic_string_view<_CharT, _Traits> __lhs,
707aed8d94eSDimitry Andric                typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
708aed8d94eSDimitry Andric{
709aed8d94eSDimitry Andric    return __lhs.compare(__rhs) > 0;
710aed8d94eSDimitry Andric}
711aed8d94eSDimitry Andric
712aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
713aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
714aed8d94eSDimitry Andricbool operator>(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
715aed8d94eSDimitry Andric                basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
716aed8d94eSDimitry Andric{
717aed8d94eSDimitry Andric    return __lhs.compare(__rhs) > 0;
718aed8d94eSDimitry Andric}
719aed8d94eSDimitry Andric
720aed8d94eSDimitry Andric
721aed8d94eSDimitry Andric// operator <=
722aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
723aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
724aed8d94eSDimitry Andricbool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
725aed8d94eSDimitry Andric{
726aed8d94eSDimitry Andric    return __lhs.compare(__rhs) <= 0;
727aed8d94eSDimitry Andric}
728aed8d94eSDimitry Andric
729aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
730aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
731aed8d94eSDimitry Andricbool operator<=(basic_string_view<_CharT, _Traits> __lhs,
732aed8d94eSDimitry Andric                typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
733aed8d94eSDimitry Andric{
734aed8d94eSDimitry Andric    return __lhs.compare(__rhs) <= 0;
735aed8d94eSDimitry Andric}
736aed8d94eSDimitry Andric
737aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
738aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
739aed8d94eSDimitry Andricbool operator<=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
740aed8d94eSDimitry Andric                basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
741aed8d94eSDimitry Andric{
742aed8d94eSDimitry Andric    return __lhs.compare(__rhs) <= 0;
743aed8d94eSDimitry Andric}
744aed8d94eSDimitry Andric
745aed8d94eSDimitry Andric
746aed8d94eSDimitry Andric// operator >=
747aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
748aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
749aed8d94eSDimitry Andricbool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
750aed8d94eSDimitry Andric{
751aed8d94eSDimitry Andric    return __lhs.compare(__rhs) >= 0;
752aed8d94eSDimitry Andric}
753aed8d94eSDimitry Andric
754aed8d94eSDimitry Andric
755aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
756aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
757aed8d94eSDimitry Andricbool operator>=(basic_string_view<_CharT, _Traits> __lhs,
758aed8d94eSDimitry Andric                typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
759aed8d94eSDimitry Andric{
760aed8d94eSDimitry Andric    return __lhs.compare(__rhs) >= 0;
761aed8d94eSDimitry Andric}
762aed8d94eSDimitry Andric
763aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
764aed8d94eSDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
765aed8d94eSDimitry Andricbool operator>=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
766aed8d94eSDimitry Andric                basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
767aed8d94eSDimitry Andric{
768aed8d94eSDimitry Andric    return __lhs.compare(__rhs) >= 0;
769aed8d94eSDimitry Andric}
770aed8d94eSDimitry Andric
771aed8d94eSDimitry Andrictypedef basic_string_view<char>     string_view;
772*b5893f02SDimitry Andric#ifndef _LIBCPP_NO_HAS_CHAR8_T
773*b5893f02SDimitry Andrictypedef basic_string_view<char8_t>  u8string_view;
774*b5893f02SDimitry Andric#endif
775aed8d94eSDimitry Andrictypedef basic_string_view<char16_t> u16string_view;
776aed8d94eSDimitry Andrictypedef basic_string_view<char32_t> u32string_view;
777aed8d94eSDimitry Andrictypedef basic_string_view<wchar_t>  wstring_view;
778aed8d94eSDimitry Andric
779aed8d94eSDimitry Andric// [string.view.hash]
780aed8d94eSDimitry Andrictemplate<class _CharT, class _Traits>
781aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, _Traits> >
782aed8d94eSDimitry Andric    : public unary_function<basic_string_view<_CharT, _Traits>, size_t>
783aed8d94eSDimitry Andric{
784*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
785*b5893f02SDimitry Andric    size_t operator()(const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT {
786aed8d94eSDimitry Andric        return __do_string_hash(__val.data(), __val.data() + __val.size());
787aed8d94eSDimitry Andric    }
788*b5893f02SDimitry Andric};
789aed8d94eSDimitry Andric
79080779b37SDimitry Andric
79180779b37SDimitry Andric#if _LIBCPP_STD_VER > 11
79280779b37SDimitry Andricinline namespace literals
79380779b37SDimitry Andric{
79480779b37SDimitry Andric  inline namespace string_view_literals
79580779b37SDimitry Andric  {
79680779b37SDimitry Andric    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
797b2c7081bSDimitry Andric    basic_string_view<char> operator "" sv(const char *__str, size_t __len) _NOEXCEPT
79880779b37SDimitry Andric    {
79980779b37SDimitry Andric        return basic_string_view<char> (__str, __len);
80080779b37SDimitry Andric    }
80180779b37SDimitry Andric
80280779b37SDimitry Andric    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
803b2c7081bSDimitry Andric    basic_string_view<wchar_t> operator "" sv(const wchar_t *__str, size_t __len) _NOEXCEPT
80480779b37SDimitry Andric    {
80580779b37SDimitry Andric        return basic_string_view<wchar_t> (__str, __len);
80680779b37SDimitry Andric    }
80780779b37SDimitry Andric
808*b5893f02SDimitry Andric#ifndef _LIBCPP_NO_HAS_CHAR8_T
809*b5893f02SDimitry Andric    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
810*b5893f02SDimitry Andric    basic_string_view<char8_t> operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT
811*b5893f02SDimitry Andric    {
812*b5893f02SDimitry Andric        return basic_string_view<char8_t> (__str, __len);
813*b5893f02SDimitry Andric    }
814*b5893f02SDimitry Andric#endif
815*b5893f02SDimitry Andric
81680779b37SDimitry Andric    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
817b2c7081bSDimitry Andric    basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT
81880779b37SDimitry Andric    {
81980779b37SDimitry Andric        return basic_string_view<char16_t> (__str, __len);
82080779b37SDimitry Andric    }
82180779b37SDimitry Andric
82280779b37SDimitry Andric    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
823b2c7081bSDimitry Andric    basic_string_view<char32_t> operator "" sv(const char32_t *__str, size_t __len) _NOEXCEPT
82480779b37SDimitry Andric    {
82580779b37SDimitry Andric        return basic_string_view<char32_t> (__str, __len);
82680779b37SDimitry Andric    }
82780779b37SDimitry Andric  }
82880779b37SDimitry Andric}
82980779b37SDimitry Andric#endif
830aed8d94eSDimitry Andric_LIBCPP_END_NAMESPACE_STD
831aed8d94eSDimitry Andric
832f9448bf3SDimitry Andric_LIBCPP_POP_MACROS
833f9448bf3SDimitry Andric
834aed8d94eSDimitry Andric#endif // _LIBCPP_STRING_VIEW
835