• 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_STRING_VIEW
12#define _LIBCPP_STRING_VIEW
13
14/*
15string_view synopsis
16
17namespace std {
18
19    // 7.2, Class template basic_string_view
20    template<class charT, class traits = char_traits<charT>>
21        class basic_string_view;
22
23    // 7.9, basic_string_view non-member comparison functions
24    template<class charT, class traits>
25    constexpr bool operator==(basic_string_view<charT, traits> x,
26                              basic_string_view<charT, traits> y) noexcept;
27    template<class charT, class traits>
28    constexpr bool operator!=(basic_string_view<charT, traits> x,
29                              basic_string_view<charT, traits> y) noexcept;
30    template<class charT, class traits>
31    constexpr bool operator< (basic_string_view<charT, traits> x,
32                                 basic_string_view<charT, traits> y) noexcept;
33    template<class charT, class traits>
34    constexpr bool operator> (basic_string_view<charT, traits> x,
35                              basic_string_view<charT, traits> y) noexcept;
36    template<class charT, class traits>
37    constexpr bool operator<=(basic_string_view<charT, traits> x,
38                                 basic_string_view<charT, traits> y) noexcept;
39    template<class charT, class traits>
40    constexpr bool operator>=(basic_string_view<charT, traits> x,
41                              basic_string_view<charT, traits> y) noexcept;
42    // see below, sufficient additional overloads of comparison functions
43
44    // 7.10, Inserters and extractors
45    template<class charT, class traits>
46      basic_ostream<charT, traits>&
47        operator<<(basic_ostream<charT, traits>& os,
48                   basic_string_view<charT, traits> str);
49
50    // basic_string_view typedef names
51    typedef basic_string_view<char> string_view;
52    typedef basic_string_view<char16_t> u16string_view;
53    typedef basic_string_view<char32_t> u32string_view;
54    typedef basic_string_view<wchar_t> wstring_view;
55
56    template<class charT, class traits = char_traits<charT>>
57    class basic_string_view {
58      public:
59      // types
60      typedef traits traits_type;
61      typedef charT value_type;
62      typedef charT* pointer;
63      typedef const charT* const_pointer;
64      typedef charT& reference;
65      typedef const charT& const_reference;
66      typedef implementation-defined const_iterator;
67      typedef const_iterator iterator;
68      typedef reverse_iterator<const_iterator> const_reverse_iterator;
69      typedef const_reverse_iterator reverse_iterator;
70      typedef size_t size_type;
71      typedef ptrdiff_t difference_type;
72      static constexpr size_type npos = size_type(-1);
73
74      // 7.3, basic_string_view constructors and assignment operators
75      constexpr basic_string_view() noexcept;
76      constexpr basic_string_view(const basic_string_view&) noexcept = default;
77      basic_string_view& operator=(const basic_string_view&) noexcept = default;
78      template<class Allocator>
79      constexpr basic_string_view(const charT* str);
80      constexpr basic_string_view(const charT* str, size_type len);
81
82      // 7.4, basic_string_view iterator support
83      constexpr const_iterator begin() const noexcept;
84      constexpr const_iterator end() const noexcept;
85      constexpr const_iterator cbegin() const noexcept;
86      constexpr const_iterator cend() const noexcept;
87      const_reverse_iterator rbegin() const noexcept;
88      const_reverse_iterator rend() const noexcept;
89      const_reverse_iterator crbegin() const noexcept;
90      const_reverse_iterator crend() const noexcept;
91
92      // 7.5, basic_string_view capacity
93      constexpr size_type size() const noexcept;
94      constexpr size_type length() const noexcept;
95      constexpr size_type max_size() const noexcept;
96      constexpr bool empty() const noexcept;
97
98      // 7.6, basic_string_view element access
99      constexpr const_reference operator[](size_type pos) const;
100      constexpr const_reference at(size_type pos) const;
101      constexpr const_reference front() const;
102      constexpr const_reference back() const;
103      constexpr const_pointer data() const noexcept;
104
105      // 7.7, basic_string_view modifiers
106      constexpr void remove_prefix(size_type n);
107      constexpr void remove_suffix(size_type n);
108      constexpr void swap(basic_string_view& s) noexcept;
109
110      size_type copy(charT* s, size_type n, size_type pos = 0) const;
111
112      constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
113      constexpr int compare(basic_string_view s) const noexcept;
114      constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;
115      constexpr int compare(size_type pos1, size_type n1,
116                            basic_string_view s, size_type pos2, size_type n2) const;
117      constexpr int compare(const charT* s) const;
118      constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
119      constexpr int compare(size_type pos1, size_type n1,
120                            const charT* s, size_type n2) const;
121      constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;
122      constexpr size_type find(charT c, size_type pos = 0) const noexcept;
123      constexpr size_type find(const charT* s, size_type pos, size_type n) const;
124      constexpr size_type find(const charT* s, size_type pos = 0) const;
125      constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;
126      constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;
127      constexpr size_type rfind(const charT* s, size_type pos, size_type n) const;
128      constexpr size_type rfind(const charT* s, size_type pos = npos) const;
129      constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;
130      constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;
131      constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const;
132      constexpr size_type find_first_of(const charT* s, size_type pos = 0) const;
133      constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;
134      constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;
135      constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const;
136      constexpr size_type find_last_of(const charT* s, size_type pos = npos) const;
137      constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;
138      constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;
139      constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const;
140      constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const;
141      constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept;
142      constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;
143      constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const;
144      constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const;
145
146      constexpr bool starts_with(basic_string_view s) const noexcept; // C++2a
147      constexpr bool starts_with(charT c) const noexcept;             // C++2a
148      constexpr bool starts_with(const charT* s) const;               // C++2a
149      constexpr bool ends_with(basic_string_view s) const noexcept;   // C++2a
150      constexpr bool ends_with(charT c) const noexcept;               // C++2a
151      constexpr bool ends_with(const charT* s) const;                 // C++2a
152
153     private:
154      const_pointer data_;  // exposition only
155      size_type     size_;  // exposition only
156    };
157
158  // 7.11, Hash support
159  template <class T> struct hash;
160  template <> struct hash<string_view>;
161  template <> struct hash<u16string_view>;
162  template <> struct hash<u32string_view>;
163  template <> struct hash<wstring_view>;
164
165  constexpr basic_string_view<char>     operator "" sv( const char *str,     size_t len ) noexcept;
166  constexpr basic_string_view<wchar_t>  operator "" sv( const wchar_t *str,  size_t len ) noexcept;
167  constexpr basic_string_view<char16_t> operator "" sv( const char16_t *str, size_t len ) noexcept;
168  constexpr basic_string_view<char32_t> operator "" sv( const char32_t *str, size_t len ) noexcept;
169
170}  // namespace std
171
172
173*/
174
175#include <__config>
176#include <__string>
177#include <algorithm>
178#include <iterator>
179#include <limits>
180#include <stdexcept>
181#include <__debug>
182
183#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
184#pragma GCC system_header
185#endif
186
187_LIBCPP_PUSH_MACROS
188#include <__undef_macros>
189
190
191_LIBCPP_BEGIN_NAMESPACE_STD
192
193template<class _CharT, class _Traits = char_traits<_CharT> >
194class _LIBCPP_TEMPLATE_VIS basic_string_view {
195public:
196    // types
197    typedef _Traits                                    traits_type;
198    typedef _CharT                                     value_type;
199    typedef _CharT*                                    pointer;
200    typedef const _CharT*                              const_pointer;
201    typedef _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    static_assert(is_trivial<value_type>::value, "Character type of basic_string_view must be trivial");
212    static_assert((is_same<_CharT, typename traits_type::char_type>::value),
213                  "traits_type::char_type must be the same type as CharT");
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_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
223    basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
224
225    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
226    basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT
227        : __data(__s), __size(__len)
228    {
229// #if _LIBCPP_STD_VER > 11
230//         _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr");
231// #endif
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_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
252    const_reverse_iterator rbegin()   const _NOEXCEPT { return const_reverse_iterator(cend()); }
253
254    _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
255    const_reverse_iterator rend()     const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
256
257    _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
258    const_reverse_iterator crbegin()  const _NOEXCEPT { return const_reverse_iterator(cend()); }
259
260    _LIBCPP_CONSTEXPR_AFTER_CXX14 _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 numeric_limits<size_type>::max(); }
272
273    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
274    bool 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 _NOEXCEPT { 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 remove_prefix(size_type __n) _NOEXCEPT
306    {
307        _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()");
308        __data += __n;
309        __size -= __n;
310    }
311
312    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
313    void remove_suffix(size_type __n) _NOEXCEPT
314    {
315        _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()");
316        __size -= __n;
317    }
318
319    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
320    void swap(basic_string_view& __other) _NOEXCEPT
321    {
322        const value_type *__p = __data;
323        __data = __other.__data;
324        __other.__data = __p;
325
326        size_type __sz = __size;
327        __size = __other.__size;
328        __other.__size = __sz;
329    }
330
331    _LIBCPP_INLINE_VISIBILITY
332    size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
333    {
334        if (__pos > size())
335            __throw_out_of_range("string_view::copy");
336        size_type __rlen = _VSTD::min(__n, size() - __pos);
337        _Traits::copy(__s, data() + __pos, __rlen);
338        return __rlen;
339    }
340
341    _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
342    basic_string_view substr(size_type __pos = 0, size_type __n = npos) const
343    {
344        return __pos > size()
345            ? (__throw_out_of_range("string_view::substr"), basic_string_view())
346            : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos));
347    }
348
349    _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT
350    {
351        size_type __rlen = _VSTD::min( size(), __sv.size());
352        int __retval = _Traits::compare(data(), __sv.data(), __rlen);
353        if ( __retval == 0 ) // first __rlen chars matched
354            __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 );
355        return __retval;
356    }
357
358    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
359    int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const
360    {
361        return substr(__pos1, __n1).compare(__sv);
362    }
363
364    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
365    int compare(                       size_type __pos1, size_type __n1,
366                basic_string_view __sv, size_type __pos2, size_type __n2) const
367    {
368        return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
369    }
370
371    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
372    int compare(const _CharT* __s) const _NOEXCEPT
373    {
374        return compare(basic_string_view(__s));
375    }
376
377    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
378    int compare(size_type __pos1, size_type __n1, const _CharT* __s) const
379    {
380        return substr(__pos1, __n1).compare(basic_string_view(__s));
381    }
382
383    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
384    int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
385    {
386        return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
387    }
388
389    // find
390    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
391    size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
392    {
393        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
394        return __str_find<value_type, size_type, traits_type, npos>
395            (data(), size(), __s.data(), __pos, __s.size());
396    }
397
398    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
399    size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT
400    {
401        return __str_find<value_type, size_type, traits_type, npos>
402            (data(), size(), __c, __pos);
403    }
404
405    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
406    size_type find(const _CharT* __s, size_type __pos, size_type __n) const
407    {
408        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
409        return __str_find<value_type, size_type, traits_type, npos>
410            (data(), size(), __s, __pos, __n);
411    }
412
413    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
414    size_type find(const _CharT* __s, size_type __pos = 0) const
415    {
416        _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr");
417        return __str_find<value_type, size_type, traits_type, npos>
418            (data(), size(), __s, __pos, traits_type::length(__s));
419    }
420
421    // rfind
422    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
423    size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT
424    {
425        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
426        return __str_rfind<value_type, size_type, traits_type, npos>
427            (data(), size(), __s.data(), __pos, __s.size());
428    }
429
430    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
431    size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT
432    {
433        return __str_rfind<value_type, size_type, traits_type, npos>
434            (data(), size(), __c, __pos);
435    }
436
437    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
438    size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const
439    {
440        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
441        return __str_rfind<value_type, size_type, traits_type, npos>
442            (data(), size(), __s, __pos, __n);
443    }
444
445    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
446    size_type rfind(const _CharT* __s, size_type __pos=npos) const
447    {
448        _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr");
449        return __str_rfind<value_type, size_type, traits_type, npos>
450            (data(), size(), __s, __pos, traits_type::length(__s));
451    }
452
453    // find_first_of
454    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
455    size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
456    {
457        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
458        return __str_find_first_of<value_type, size_type, traits_type, npos>
459            (data(), size(), __s.data(), __pos, __s.size());
460    }
461
462    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
463    size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT
464    { return find(__c, __pos); }
465
466    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
467    size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
468    {
469        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
470        return __str_find_first_of<value_type, size_type, traits_type, npos>
471            (data(), size(), __s, __pos, __n);
472    }
473
474    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
475    size_type find_first_of(const _CharT* __s, size_type __pos=0) const
476    {
477        _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr");
478        return __str_find_first_of<value_type, size_type, traits_type, npos>
479            (data(), size(), __s, __pos, traits_type::length(__s));
480    }
481
482    // find_last_of
483    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
484    size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
485    {
486        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
487        return __str_find_last_of<value_type, size_type, traits_type, npos>
488            (data(), size(), __s.data(), __pos, __s.size());
489    }
490
491    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
492    size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT
493    { return rfind(__c, __pos); }
494
495    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
496    size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
497    {
498        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
499        return __str_find_last_of<value_type, size_type, traits_type, npos>
500            (data(), size(), __s, __pos, __n);
501    }
502
503    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
504    size_type find_last_of(const _CharT* __s, size_type __pos=npos) const
505    {
506        _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr");
507        return __str_find_last_of<value_type, size_type, traits_type, npos>
508            (data(), size(), __s, __pos, traits_type::length(__s));
509    }
510
511    // find_first_not_of
512    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
513    size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT
514    {
515        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
516        return __str_find_first_not_of<value_type, size_type, traits_type, npos>
517            (data(), size(), __s.data(), __pos, __s.size());
518    }
519
520    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
521    size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT
522    {
523        return __str_find_first_not_of<value_type, size_type, traits_type, npos>
524            (data(), size(), __c, __pos);
525    }
526
527    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
528    size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
529    {
530        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
531        return __str_find_first_not_of<value_type, size_type, traits_type, npos>
532            (data(), size(), __s, __pos, __n);
533    }
534
535    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
536    size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const
537    {
538        _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
539        return __str_find_first_not_of<value_type, size_type, traits_type, npos>
540            (data(), size(), __s, __pos, traits_type::length(__s));
541    }
542
543    // find_last_not_of
544    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
545    size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
546    {
547        _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
548        return __str_find_last_not_of<value_type, size_type, traits_type, npos>
549            (data(), size(), __s.data(), __pos, __s.size());
550    }
551
552    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
553    size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT
554    {
555        return __str_find_last_not_of<value_type, size_type, traits_type, npos>
556            (data(), size(), __c, __pos);
557    }
558
559    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
560    size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
561    {
562        _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
563        return __str_find_last_not_of<value_type, size_type, traits_type, npos>
564            (data(), size(), __s, __pos, __n);
565    }
566
567    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
568    size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const
569    {
570        _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
571        return __str_find_last_not_of<value_type, size_type, traits_type, npos>
572            (data(), size(), __s, __pos, traits_type::length(__s));
573    }
574
575#if _LIBCPP_STD_VER > 17
576    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
577    bool starts_with(basic_string_view __s) const _NOEXCEPT
578    { return size() >= __s.size() && compare(0, __s.size(), __s) == 0; }
579
580    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
581    bool starts_with(value_type __c) const _NOEXCEPT
582    { return !empty() && _Traits::eq(front(), __c); }
583
584    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
585    bool starts_with(const value_type* __s) const _NOEXCEPT
586    { return starts_with(basic_string_view(__s)); }
587
588    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
589    bool ends_with(basic_string_view __s) const _NOEXCEPT
590    { return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0; }
591
592    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
593    bool ends_with(value_type __c) const _NOEXCEPT
594    { return !empty() && _Traits::eq(back(), __c); }
595
596    _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
597    bool ends_with(const value_type* __s) const _NOEXCEPT
598    { return ends_with(basic_string_view(__s)); }
599#endif
600
601private:
602    const   value_type* __data;
603    size_type           __size;
604};
605
606
607// [string.view.comparison]
608// operator ==
609template<class _CharT, class _Traits>
610_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
611bool 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
618template<class _CharT, class _Traits>
619_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
620bool operator==(basic_string_view<_CharT, _Traits> __lhs,
621                typename 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
627template<class _CharT, class _Traits>
628_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
629bool operator==(typename 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 !=
638template<class _CharT, class _Traits>
639_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
640bool 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
647template<class _CharT, class _Traits>
648_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
649bool operator!=(basic_string_view<_CharT, _Traits> __lhs,
650                typename 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
657template<class _CharT, class _Traits>
658_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
659bool operator!=(typename 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 <
669template<class _CharT, class _Traits>
670_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
671bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
672{
673    return __lhs.compare(__rhs) < 0;
674}
675
676template<class _CharT, class _Traits>
677_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
678bool operator<(basic_string_view<_CharT, _Traits> __lhs,
679                typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
680{
681    return __lhs.compare(__rhs) < 0;
682}
683
684template<class _CharT, class _Traits>
685_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
686bool operator<(typename 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 >
694template<class _CharT, class _Traits>
695_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
696bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
697{
698    return __lhs.compare(__rhs) > 0;
699}
700
701template<class _CharT, class _Traits>
702_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
703bool operator>(basic_string_view<_CharT, _Traits> __lhs,
704                typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
705{
706    return __lhs.compare(__rhs) > 0;
707}
708
709template<class _CharT, class _Traits>
710_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
711bool operator>(typename 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 <=
719template<class _CharT, class _Traits>
720_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
721bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
722{
723    return __lhs.compare(__rhs) <= 0;
724}
725
726template<class _CharT, class _Traits>
727_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
728bool operator<=(basic_string_view<_CharT, _Traits> __lhs,
729                typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
730{
731    return __lhs.compare(__rhs) <= 0;
732}
733
734template<class _CharT, class _Traits>
735_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
736bool operator<=(typename 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 >=
744template<class _CharT, class _Traits>
745_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
746bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
747{
748    return __lhs.compare(__rhs) >= 0;
749}
750
751
752template<class _CharT, class _Traits>
753_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
754bool operator>=(basic_string_view<_CharT, _Traits> __lhs,
755                typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
756{
757    return __lhs.compare(__rhs) >= 0;
758}
759
760template<class _CharT, class _Traits>
761_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
762bool operator>=(typename 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
768typedef basic_string_view<char>     string_view;
769typedef basic_string_view<char16_t> u16string_view;
770typedef basic_string_view<char32_t> u32string_view;
771typedef basic_string_view<wchar_t>  wstring_view;
772
773// [string.view.hash]
774template<class _CharT, class _Traits>
775struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, _Traits> >
776    : public unary_function<basic_string_view<_CharT, _Traits>, size_t>
777{
778    size_t operator()(const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT;
779};
780
781template<class _CharT, class _Traits>
782size_t
783hash<basic_string_view<_CharT, _Traits> >::operator()(
784        const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT
785{
786    return __do_string_hash(__val.data(), __val.data() + __val.size());
787}
788
789
790#if _LIBCPP_STD_VER > 11
791inline namespace literals
792{
793  inline namespace string_view_literals
794  {
795    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
796    basic_string_view<char> operator "" sv(const char *__str, size_t __len) _NOEXCEPT
797    {
798        return basic_string_view<char> (__str, __len);
799    }
800
801    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
802    basic_string_view<wchar_t> operator "" sv(const wchar_t *__str, size_t __len) _NOEXCEPT
803    {
804        return basic_string_view<wchar_t> (__str, __len);
805    }
806
807    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
808    basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT
809    {
810        return basic_string_view<char16_t> (__str, __len);
811    }
812
813    inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
814    basic_string_view<char32_t> operator "" sv(const char32_t *__str, size_t __len) _NOEXCEPT
815    {
816        return basic_string_view<char32_t> (__str, __len);
817    }
818  }
819}
820#endif
821_LIBCPP_END_NAMESPACE_STD
822
823_LIBCPP_POP_MACROS
824
825#endif // _LIBCPP_STRING_VIEW
826