Home | History | Annotate | Download | only in include
      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 /*
     15 string_view synopsis
     16 
     17 namespace 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 <version>
    182 #include <__debug>
    183 
    184 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
    185 #pragma GCC system_header
    186 #endif
    187 
    188 _LIBCPP_PUSH_MACROS
    189 #include <__undef_macros>
    190 
    191 
    192 _LIBCPP_BEGIN_NAMESPACE_STD
    193 
    194 template<class _CharT, class _Traits = 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 _CharT*                                    pointer;
    201     typedef const _CharT*                              const_pointer;
    202     typedef _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     static_assert((!is_array<value_type>::value), "Character type of basic_string_view must not be an array");
    213     static_assert(( is_standard_layout<value_type>::value), "Character type of basic_string_view must be standard-layout");
    214     static_assert(( is_trivial<value_type>::value), "Character type of basic_string_view must be trivial");
    215     static_assert((is_same<_CharT, typename traits_type::char_type>::value),
    216                   "traits_type::char_type must be the same type as CharT");
    217 
    218     // [string.view.cons], construct/copy
    219     _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    220     basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {}
    221 
    222     _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    223     basic_string_view(const basic_string_view&) _NOEXCEPT = default;
    224 
    225     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    226     basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
    227 
    228     _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    229     basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT
    230         : __data(__s), __size(__len)
    231     {
    232 // #if _LIBCPP_STD_VER > 11
    233 //         _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr");
    234 // #endif
    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_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
    255     const_reverse_iterator rbegin()   const _NOEXCEPT { return const_reverse_iterator(cend()); }
    256 
    257     _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
    258     const_reverse_iterator rend()     const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
    259 
    260     _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
    261     const_reverse_iterator crbegin()  const _NOEXCEPT { return const_reverse_iterator(cend()); }
    262 
    263     _LIBCPP_CONSTEXPR_AFTER_CXX14 _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 numeric_limits<size_type>::max(); }
    275 
    276     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
    277     bool 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 _NOEXCEPT { 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 remove_prefix(size_type __n) _NOEXCEPT
    309     {
    310         _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()");
    311         __data += __n;
    312         __size -= __n;
    313     }
    314 
    315     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    316     void remove_suffix(size_type __n) _NOEXCEPT
    317     {
    318         _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()");
    319         __size -= __n;
    320     }
    321 
    322     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    323     void swap(basic_string_view& __other) _NOEXCEPT
    324     {
    325         const value_type *__p = __data;
    326         __data = __other.__data;
    327         __other.__data = __p;
    328 
    329         size_type __sz = __size;
    330         __size = __other.__size;
    331         __other.__size = __sz;
    332     }
    333 
    334     _LIBCPP_INLINE_VISIBILITY
    335     size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
    336     {
    337         if (__pos > size())
    338             __throw_out_of_range("string_view::copy");
    339         size_type __rlen = _VSTD::min(__n, size() - __pos);
    340         _Traits::copy(__s, data() + __pos, __rlen);
    341         return __rlen;
    342     }
    343 
    344     _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    345     basic_string_view substr(size_type __pos = 0, size_type __n = npos) const
    346     {
    347         return __pos > size()
    348             ? (__throw_out_of_range("string_view::substr"), basic_string_view())
    349             : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos));
    350     }
    351 
    352     _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT
    353     {
    354         size_type __rlen = _VSTD::min( size(), __sv.size());
    355         int __retval = _Traits::compare(data(), __sv.data(), __rlen);
    356         if ( __retval == 0 ) // first __rlen chars matched
    357             __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 );
    358         return __retval;
    359     }
    360 
    361     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    362     int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const
    363     {
    364         return substr(__pos1, __n1).compare(__sv);
    365     }
    366 
    367     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    368     int compare(                       size_type __pos1, size_type __n1, 
    369                 basic_string_view __sv, size_type __pos2, size_type __n2) const
    370     {
    371         return substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2));
    372     }
    373 
    374     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    375     int compare(const _CharT* __s) const _NOEXCEPT
    376     {
    377         return compare(basic_string_view(__s));
    378     }
    379 
    380     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    381     int compare(size_type __pos1, size_type __n1, const _CharT* __s) const
    382     {
    383         return substr(__pos1, __n1).compare(basic_string_view(__s));
    384     }
    385 
    386     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    387     int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
    388     {
    389         return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
    390     }
    391 
    392     // find
    393     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    394     size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
    395     {
    396         _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
    397         return __str_find<value_type, size_type, traits_type, npos>
    398             (data(), size(), __s.data(), __pos, __s.size());
    399     }
    400 
    401     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    402     size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT
    403     {
    404         return __str_find<value_type, size_type, traits_type, npos>
    405             (data(), size(), __c, __pos);
    406     }
    407 
    408     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    409     size_type find(const _CharT* __s, size_type __pos, size_type __n) const
    410     {
    411         _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
    412         return __str_find<value_type, size_type, traits_type, npos>
    413             (data(), size(), __s, __pos, __n);
    414     }
    415 
    416     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    417     size_type find(const _CharT* __s, size_type __pos = 0) const
    418     {
    419         _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr");
    420         return __str_find<value_type, size_type, traits_type, npos>
    421             (data(), size(), __s, __pos, traits_type::length(__s));
    422     }
    423 
    424     // rfind
    425     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    426     size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT
    427     {
    428         _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
    429         return __str_rfind<value_type, size_type, traits_type, npos>
    430             (data(), size(), __s.data(), __pos, __s.size());
    431     }
    432 
    433     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    434     size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT
    435     {
    436         return __str_rfind<value_type, size_type, traits_type, npos>
    437             (data(), size(), __c, __pos);
    438     }
    439 
    440     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    441     size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const
    442     {
    443         _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
    444         return __str_rfind<value_type, size_type, traits_type, npos>
    445             (data(), size(), __s, __pos, __n);
    446     }
    447 
    448     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    449     size_type rfind(const _CharT* __s, size_type __pos=npos) const
    450     {
    451         _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr");
    452         return __str_rfind<value_type, size_type, traits_type, npos>
    453             (data(), size(), __s, __pos, traits_type::length(__s));
    454     }
    455 
    456     // find_first_of
    457     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    458     size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
    459     {
    460         _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
    461         return __str_find_first_of<value_type, size_type, traits_type, npos>
    462             (data(), size(), __s.data(), __pos, __s.size());
    463     }
    464 
    465     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    466     size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT
    467     { return find(__c, __pos); }
    468 
    469     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    470     size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
    471     {
    472         _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
    473         return __str_find_first_of<value_type, size_type, traits_type, npos>
    474             (data(), size(), __s, __pos, __n);
    475     }
    476 
    477     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    478     size_type find_first_of(const _CharT* __s, size_type __pos=0) const
    479     {
    480         _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr");
    481         return __str_find_first_of<value_type, size_type, traits_type, npos>
    482             (data(), size(), __s, __pos, traits_type::length(__s));
    483     }
    484 
    485     // find_last_of
    486     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    487     size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
    488     {
    489         _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
    490         return __str_find_last_of<value_type, size_type, traits_type, npos>
    491             (data(), size(), __s.data(), __pos, __s.size());
    492     }
    493 
    494     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    495     size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT
    496     { return rfind(__c, __pos); }
    497 
    498     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    499     size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
    500     {
    501         _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
    502         return __str_find_last_of<value_type, size_type, traits_type, npos>
    503             (data(), size(), __s, __pos, __n);
    504     }
    505 
    506     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    507     size_type find_last_of(const _CharT* __s, size_type __pos=npos) const
    508     {
    509         _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr");
    510         return __str_find_last_of<value_type, size_type, traits_type, npos>
    511             (data(), size(), __s, __pos, traits_type::length(__s));
    512     }
    513 
    514     // find_first_not_of
    515     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    516     size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT
    517     {
    518         _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
    519         return __str_find_first_not_of<value_type, size_type, traits_type, npos>
    520             (data(), size(), __s.data(), __pos, __s.size());
    521     }
    522 
    523     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    524     size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT
    525     {
    526         return __str_find_first_not_of<value_type, size_type, traits_type, npos>
    527             (data(), size(), __c, __pos);
    528     }
    529 
    530     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    531     size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
    532     {
    533         _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
    534         return __str_find_first_not_of<value_type, size_type, traits_type, npos>
    535             (data(), size(), __s, __pos, __n);
    536     }
    537 
    538     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    539     size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const
    540     {
    541         _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
    542         return __str_find_first_not_of<value_type, size_type, traits_type, npos>
    543             (data(), size(), __s, __pos, traits_type::length(__s));
    544     }
    545 
    546     // find_last_not_of
    547     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    548     size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
    549     {
    550         _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
    551         return __str_find_last_not_of<value_type, size_type, traits_type, npos>
    552             (data(), size(), __s.data(), __pos, __s.size());
    553     }
    554 
    555     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    556     size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT
    557     {
    558         return __str_find_last_not_of<value_type, size_type, traits_type, npos>
    559             (data(), size(), __c, __pos);
    560     }
    561 
    562     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    563     size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
    564     {
    565         _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
    566         return __str_find_last_not_of<value_type, size_type, traits_type, npos>
    567             (data(), size(), __s, __pos, __n);
    568     }
    569 
    570     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    571     size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const
    572     {
    573         _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
    574         return __str_find_last_not_of<value_type, size_type, traits_type, npos>
    575             (data(), size(), __s, __pos, traits_type::length(__s));
    576     }
    577 
    578 #if _LIBCPP_STD_VER > 17
    579     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    580     bool starts_with(basic_string_view __s) const _NOEXCEPT
    581     { return size() >= __s.size() && compare(0, __s.size(), __s) == 0; }
    582 
    583     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    584     bool starts_with(value_type __c) const _NOEXCEPT
    585     { return !empty() && _Traits::eq(front(), __c); }
    586 
    587     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    588     bool starts_with(const value_type* __s) const _NOEXCEPT
    589     { return starts_with(basic_string_view(__s)); }
    590 
    591     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    592     bool ends_with(basic_string_view __s) const _NOEXCEPT
    593     { return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0; }
    594 
    595     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    596     bool ends_with(value_type __c) const _NOEXCEPT
    597     { return !empty() && _Traits::eq(back(), __c); }
    598 
    599     _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    600     bool ends_with(const value_type* __s) const _NOEXCEPT
    601     { return ends_with(basic_string_view(__s)); }
    602 #endif
    603 
    604 private:
    605     const   value_type* __data;
    606     size_type           __size;
    607 };
    608 
    609 
    610 // [string.view.comparison]
    611 // operator ==
    612 template<class _CharT, class _Traits>
    613 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    614 bool operator==(basic_string_view<_CharT, _Traits> __lhs,
    615                 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    616 {
    617     if ( __lhs.size() != __rhs.size()) return false;
    618     return __lhs.compare(__rhs) == 0;
    619 }
    620 
    621 template<class _CharT, class _Traits>
    622 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    623 bool operator==(basic_string_view<_CharT, _Traits> __lhs,
    624                 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
    625 {
    626     if ( __lhs.size() != __rhs.size()) return false;
    627     return __lhs.compare(__rhs) == 0;
    628 }
    629 
    630 template<class _CharT, class _Traits>
    631 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    632 bool operator==(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
    633                 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    634 {
    635     if ( __lhs.size() != __rhs.size()) return false;
    636     return __lhs.compare(__rhs) == 0;
    637 }
    638 
    639 
    640 // operator !=
    641 template<class _CharT, class _Traits>
    642 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    643 bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    644 {
    645     if ( __lhs.size() != __rhs.size())
    646         return true;
    647     return __lhs.compare(__rhs) != 0;
    648 }
    649 
    650 template<class _CharT, class _Traits>
    651 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    652 bool operator!=(basic_string_view<_CharT, _Traits> __lhs,
    653                 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
    654 {
    655     if ( __lhs.size() != __rhs.size())
    656         return true;
    657     return __lhs.compare(__rhs) != 0;
    658 }
    659 
    660 template<class _CharT, class _Traits>
    661 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    662 bool operator!=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
    663                 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    664 {
    665     if ( __lhs.size() != __rhs.size())
    666         return true;
    667     return __lhs.compare(__rhs) != 0;
    668 }
    669 
    670 
    671 // operator <
    672 template<class _CharT, class _Traits>
    673 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    674 bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    675 {
    676     return __lhs.compare(__rhs) < 0;
    677 }
    678 
    679 template<class _CharT, class _Traits>
    680 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    681 bool operator<(basic_string_view<_CharT, _Traits> __lhs,
    682                 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
    683 {
    684     return __lhs.compare(__rhs) < 0;
    685 }
    686 
    687 template<class _CharT, class _Traits>
    688 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    689 bool operator<(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
    690                 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    691 {
    692     return __lhs.compare(__rhs) < 0;
    693 }
    694 
    695 
    696 // operator >
    697 template<class _CharT, class _Traits>
    698 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    699 bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    700 {
    701     return __lhs.compare(__rhs) > 0;
    702 }
    703 
    704 template<class _CharT, class _Traits>
    705 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    706 bool operator>(basic_string_view<_CharT, _Traits> __lhs,
    707                 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
    708 {
    709     return __lhs.compare(__rhs) > 0;
    710 }
    711 
    712 template<class _CharT, class _Traits>
    713 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    714 bool operator>(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
    715                 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    716 {
    717     return __lhs.compare(__rhs) > 0;
    718 }
    719 
    720 
    721 // operator <=
    722 template<class _CharT, class _Traits>
    723 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    724 bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    725 {
    726     return __lhs.compare(__rhs) <= 0;
    727 }
    728 
    729 template<class _CharT, class _Traits>
    730 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    731 bool operator<=(basic_string_view<_CharT, _Traits> __lhs,
    732                 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
    733 {
    734     return __lhs.compare(__rhs) <= 0;
    735 }
    736 
    737 template<class _CharT, class _Traits>
    738 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    739 bool operator<=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
    740                 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    741 {
    742     return __lhs.compare(__rhs) <= 0;
    743 }
    744 
    745 
    746 // operator >=
    747 template<class _CharT, class _Traits>
    748 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    749 bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    750 {
    751     return __lhs.compare(__rhs) >= 0;
    752 }
    753 
    754 
    755 template<class _CharT, class _Traits>
    756 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    757 bool operator>=(basic_string_view<_CharT, _Traits> __lhs,
    758                 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
    759 {
    760     return __lhs.compare(__rhs) >= 0;
    761 }
    762 
    763 template<class _CharT, class _Traits>
    764 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    765 bool operator>=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
    766                 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    767 {
    768     return __lhs.compare(__rhs) >= 0;
    769 }
    770 
    771 typedef basic_string_view<char>     string_view;
    772 #ifndef _LIBCPP_NO_HAS_CHAR8_T
    773 typedef basic_string_view<char8_t>  u8string_view;
    774 #endif
    775 typedef basic_string_view<char16_t> u16string_view;
    776 typedef basic_string_view<char32_t> u32string_view;
    777 typedef basic_string_view<wchar_t>  wstring_view;
    778 
    779 // [string.view.hash]
    780 template<class _CharT, class _Traits>
    781 struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, _Traits> >
    782     : public unary_function<basic_string_view<_CharT, _Traits>, size_t>
    783 {
    784     _LIBCPP_INLINE_VISIBILITY
    785     size_t operator()(const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT {
    786         return __do_string_hash(__val.data(), __val.data() + __val.size());
    787     }
    788 };
    789 
    790 
    791 #if _LIBCPP_STD_VER > 11 
    792 inline namespace literals
    793 {
    794   inline namespace string_view_literals
    795   {
    796     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
    797     basic_string_view<char> operator "" sv(const char *__str, size_t __len) _NOEXCEPT
    798     {
    799         return basic_string_view<char> (__str, __len);
    800     }
    801 
    802     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
    803     basic_string_view<wchar_t> operator "" sv(const wchar_t *__str, size_t __len) _NOEXCEPT
    804     {
    805         return basic_string_view<wchar_t> (__str, __len);
    806     }
    807 
    808 #ifndef _LIBCPP_NO_HAS_CHAR8_T
    809     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
    810     basic_string_view<char8_t> operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT
    811     {
    812         return basic_string_view<char8_t> (__str, __len);
    813     }
    814 #endif
    815 
    816     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
    817     basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT
    818     {
    819         return basic_string_view<char16_t> (__str, __len);
    820     }
    821 
    822     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
    823     basic_string_view<char32_t> operator "" sv(const char32_t *__str, size_t __len) _NOEXCEPT
    824     {
    825         return basic_string_view<char32_t> (__str, __len);
    826     }
    827   }
    828 }
    829 #endif
    830 _LIBCPP_END_NAMESPACE_STD
    831 
    832 _LIBCPP_POP_MACROS
    833 
    834 #endif // _LIBCPP_STRING_VIEW
    835