string_view revision 278724
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/*
15string_view synopsis
16
17namespace 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>
787template<class _CharT, class _Traits>
788struct _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
794template<class _CharT, class _Traits>
795size_t
796hash<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
803template <class _CharT, class _Traits>
804__quoted_output_proxy<_CharT, const _CharT *, _Traits>
805quoted ( 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
816