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