Home | History | Annotate | Download | only in experimental
      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 /*
     15 string_view synopsis
     16 
     17 namespace 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>
    785 template<class _CharT, class _Traits>
    786 struct _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 
    792 template<class _CharT, class _Traits>
    793 size_t
    794 hash<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
    801 template <class _CharT, class _Traits>
    802 __quoted_output_proxy<_CharT, const _CharT *, _Traits>
    803 quoted ( 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