• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_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        _LIBCPP_EXPLICIT operator basic_string<_CharT, _Traits, _Allocator>() const
344        { return basic_string<_CharT, _Traits, _Allocator>( begin(), end()); }
345
346        template<class _Allocator = allocator<_CharT> >
347        _LIBCPP_INLINE_VISIBILITY
348        basic_string<_CharT, _Traits, _Allocator>
349        to_string( const _Allocator& __a = _Allocator()) const
350        { return basic_string<_CharT, _Traits, _Allocator> ( begin(), end(), __a ); }
351
352        size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
353        {
354            if ( __pos > size())
355                __throw_out_of_range("string_view::copy");
356            size_type __rlen = _VSTD::min( __n, size() - __pos );
357            _VSTD::copy_n(begin() + __pos, __rlen, __s );
358            return __rlen;
359        }
360
361        _LIBCPP_CONSTEXPR
362        basic_string_view substr(size_type __pos = 0, size_type __n = npos) const
363        {
364//             if (__pos > size())
365//                 __throw_out_of_range("string_view::substr");
366//             size_type __rlen = _VSTD::min( __n, size() - __pos );
367//             return basic_string_view(data() + __pos, __rlen);
368            return __pos > size()
369                ? (__throw_out_of_range("string_view::substr"), basic_string_view())
370                : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos));
371        }
372
373        _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT
374        {
375            size_type __rlen = _VSTD::min( size(), __sv.size());
376            int __retval = _Traits::compare(data(), __sv.data(), __rlen);
377            if ( __retval == 0 ) // first __rlen chars matched
378                __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 );
379            return __retval;
380        }
381
382        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
383        int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const
384        {
385            return substr(__pos1, __n1).compare(__sv);
386        }
387
388        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
389        int compare(                       size_type __pos1, size_type __n1,
390                    basic_string_view _sv, size_type __pos2, size_type __n2) const
391        {
392            return substr(__pos1, __n1).compare(_sv.substr(__pos2, __n2));
393        }
394
395        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
396        int compare(const _CharT* __s) const
397        {
398            return compare(basic_string_view(__s));
399        }
400
401        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
402        int compare(size_type __pos1, size_type __n1, const _CharT* __s) const
403        {
404            return substr(__pos1, __n1).compare(basic_string_view(__s));
405        }
406
407        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
408        int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
409        {
410            return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
411        }
412
413        // find
414        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
415        size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
416        {
417            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
418            return _VSTD::__str_find<value_type, size_type, traits_type, npos>
419                (data(), size(), __s.data(), __pos, __s.size());
420        }
421
422        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
423        size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT
424        {
425            return _VSTD::__str_find<value_type, size_type, traits_type, npos>
426                (data(), size(), __c, __pos);
427        }
428
429        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
430        size_type find(const _CharT* __s, size_type __pos, size_type __n) const
431        {
432            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
433            return _VSTD::__str_find<value_type, size_type, traits_type, npos>
434                (data(), size(), __s, __pos, __n);
435        }
436
437        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
438        size_type find(const _CharT* __s, size_type __pos = 0) const
439        {
440            _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr");
441            return _VSTD::__str_find<value_type, size_type, traits_type, npos>
442                (data(), size(), __s, __pos, traits_type::length(__s));
443        }
444
445        // rfind
446        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
447        size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT
448        {
449            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
450            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
451                (data(), size(), __s.data(), __pos, __s.size());
452        }
453
454        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
455        size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT
456        {
457            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
458                (data(), size(), __c, __pos);
459        }
460
461        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
462        size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const
463        {
464            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
465            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
466                (data(), size(), __s, __pos, __n);
467        }
468
469        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
470        size_type rfind(const _CharT* __s, size_type __pos=npos) const
471        {
472            _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr");
473            return _VSTD::__str_rfind<value_type, size_type, traits_type, npos>
474                (data(), size(), __s, __pos, traits_type::length(__s));
475        }
476
477        // find_first_of
478        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
479        size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
480        {
481            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
482            return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
483                (data(), size(), __s.data(), __pos, __s.size());
484        }
485
486        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
487        size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT
488        { return find(__c, __pos); }
489
490        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
491        size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
492        {
493            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
494            return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
495                (data(), size(), __s, __pos, __n);
496        }
497
498        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
499        size_type find_first_of(const _CharT* __s, size_type __pos=0) const
500        {
501            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr");
502            return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos>
503                (data(), size(), __s, __pos, traits_type::length(__s));
504        }
505
506        // find_last_of
507        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
508        size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
509        {
510            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
511            return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
512                (data(), size(), __s.data(), __pos, __s.size());
513        }
514
515        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
516        size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT
517        { return rfind(__c, __pos); }
518
519        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
520        size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
521        {
522            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
523            return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
524                (data(), size(), __s, __pos, __n);
525        }
526
527        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
528        size_type find_last_of(const _CharT* __s, size_type __pos=npos) const
529        {
530            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr");
531            return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos>
532                (data(), size(), __s, __pos, traits_type::length(__s));
533        }
534
535        // find_first_not_of
536        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
537        size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT
538        {
539            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
540            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
541                (data(), size(), __s.data(), __pos, __s.size());
542        }
543
544        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
545        size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT
546        {
547            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
548                (data(), size(), __c, __pos);
549        }
550
551        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
552        size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
553        {
554            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
555            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
556                (data(), size(), __s, __pos, __n);
557        }
558
559        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
560        size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const
561        {
562            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
563            return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos>
564                (data(), size(), __s, __pos, traits_type::length(__s));
565        }
566
567        // find_last_not_of
568        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
569        size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
570        {
571            _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
572            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
573                (data(), size(), __s.data(), __pos, __s.size());
574        }
575
576        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
577        size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT
578        {
579            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
580                (data(), size(), __c, __pos);
581        }
582
583        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
584        size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
585        {
586            _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
587            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
588                (data(), size(), __s, __pos, __n);
589        }
590
591        _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
592        size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const
593        {
594            _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
595            return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos>
596                (data(), size(), __s, __pos, traits_type::length(__s));
597        }
598
599    private:
600        const   value_type* __data;
601        size_type           __size;
602    };
603
604
605    // [string.view.comparison]
606    // operator ==
607    template<class _CharT, class _Traits>
608    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
609    bool operator==(basic_string_view<_CharT, _Traits> __lhs,
610                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
611    {
612        if ( __lhs.size() != __rhs.size()) return false;
613        return __lhs.compare(__rhs) == 0;
614    }
615
616    template<class _CharT, class _Traits>
617    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
618    bool operator==(basic_string_view<_CharT, _Traits> __lhs,
619                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
620    {
621        if ( __lhs.size() != __rhs.size()) return false;
622        return __lhs.compare(__rhs) == 0;
623    }
624
625    template<class _CharT, class _Traits>
626    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
627    bool operator==(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
628                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
629    {
630        if ( __lhs.size() != __rhs.size()) return false;
631        return __lhs.compare(__rhs) == 0;
632    }
633
634
635    // operator !=
636    template<class _CharT, class _Traits>
637    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
638    bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
639    {
640        if ( __lhs.size() != __rhs.size())
641            return true;
642        return __lhs.compare(__rhs) != 0;
643    }
644
645    template<class _CharT, class _Traits>
646    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
647    bool operator!=(basic_string_view<_CharT, _Traits> __lhs,
648                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
649    {
650        if ( __lhs.size() != __rhs.size())
651            return true;
652        return __lhs.compare(__rhs) != 0;
653    }
654
655    template<class _CharT, class _Traits>
656    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
657    bool operator!=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
658                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
659    {
660        if ( __lhs.size() != __rhs.size())
661            return true;
662        return __lhs.compare(__rhs) != 0;
663    }
664
665
666    // operator <
667    template<class _CharT, class _Traits>
668    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
669    bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
670    {
671        return __lhs.compare(__rhs) < 0;
672    }
673
674    template<class _CharT, class _Traits>
675    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
676    bool operator<(basic_string_view<_CharT, _Traits> __lhs,
677                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
678    {
679        return __lhs.compare(__rhs) < 0;
680    }
681
682    template<class _CharT, class _Traits>
683    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
684    bool operator<(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
685                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
686    {
687        return __lhs.compare(__rhs) < 0;
688    }
689
690
691    // operator >
692    template<class _CharT, class _Traits>
693    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
694    bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
695    {
696        return __lhs.compare(__rhs) > 0;
697    }
698
699    template<class _CharT, class _Traits>
700    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
701    bool operator>(basic_string_view<_CharT, _Traits> __lhs,
702                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
703    {
704        return __lhs.compare(__rhs) > 0;
705    }
706
707    template<class _CharT, class _Traits>
708    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
709    bool operator>(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
710                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
711    {
712        return __lhs.compare(__rhs) > 0;
713    }
714
715
716    // operator <=
717    template<class _CharT, class _Traits>
718    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
719    bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
720    {
721        return __lhs.compare(__rhs) <= 0;
722    }
723
724    template<class _CharT, class _Traits>
725    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
726    bool operator<=(basic_string_view<_CharT, _Traits> __lhs,
727                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
728    {
729        return __lhs.compare(__rhs) <= 0;
730    }
731
732    template<class _CharT, class _Traits>
733    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
734    bool operator<=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
735                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
736    {
737        return __lhs.compare(__rhs) <= 0;
738    }
739
740
741    // operator >=
742    template<class _CharT, class _Traits>
743    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
744    bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
745    {
746        return __lhs.compare(__rhs) >= 0;
747    }
748
749
750    template<class _CharT, class _Traits>
751    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
752    bool operator>=(basic_string_view<_CharT, _Traits> __lhs,
753                    typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
754    {
755        return __lhs.compare(__rhs) >= 0;
756    }
757
758    template<class _CharT, class _Traits>
759    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
760    bool operator>=(typename _VSTD::common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
761                    basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
762    {
763        return __lhs.compare(__rhs) >= 0;
764    }
765
766
767    // [string.view.io]
768    template<class _CharT, class _Traits>
769    basic_ostream<_CharT, _Traits>&
770    operator<<(basic_ostream<_CharT, _Traits>& __os, basic_string_view<_CharT, _Traits> __sv)
771    {
772        return _VSTD::__put_character_sequence(__os, __sv.data(), __sv.size());
773    }
774
775  typedef basic_string_view<char>     string_view;
776  typedef basic_string_view<char16_t> u16string_view;
777  typedef basic_string_view<char32_t> u32string_view;
778  typedef basic_string_view<wchar_t>  wstring_view;
779
780_LIBCPP_END_NAMESPACE_LFTS
781_LIBCPP_BEGIN_NAMESPACE_STD
782
783// [string.view.hash]
784// Shamelessly stolen from <string>
785template<class _CharT, class _Traits>
786struct _LIBCPP_TEMPLATE_VIS hash<std::experimental::basic_string_view<_CharT, _Traits> >
787    : public unary_function<std::experimental::basic_string_view<_CharT, _Traits>, size_t>
788{
789    size_t operator()(const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT;
790};
791
792template<class _CharT, class _Traits>
793size_t
794hash<std::experimental::basic_string_view<_CharT, _Traits> >::operator()(
795        const std::experimental::basic_string_view<_CharT, _Traits>& __val) const _NOEXCEPT
796{
797    return __do_string_hash(__val.data(), __val.data() + __val.size());
798}
799
800#if _LIBCPP_STD_VER > 11
801template <class _CharT, class _Traits>
802__quoted_output_proxy<_CharT, const _CharT *, _Traits>
803quoted ( std::experimental::basic_string_view <_CharT, _Traits> __sv,
804             _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\'))
805{
806    return __quoted_output_proxy<_CharT, const _CharT *, _Traits>
807         ( __sv.data(), __sv.data() + __sv.size(), __delim, __escape );
808}
809#endif
810
811_LIBCPP_END_NAMESPACE_STD
812
813#endif // _LIBCPP_LFTS_STRING_VIEW
814