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