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