]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/libc++/include/experimental/string_view
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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 <iomanip>
184
185 #include <__debug>
186
187 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
188 #pragma GCC system_header
189 #endif
190
191 _LIBCPP_BEGIN_NAMESPACE_LFTS
192
193     template<class _CharT, class _Traits = _VSTD::char_traits<_CharT> >
194     class _LIBCPP_TYPE_VIS_ONLY basic_string_view {
195     public:
196         // types
197         typedef _Traits                                    traits_type;
198         typedef _CharT                                     value_type;
199         typedef const _CharT*                              pointer;
200         typedef const _CharT*                              const_pointer;
201         typedef const _CharT&                              reference;
202         typedef const _CharT&                              const_reference;
203         typedef const_pointer                              const_iterator; // See [string.view.iterators]
204         typedef const_iterator                             iterator;
205         typedef _VSTD::reverse_iterator<const_iterator>    const_reverse_iterator;
206         typedef const_reverse_iterator                     reverse_iterator;
207         typedef size_t                                     size_type;
208         typedef ptrdiff_t                                  difference_type;
209         static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1);
210
211         // [string.view.cons], construct/copy
212         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
213         basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {}
214
215         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
216         basic_string_view(const basic_string_view&) _NOEXCEPT = default;
217
218         _LIBCPP_INLINE_VISIBILITY
219         basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
220
221         template<class _Allocator>
222         _LIBCPP_INLINE_VISIBILITY
223         basic_string_view(const basic_string<_CharT, _Traits, _Allocator>& __str) _NOEXCEPT
224             : __data (__str.data()), __size(__str.size()) {}
225
226         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
227         basic_string_view(const _CharT* __s, size_type __len)
228             : __data(__s), __size(__len)
229         {
230 //             _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): recieved nullptr");
231         }
232
233         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
234         basic_string_view(const _CharT* __s)
235             : __data(__s), __size(_Traits::length(__s)) {}
236
237         // [string.view.iterators], iterators
238         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
239         const_iterator begin()  const _NOEXCEPT { return cbegin(); }
240
241         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
242         const_iterator end()    const _NOEXCEPT { return cend(); }
243
244         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
245         const_iterator cbegin() const _NOEXCEPT { return __data; }
246
247         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
248         const_iterator cend()   const _NOEXCEPT { return __data + __size; }
249
250         _LIBCPP_INLINE_VISIBILITY
251         const_reverse_iterator rbegin()   const _NOEXCEPT { return const_reverse_iterator(cend()); }
252
253         _LIBCPP_INLINE_VISIBILITY
254         const_reverse_iterator rend()     const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
255
256         _LIBCPP_INLINE_VISIBILITY
257         const_reverse_iterator crbegin()  const _NOEXCEPT { return const_reverse_iterator(cend()); }
258
259         _LIBCPP_INLINE_VISIBILITY
260         const_reverse_iterator crend()    const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
261
262         // [string.view.capacity], capacity
263         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
264         size_type size()     const _NOEXCEPT { return __size; }
265
266         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
267         size_type length()   const _NOEXCEPT { return __size; }
268
269         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
270         size_type max_size() const _NOEXCEPT { return _VSTD::numeric_limits<size_type>::max(); }
271
272         _LIBCPP_CONSTEXPR bool _LIBCPP_INLINE_VISIBILITY
273         empty()         const _NOEXCEPT { return __size == 0; }
274
275         // [string.view.access], element access
276         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
277         const_reference operator[](size_type __pos) const { return __data[__pos]; }
278
279         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
280         const_reference at(size_type __pos) const
281         {
282             return __pos >= size()
283                 ? throw out_of_range("string_view::at")
284                 : __data[__pos];
285 //             if (__pos >= size())
286 //                 throw out_of_range("string_view::at");
287 //             return __data[__pos]; 
288         }
289
290         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
291         const_reference front() const
292         {
293             return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data[0];
294         }
295
296         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
297         const_reference back() const
298         {
299             return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data[__size-1];
300         }
301
302         _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
303         const_pointer data() const _NOEXCEPT { return __data; }
304
305         // [string.view.modifiers], modifiers:
306         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
307         void clear() _NOEXCEPT
308         {
309             __data = nullptr;
310             __size = 0;
311         }
312
313         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
314         void remove_prefix(size_type __n) _NOEXCEPT
315         {
316             _LIBCPP_ASSERT(n <= size(), "remove_prefix() can't remove more than size()");
317             __data += __n;
318             __size -= __n;
319         }
320
321         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
322         void remove_suffix(size_type __n) _NOEXCEPT
323         {
324             _LIBCPP_ASSERT(n <= size(), "remove_suffix() can't remove more than size()");
325             __size -= __n;
326         }
327
328         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
329         void swap(basic_string_view& __other) _NOEXCEPT
330         {
331             const value_type *__p = __data;
332             __data = __other.__data;
333             __other.__data = __p;
334
335             size_type __sz = __size;
336             __size = __other.__size;
337             __other.__size = __sz;
338 //             _VSTD::swap( __data, __other.__data );
339 //             _VSTD::swap( __size, __other.__size );
340         }
341
342         // [string.view.ops], string operations:
343         template<class _Allocator>
344         _LIBCPP_INLINE_VISIBILITY
345         _LIBCPP_EXPLICIT operator basic_string<_CharT, _Traits, _Allocator>() const
346         { return basic_string<_CharT, _Traits, _Allocator>( begin(), end()); }
347
348         template<class _Allocator = allocator<_CharT> >
349         _LIBCPP_INLINE_VISIBILITY
350         basic_string<_CharT, _Traits, _Allocator>
351         to_string( const _Allocator& __a = _Allocator()) const
352         { return basic_string<_CharT, _Traits, _Allocator> ( begin(), end(), __a ); }
353
354         size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
355         {
356             if ( __pos > size())
357                 throw out_of_range("string_view::copy");
358             size_type __rlen = _VSTD::min( __n, size() - __pos );
359             _VSTD::copy_n(begin() + __pos, __rlen, __s );
360             return __rlen;
361         }
362
363         _LIBCPP_CONSTEXPR
364         basic_string_view substr(size_type __pos = 0, size_type __n = npos) const
365         {
366 //             if (__pos > size())
367 //                 throw out_of_range("string_view::substr");
368 //             size_type __rlen = _VSTD::min( __n, size() - __pos );
369 //             return basic_string_view(data() + __pos, __rlen);
370             return __pos > size()
371                 ? throw out_of_range("string_view::substr")
372                 : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos));
373         }
374
375         _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT
376         {
377             size_type __rlen = _VSTD::min( size(), __sv.size());
378             int __retval = _Traits::compare(data(), __sv.data(), __rlen);
379             if ( __retval == 0 ) // first __rlen chars matched
380                 __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 );
381             return __retval;
382         }
383
384         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
385         int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const
386         {
387             return substr(__pos1, __n1).compare(__sv);
388         }
389
390         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
391         int compare(                       size_type __pos1, size_type __n1, 
392                     basic_string_view _sv, size_type __pos2, size_type __n2) const
393         {
394             return substr(__pos1, __n1).compare(_sv.substr(__pos2, __n2));
395         }
396
397         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
398         int compare(const _CharT* __s) const
399         {
400             return compare(basic_string_view(__s));
401         }
402
403         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
404         int compare(size_type __pos1, size_type __n1, const _CharT* __s) const
405         {
406             return substr(__pos1, __n1).compare(basic_string_view(__s));
407         }
408
409         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
410         int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
411         {
412             return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
413         }
414
415         // find
416         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
417         size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
418         {
419             _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): recieved nullptr");
420             return _VSTD::__str_find<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 find(_CharT __c, size_type __pos = 0) const _NOEXCEPT
426         {
427             return _VSTD::__str_find<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 find(const _CharT* __s, size_type __pos, size_type __n) const
433         {
434             _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): recieved nullptr");
435             return _VSTD::__str_find<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 find(const _CharT* __s, size_type __pos = 0) const
441         {
442             _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): recieved nullptr");
443             return _VSTD::__str_find<value_type, size_type, traits_type, npos>
444                 (data(), size(), __s, __pos, traits_type::length(__s));
445         }
446
447         // rfind
448         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
449         size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT
450         {
451             _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): recieved nullptr");
452             return _VSTD::__str_rfind<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 rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT
458         {
459             return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
460                 (data(), size(), __c, __pos);
461         }
462
463         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
464         size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const
465         {
466             _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): recieved nullptr");
467             return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
468                 (data(), size(), __s, __pos, __n);
469         }
470
471         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
472         size_type rfind(const _CharT* __s, size_type __pos=npos) const
473         {
474             _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): recieved nullptr");
475             return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
476                 (data(), size(), __s, __pos, traits_type::length(__s));
477         }
478
479         // find_first_of
480         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
481         size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
482         {
483             _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): recieved nullptr");
484             return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
485                 (data(), size(), __s.data(), __pos, __s.size());
486         }
487
488         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
489         size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT
490         { return find(__c, __pos); }
491
492         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
493         size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
494         {
495             _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): recieved nullptr");
496             return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
497                 (data(), size(), __s, __pos, __n);
498         }
499
500         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
501         size_type find_first_of(const _CharT* __s, size_type __pos=0) const
502         {
503             _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): recieved nullptr");
504             return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
505                 (data(), size(), __s, __pos, traits_type::length(__s));
506         }
507
508         // find_last_of
509         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
510         size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
511         {
512             _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): recieved nullptr");
513             return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
514                 (data(), size(), __s.data(), __pos, __s.size());
515         }
516
517         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
518         size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT
519         { return rfind(__c, __pos); }
520
521         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
522         size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
523         {
524             _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): recieved nullptr");
525             return _VSTD::__str_find_last_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_last_of(const _CharT* __s, size_type __pos=npos) const
531         {
532             _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): recieved nullptr");
533             return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
534                 (data(), size(), __s, __pos, traits_type::length(__s));
535         }
536
537         // find_first_not_of
538         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
539         size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT
540         {
541             _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): recieved nullptr");
542             return _VSTD::__str_find_first_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_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT
548         {
549             return _VSTD::__str_find_first_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_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
555         {
556             _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): recieved nullptr");
557             return _VSTD::__str_find_first_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_first_not_of(const _CharT* __s, size_type __pos=0) const
563         {
564             _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): recieved nullptr");
565             return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
566                 (data(), size(), __s, __pos, traits_type::length(__s));
567         }
568
569         // find_last_not_of
570         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
571         size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
572         {
573             _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): recieved nullptr");
574             return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
575                 (data(), size(), __s.data(), __pos, __s.size());
576         }
577
578         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
579         size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT
580         {
581             return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
582                 (data(), size(), __c, __pos);
583         }
584
585         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
586         size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
587         {
588             _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): recieved nullptr");
589             return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
590                 (data(), size(), __s, __pos, __n);
591         }
592
593         _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
594         size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const
595         {
596             _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): recieved nullptr");
597             return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
598                 (data(), size(), __s, __pos, traits_type::length(__s));
599         }
600
601     private:
602         const   value_type* __data;
603         size_type           __size;
604     };
605
606
607     // [string.view.comparison]
608     // operator ==
609     template<class _CharT, class _Traits>
610     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
611     bool operator==(basic_string_view<_CharT, _Traits> __lhs,
612                     basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
613     {
614         if ( __lhs.size() != __rhs.size()) return false;
615         return __lhs.compare(__rhs) == 0;
616     }
617
618     template<class _CharT, class _Traits>
619     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
620     bool operator==(basic_string_view<_CharT, _Traits> __lhs,
621                     typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
622     {
623         if ( __lhs.size() != __rhs.size()) return false;
624         return __lhs.compare(__rhs) == 0;
625     }
626
627     template<class _CharT, class _Traits>
628     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
629     bool operator==(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
630                     basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
631     {
632         if ( __lhs.size() != __rhs.size()) return false;
633         return __lhs.compare(__rhs) == 0;
634     }
635
636
637     // operator !=
638     template<class _CharT, class _Traits>
639     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
640     bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
641     {
642         if ( __lhs.size() != __rhs.size())
643             return true;
644         return __lhs.compare(__rhs) != 0;
645     }
646
647     template<class _CharT, class _Traits>
648     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
649     bool operator!=(basic_string_view<_CharT, _Traits> __lhs,
650                     typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
651     {
652         if ( __lhs.size() != __rhs.size())
653             return true;
654         return __lhs.compare(__rhs) != 0;
655     }
656
657     template<class _CharT, class _Traits>
658     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
659     bool operator!=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
660                     basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
661     {
662         if ( __lhs.size() != __rhs.size())
663             return true;
664         return __lhs.compare(__rhs) != 0;
665     }
666
667
668     // operator <
669     template<class _CharT, class _Traits>
670     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
671     bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
672     {
673         return __lhs.compare(__rhs) < 0;
674     }
675
676     template<class _CharT, class _Traits>
677     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
678     bool operator<(basic_string_view<_CharT, _Traits> __lhs,
679                     typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
680     {
681         return __lhs.compare(__rhs) < 0;
682     }
683
684     template<class _CharT, class _Traits>
685     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
686     bool operator<(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
687                     basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
688     {
689         return __lhs.compare(__rhs) < 0;
690     }
691
692
693     // operator >
694     template<class _CharT, class _Traits>
695     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
696     bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
697     {
698         return __lhs.compare(__rhs) > 0;
699     }
700
701     template<class _CharT, class _Traits>
702     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
703     bool operator>(basic_string_view<_CharT, _Traits> __lhs,
704                     typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
705     {
706         return __lhs.compare(__rhs) > 0;
707     }
708
709     template<class _CharT, class _Traits>
710     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
711     bool operator>(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
712                     basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
713     {
714         return __lhs.compare(__rhs) > 0;
715     }
716
717
718     // operator <=
719     template<class _CharT, class _Traits>
720     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
721     bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
722     {
723         return __lhs.compare(__rhs) <= 0;
724     }
725
726     template<class _CharT, class _Traits>
727     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
728     bool operator<=(basic_string_view<_CharT, _Traits> __lhs,
729                     typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
730     {
731         return __lhs.compare(__rhs) <= 0;
732     }
733
734     template<class _CharT, class _Traits>
735     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
736     bool operator<=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
737                     basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
738     {
739         return __lhs.compare(__rhs) <= 0;
740     }
741
742
743     // operator >=
744     template<class _CharT, class _Traits>
745     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
746     bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
747     {
748         return __lhs.compare(__rhs) >= 0;
749     }
750
751
752     template<class _CharT, class _Traits>
753     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
754     bool operator>=(basic_string_view<_CharT, _Traits> __lhs,
755                     typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
756     {
757         return __lhs.compare(__rhs) >= 0;
758     }
759
760     template<class _CharT, class _Traits>
761     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
762     bool operator>=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
763                     basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
764     {
765         return __lhs.compare(__rhs) >= 0;
766     }
767
768
769     // [string.view.io]
770     template<class _CharT, class _Traits>
771     basic_ostream<_CharT, _Traits>&
772     operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __sv)
773     {
774         return _VSTD::__put_character_sequence(__os, __sv.data(), __sv.size());
775     }
776
777   typedef basic_string_view<char>     string_view;
778   typedef basic_string_view<char16_t> u16string_view;
779   typedef basic_string_view<char32_t> u32string_view;
780   typedef basic_string_view<wchar_t>  wstring_view;
781
782 _LIBCPP_END_NAMESPACE_LFTS
783 _LIBCPP_BEGIN_NAMESPACE_STD
784
785 // [string.view.hash]
786 // Shamelessly stolen from <string>
787 template<class _CharT, class _Traits>
788 struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::basic_string_view<_CharT, _Traits> >
789     : public unary_function<std::experimental::basic_string_view<_CharT, _Traits>, size_t>
790 {
791     size_t operator()(const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT;
792 };
793
794 template<class _CharT, class _Traits>
795 size_t
796 hash<std::experimental::basic_string_view<_CharT, _Traits> >::operator()(
797         const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT
798 {
799     return __do_string_hash(__val.data(), __val.data() + __val.size());
800 }
801
802 #if _LIBCPP_STD_VER > 11
803 template <class _CharT, class _Traits>
804 __quoted_output_proxy<_CharT, const _CharT *, _Traits>
805 quoted ( std::experimental::basic_string_view <_CharT, _Traits> __sv,
806              _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
807 {
808     return __quoted_output_proxy<_CharT, const _CharT *, _Traits> 
809          ( __sv.data(), __sv.data() + __sv.size(), __delim, __escape );
810 }
811 #endif
812
813 _LIBCPP_END_NAMESPACE_STD
814
815 #endif // _LIBCPP_LFTS_STRING_VIEW