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