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