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