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