]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libc++/include/string_view
MFV r316929: 6914 kernel virtual memory fragmentation leads to hang
[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 clear() noexcept;
107       constexpr void remove_prefix(size_type n);
108       constexpr void remove_suffix(size_type n);
109       constexpr void swap(basic_string_view& s) noexcept;
110
111       size_type copy(charT* s, size_type n, size_type pos = 0) const;
112
113       constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
114       constexpr int compare(basic_string_view s) const noexcept;
115       constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;
116       constexpr int compare(size_type pos1, size_type n1,
117                             basic_string_view s, size_type pos2, size_type n2) const;
118       constexpr int compare(const charT* s) const;
119       constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
120       constexpr int compare(size_type pos1, size_type n1,
121                             const charT* s, size_type n2) const;
122       constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;
123       constexpr size_type find(charT c, size_type pos = 0) const noexcept;
124       constexpr size_type find(const charT* s, size_type pos, size_type n) const;
125       constexpr size_type find(const charT* s, size_type pos = 0) const;
126       constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;
127       constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;
128       constexpr size_type rfind(const charT* s, size_type pos, size_type n) const;
129       constexpr size_type rfind(const charT* s, size_type pos = npos) const;
130       constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;
131       constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;
132       constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const;
133       constexpr size_type find_first_of(const charT* s, size_type pos = 0) const;
134       constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;
135       constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;
136       constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const;
137       constexpr size_type find_last_of(const charT* s, size_type pos = npos) const;
138       constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;
139       constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;
140       constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const;
141       constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const;
142       constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept;
143       constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;
144       constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const;
145       constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const;
146
147      private:
148       const_pointer data_;  // exposition only
149       size_type     size_;  // exposition only
150     };
151
152   // 7.11, Hash support
153   template <class T> struct hash;
154   template <> struct hash<string_view>;
155   template <> struct hash<u16string_view>;
156   template <> struct hash<u32string_view>;
157   template <> struct hash<wstring_view>;
158
159   constexpr basic_string<char>     operator "" s( const char *str,     size_t len ); // C++17
160   constexpr basic_string<wchar_t>  operator "" s( const wchar_t *str,  size_t len ); // C++17
161   constexpr basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++17
162   constexpr basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++17
163
164 }  // namespace std
165
166
167 */
168
169 #include <__config>
170
171 #include <__string>
172 #include <algorithm>
173 #include <iterator>
174 #include <limits>
175 #include <stdexcept>
176 #include <__debug>
177
178 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
179 #pragma GCC system_header
180 #endif
181
182 _LIBCPP_BEGIN_NAMESPACE_STD
183
184 template<class _CharT, class _Traits = char_traits<_CharT> >
185 class _LIBCPP_TEMPLATE_VIS basic_string_view {
186 public:
187         // types
188         typedef _Traits                                    traits_type;
189         typedef _CharT                                     value_type;
190         typedef const _CharT*                              pointer;
191         typedef const _CharT*                              const_pointer;
192         typedef const _CharT&                              reference;
193         typedef const _CharT&                              const_reference;
194         typedef const_pointer                              const_iterator; // See [string.view.iterators]
195         typedef const_iterator                             iterator;
196         typedef _VSTD::reverse_iterator<const_iterator>    const_reverse_iterator;
197         typedef const_reverse_iterator                     reverse_iterator;
198         typedef size_t                                     size_type;
199         typedef ptrdiff_t                                  difference_type;
200         static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1);
201
202         // [string.view.cons], construct/copy
203         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
204         basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {}
205
206         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
207         basic_string_view(const basic_string_view&) _NOEXCEPT = default;
208
209         _LIBCPP_INLINE_VISIBILITY
210         basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
211
212         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
213         basic_string_view(const _CharT* __s, size_type __len)
214                 : __data(__s), __size(__len)
215         {
216 // #if _LIBCPP_STD_VER > 11
217 //         _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr");
218 // #endif
219         }
220
221         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
222         basic_string_view(const _CharT* __s)
223                 : __data(__s), __size(_Traits::length(__s)) {}
224
225         // [string.view.iterators], iterators
226         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
227         const_iterator begin()  const _NOEXCEPT { return cbegin(); }
228
229         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
230         const_iterator end()    const _NOEXCEPT { return cend(); }
231
232         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
233         const_iterator cbegin() const _NOEXCEPT { return __data; }
234
235         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
236         const_iterator cend()   const _NOEXCEPT { return __data + __size; }
237
238         _LIBCPP_INLINE_VISIBILITY
239         const_reverse_iterator rbegin()   const _NOEXCEPT { return const_reverse_iterator(cend()); }
240
241         _LIBCPP_INLINE_VISIBILITY
242         const_reverse_iterator rend()     const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
243
244         _LIBCPP_INLINE_VISIBILITY
245         const_reverse_iterator crbegin()  const _NOEXCEPT { return const_reverse_iterator(cend()); }
246
247         _LIBCPP_INLINE_VISIBILITY
248         const_reverse_iterator crend()    const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
249
250         // [string.view.capacity], capacity
251         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
252         size_type size()     const _NOEXCEPT { return __size; }
253
254         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
255         size_type length()   const _NOEXCEPT { return __size; }
256
257         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
258         size_type max_size() const _NOEXCEPT { return numeric_limits<size_type>::max(); }
259
260         _LIBCPP_CONSTEXPR bool _LIBCPP_INLINE_VISIBILITY
261         empty()         const _NOEXCEPT { return __size == 0; }
262
263         // [string.view.access], element access
264         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
265         const_reference operator[](size_type __pos) const _NOEXCEPT { return __data[__pos]; }
266
267         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
268         const_reference at(size_type __pos) const
269         {
270                 return __pos >= size()
271                         ? (__throw_out_of_range("string_view::at"), __data[0])
272                         : __data[__pos];
273         }
274
275         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
276         const_reference front() const
277         {
278                 return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data[0];
279         }
280
281         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
282         const_reference back() const
283         {
284                 return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data[__size-1];
285         }
286
287         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
288         const_pointer data() const _NOEXCEPT { return __data; }
289
290         // [string.view.modifiers], modifiers:
291         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
292         void clear() _NOEXCEPT
293         {
294                 __data = nullptr;
295                 __size = 0;
296         }
297
298         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
299         void remove_prefix(size_type __n) _NOEXCEPT
300         {
301                 _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()");
302                 __data += __n;
303                 __size -= __n;
304         }
305
306         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
307         void remove_suffix(size_type __n) _NOEXCEPT
308         {
309                 _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()");
310                 __size -= __n;
311         }
312
313         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
314         void swap(basic_string_view& __other) _NOEXCEPT
315         {
316                 const value_type *__p = __data;
317                 __data = __other.__data;
318                 __other.__data = __p;
319
320                 size_type __sz = __size;
321                 __size = __other.__size;
322                 __other.__size = __sz;
323         }
324
325         _LIBCPP_INLINE_VISIBILITY
326         size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
327         {
328                 if (__pos > size())
329                         __throw_out_of_range("string_view::copy");
330                 size_type __rlen = _VSTD::min(__n, size() - __pos);
331                 _Traits::copy(__s, data() + __pos, __rlen);
332                 return __rlen;
333         }
334
335         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
336         basic_string_view substr(size_type __pos = 0, size_type __n = npos) const
337         {
338                 return __pos > size()
339                         ? (__throw_out_of_range("string_view::substr"), basic_string_view())
340                         : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos));
341         }
342
343         _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT
344         {
345                 size_type __rlen = _VSTD::min( size(), __sv.size());
346                 int __retval = _Traits::compare(data(), __sv.data(), __rlen);
347                 if ( __retval == 0 ) // first __rlen chars matched
348                         __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 );
349                 return __retval;
350         }
351
352         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
353         int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const
354         {
355                 return substr(__pos1, __n1).compare(__sv);
356         }
357
358         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
359         int compare(                       size_type __pos1, size_type __n1, 
360                                 basic_string_view _sv, size_type __pos2, size_type __n2) const
361         {
362                 return substr(__pos1, __n1).compare(_sv.substr(__pos2, __n2));
363         }
364
365         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
366         int compare(const _CharT* __s) const _NOEXCEPT
367         {
368                 return compare(basic_string_view(__s));
369         }
370
371         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
372         int compare(size_type __pos1, size_type __n1, const _CharT* __s) const
373         {
374                 return substr(__pos1, __n1).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, size_type __n2) const
379         {
380                 return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
381         }
382
383         // find
384         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
385         size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
386         {
387                 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
388                 return __str_find<value_type, size_type, traits_type, npos>
389                         (data(), size(), __s.data(), __pos, __s.size());
390         }
391
392         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
393         size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT
394         {
395                 return __str_find<value_type, size_type, traits_type, npos>
396                         (data(), size(), __c, __pos);
397         }
398
399         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
400         size_type find(const _CharT* __s, size_type __pos, size_type __n) const
401         {
402                 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
403                 return __str_find<value_type, size_type, traits_type, npos>
404                         (data(), size(), __s, __pos, __n);
405         }
406
407         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
408         size_type find(const _CharT* __s, size_type __pos = 0) const
409         {
410                 _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr");
411                 return __str_find<value_type, size_type, traits_type, npos>
412                         (data(), size(), __s, __pos, traits_type::length(__s));
413         }
414
415         // rfind
416         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
417         size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT
418         {
419                 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
420                 return __str_rfind<value_type, size_type, traits_type, npos>
421                         (data(), size(), __s.data(), __pos, __s.size());
422         }
423
424         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
425         size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT
426         {
427                 return __str_rfind<value_type, size_type, traits_type, npos>
428                         (data(), size(), __c, __pos);
429         }
430
431         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
432         size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const
433         {
434                 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
435                 return __str_rfind<value_type, size_type, traits_type, npos>
436                         (data(), size(), __s, __pos, __n);
437         }
438
439         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
440         size_type rfind(const _CharT* __s, size_type __pos=npos) const
441         {
442                 _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr");
443                 return __str_rfind<value_type, size_type, traits_type, npos>
444                         (data(), size(), __s, __pos, traits_type::length(__s));
445         }
446
447         // find_first_of
448         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
449         size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
450         {
451                 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
452                 return __str_find_first_of<value_type, size_type, traits_type, npos>
453                         (data(), size(), __s.data(), __pos, __s.size());
454         }
455
456         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
457         size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT
458         { return find(__c, __pos); }
459
460         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
461         size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
462         {
463                 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
464                 return __str_find_first_of<value_type, size_type, traits_type, npos>
465                         (data(), size(), __s, __pos, __n);
466         }
467
468         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
469         size_type find_first_of(const _CharT* __s, size_type __pos=0) const
470         {
471                 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr");
472                 return __str_find_first_of<value_type, size_type, traits_type, npos>
473                         (data(), size(), __s, __pos, traits_type::length(__s));
474         }
475
476         // find_last_of
477         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
478         size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
479         {
480                 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
481                 return __str_find_last_of<value_type, size_type, traits_type, npos>
482                         (data(), size(), __s.data(), __pos, __s.size());
483         }
484
485         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
486         size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT
487         { return rfind(__c, __pos); }
488
489         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
490         size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
491         {
492                 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
493                 return __str_find_last_of<value_type, size_type, traits_type, npos>
494                         (data(), size(), __s, __pos, __n);
495         }
496
497         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
498         size_type find_last_of(const _CharT* __s, size_type __pos=npos) const
499         {
500                 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr");
501                 return __str_find_last_of<value_type, size_type, traits_type, npos>
502                         (data(), size(), __s, __pos, traits_type::length(__s));
503         }
504
505         // find_first_not_of
506         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
507         size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT
508         {
509                 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
510                 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
511                         (data(), size(), __s.data(), __pos, __s.size());
512         }
513
514         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
515         size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT
516         {
517                 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
518                         (data(), size(), __c, __pos);
519         }
520
521         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
522         size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
523         {
524                 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
525                 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
526                         (data(), size(), __s, __pos, __n);
527         }
528
529         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
530         size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const
531         {
532                 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
533                 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
534                         (data(), size(), __s, __pos, traits_type::length(__s));
535         }
536
537         // find_last_not_of
538         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
539         size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
540         {
541                 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
542                 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
543                         (data(), size(), __s.data(), __pos, __s.size());
544         }
545
546         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
547         size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT
548         {
549                 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
550                         (data(), size(), __c, __pos);
551         }
552
553         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
554         size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
555         {
556                 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
557                 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
558                         (data(), size(), __s, __pos, __n);
559         }
560
561         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
562         size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const
563         {
564                 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
565                 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
566                         (data(), size(), __s, __pos, traits_type::length(__s));
567         }
568
569 private:
570         const   value_type* __data;
571         size_type           __size;
572 };
573
574
575 // [string.view.comparison]
576 // operator ==
577 template<class _CharT, class _Traits>
578 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
579 bool operator==(basic_string_view<_CharT, _Traits> __lhs,
580                                 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
581 {
582         if ( __lhs.size() != __rhs.size()) return false;
583         return __lhs.compare(__rhs) == 0;
584 }
585
586 template<class _CharT, class _Traits>
587 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
588 bool operator==(basic_string_view<_CharT, _Traits> __lhs,
589                                 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
590 {
591         if ( __lhs.size() != __rhs.size()) return false;
592         return __lhs.compare(__rhs) == 0;
593 }
594
595 template<class _CharT, class _Traits>
596 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
597 bool operator==(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
598                                 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
599 {
600         if ( __lhs.size() != __rhs.size()) return false;
601         return __lhs.compare(__rhs) == 0;
602 }
603
604
605 // operator !=
606 template<class _CharT, class _Traits>
607 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
608 bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
609 {
610         if ( __lhs.size() != __rhs.size())
611                 return true;
612         return __lhs.compare(__rhs) != 0;
613 }
614
615 template<class _CharT, class _Traits>
616 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
617 bool operator!=(basic_string_view<_CharT, _Traits> __lhs,
618                                 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
619 {
620         if ( __lhs.size() != __rhs.size())
621                 return true;
622         return __lhs.compare(__rhs) != 0;
623 }
624
625 template<class _CharT, class _Traits>
626 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
627 bool operator!=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
628                                 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
629 {
630         if ( __lhs.size() != __rhs.size())
631                 return true;
632         return __lhs.compare(__rhs) != 0;
633 }
634
635
636 // operator <
637 template<class _CharT, class _Traits>
638 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
639 bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
640 {
641         return __lhs.compare(__rhs) < 0;
642 }
643
644 template<class _CharT, class _Traits>
645 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
646 bool operator<(basic_string_view<_CharT, _Traits> __lhs,
647                                 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
648 {
649         return __lhs.compare(__rhs) < 0;
650 }
651
652 template<class _CharT, class _Traits>
653 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
654 bool operator<(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
655                                 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
656 {
657         return __lhs.compare(__rhs) < 0;
658 }
659
660
661 // operator >
662 template<class _CharT, class _Traits>
663 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
664 bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
665 {
666         return __lhs.compare(__rhs) > 0;
667 }
668
669 template<class _CharT, class _Traits>
670 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
671 bool operator>(basic_string_view<_CharT, _Traits> __lhs,
672                                 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
673 {
674         return __lhs.compare(__rhs) > 0;
675 }
676
677 template<class _CharT, class _Traits>
678 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
679 bool operator>(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
680                                 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
681 {
682         return __lhs.compare(__rhs) > 0;
683 }
684
685
686 // operator <=
687 template<class _CharT, class _Traits>
688 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
689 bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
690 {
691         return __lhs.compare(__rhs) <= 0;
692 }
693
694 template<class _CharT, class _Traits>
695 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
696 bool operator<=(basic_string_view<_CharT, _Traits> __lhs,
697                                 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
698 {
699         return __lhs.compare(__rhs) <= 0;
700 }
701
702 template<class _CharT, class _Traits>
703 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
704 bool operator<=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
705                                 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
706 {
707         return __lhs.compare(__rhs) <= 0;
708 }
709
710
711 // operator >=
712 template<class _CharT, class _Traits>
713 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
714 bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
715 {
716         return __lhs.compare(__rhs) >= 0;
717 }
718
719
720 template<class _CharT, class _Traits>
721 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
722 bool operator>=(basic_string_view<_CharT, _Traits> __lhs,
723                                 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
724 {
725         return __lhs.compare(__rhs) >= 0;
726 }
727
728 template<class _CharT, class _Traits>
729 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
730 bool operator>=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
731                                 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
732 {
733         return __lhs.compare(__rhs) >= 0;
734 }
735
736 typedef basic_string_view<char>     string_view;
737 typedef basic_string_view<char16_t> u16string_view;
738 typedef basic_string_view<char32_t> u32string_view;
739 typedef basic_string_view<wchar_t>  wstring_view;
740
741 // [string.view.hash]
742 template<class _CharT, class _Traits>
743 struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, _Traits> >
744     : public unary_function<basic_string_view<_CharT, _Traits>, size_t>
745 {
746     size_t operator()(const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT;
747 };
748
749 template<class _CharT, class _Traits>
750 size_t
751 hash<basic_string_view<_CharT, _Traits> >::operator()(
752         const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT
753 {
754     return __do_string_hash(__val.data(), __val.data() + __val.size());
755 }
756
757
758 #if _LIBCPP_STD_VER > 11 
759 inline namespace literals
760 {
761   inline namespace string_view_literals
762   {
763     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
764     basic_string_view<char> operator "" sv(const char *__str, size_t __len)
765     {
766         return basic_string_view<char> (__str, __len);
767     }
768
769     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
770     basic_string_view<wchar_t> operator "" sv(const wchar_t *__str, size_t __len)
771     {
772         return basic_string_view<wchar_t> (__str, __len);
773     }
774
775     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
776     basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len)
777     {
778         return basic_string_view<char16_t> (__str, __len);
779     }
780
781     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
782     basic_string_view<char32_t> operator "" sv(const char32_t *__str, size_t __len)
783     {
784         return basic_string_view<char32_t> (__str, __len);
785     }
786   }
787 }
788 #endif
789 _LIBCPP_END_NAMESPACE_STD
790
791 #endif // _LIBCPP_STRING_VIEW