Home | History | Annotate | Download | only in v1
      1 // -*- C++ -*-
      2 //===------------------------ string_view ---------------------------------===//
      3 //
      4 //                     The LLVM Compiler Infrastructure
      5 //
      6 // This file is distributed under the University of Illinois Open Source
      7 // License. See LICENSE.TXT for details.
      8 //
      9 //===----------------------------------------------------------------------===//
     10 
     11 #ifndef _LIBCPP_STRING_VIEW
     12 #define _LIBCPP_STRING_VIEW
     13 
     14 /*
     15 string_view synopsis
     16 
     17 namespace std {
     18 
     19     // 7.2, Class template basic_string_view
     20     template<class charT, class traits = char_traits<charT>>
     21         class basic_string_view;
     22 
     23     // 7.9, basic_string_view non-member comparison functions
     24     template<class charT, class traits>
     25     constexpr bool operator==(basic_string_view<charT, traits> x,
     26                               basic_string_view<charT, traits> y) noexcept;
     27     template<class charT, class traits>
     28     constexpr bool operator!=(basic_string_view<charT, traits> x,
     29                               basic_string_view<charT, traits> y) noexcept;
     30     template<class charT, class traits>
     31     constexpr bool operator< (basic_string_view<charT, traits> x,
     32                                  basic_string_view<charT, traits> y) noexcept;
     33     template<class charT, class traits>
     34     constexpr bool operator> (basic_string_view<charT, traits> x,
     35                               basic_string_view<charT, traits> y) noexcept;
     36     template<class charT, class traits>
     37     constexpr bool operator<=(basic_string_view<charT, traits> x,
     38                                  basic_string_view<charT, traits> y) noexcept;
     39     template<class charT, class traits>
     40     constexpr bool operator>=(basic_string_view<charT, traits> x,
     41                               basic_string_view<charT, traits> y) noexcept;
     42     // see below, sufficient additional overloads of comparison functions
     43 
     44     // 7.10, Inserters and extractors
     45     template<class charT, class traits>
     46       basic_ostream<charT, traits>&
     47         operator<<(basic_ostream<charT, traits>& os,
     48                    basic_string_view<charT, traits> str);
     49 
     50     // basic_string_view typedef names
     51     typedef basic_string_view<char> string_view;
     52     typedef basic_string_view<char16_t> u16string_view;
     53     typedef basic_string_view<char32_t> u32string_view;
     54     typedef basic_string_view<wchar_t> wstring_view;
     55 
     56     template<class charT, class traits = char_traits<charT>>
     57     class basic_string_view {
     58       public:
     59       // types
     60       typedef traits traits_type;
     61       typedef charT value_type;
     62       typedef charT* pointer;
     63       typedef const charT* const_pointer;
     64       typedef charT& reference;
     65       typedef const charT& const_reference;
     66       typedef implementation-defined const_iterator;
     67       typedef const_iterator iterator;
     68       typedef reverse_iterator<const_iterator> const_reverse_iterator;
     69       typedef const_reverse_iterator reverse_iterator;
     70       typedef size_t size_type;
     71       typedef ptrdiff_t difference_type;
     72       static constexpr size_type npos = size_type(-1);
     73 
     74       // 7.3, basic_string_view constructors and assignment operators
     75       constexpr basic_string_view() noexcept;
     76       constexpr basic_string_view(const basic_string_view&) noexcept = default;
     77       basic_string_view& operator=(const basic_string_view&) noexcept = default;
     78       template<class Allocator>
     79       constexpr basic_string_view(const charT* str);
     80       constexpr basic_string_view(const charT* str, size_type len);
     81 
     82       // 7.4, basic_string_view iterator support
     83       constexpr const_iterator begin() const noexcept;
     84       constexpr const_iterator end() const noexcept;
     85       constexpr const_iterator cbegin() const noexcept;
     86       constexpr const_iterator cend() const noexcept;
     87       const_reverse_iterator rbegin() const noexcept;
     88       const_reverse_iterator rend() const noexcept;
     89       const_reverse_iterator crbegin() const noexcept;
     90       const_reverse_iterator crend() const noexcept;
     91 
     92       // 7.5, basic_string_view capacity
     93       constexpr size_type size() const noexcept;
     94       constexpr size_type length() const noexcept;
     95       constexpr size_type max_size() const noexcept;
     96       constexpr bool empty() const noexcept;
     97 
     98       // 7.6, basic_string_view element access
     99       constexpr const_reference operator[](size_type pos) const;
    100       constexpr const_reference at(size_type pos) const;
    101       constexpr const_reference front() const;
    102       constexpr const_reference back() const;
    103       constexpr const_pointer data() const noexcept;
    104 
    105       // 7.7, basic_string_view modifiers
    106       constexpr void clear() noexcept;
    107       constexpr void remove_prefix(size_type n);
    108       constexpr void remove_suffix(size_type n);
    109       constexpr void swap(basic_string_view& s) noexcept;
    110 
    111       size_type copy(charT* s, size_type n, size_type pos = 0) const;
    112 
    113       constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
    114       constexpr int compare(basic_string_view s) const noexcept;
    115       constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;
    116       constexpr int compare(size_type pos1, size_type n1,
    117                             basic_string_view s, size_type pos2, size_type n2) const;
    118       constexpr int compare(const charT* s) const;
    119       constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
    120       constexpr int compare(size_type pos1, size_type n1,
    121                             const charT* s, size_type n2) const;
    122       constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;
    123       constexpr size_type find(charT c, size_type pos = 0) const noexcept;
    124       constexpr size_type find(const charT* s, size_type pos, size_type n) const;
    125       constexpr size_type find(const charT* s, size_type pos = 0) const;
    126       constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;
    127       constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;
    128       constexpr size_type rfind(const charT* s, size_type pos, size_type n) const;
    129       constexpr size_type rfind(const charT* s, size_type pos = npos) const;
    130       constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;
    131       constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;
    132       constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const;
    133       constexpr size_type find_first_of(const charT* s, size_type pos = 0) const;
    134       constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;
    135       constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;
    136       constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const;
    137       constexpr size_type find_last_of(const charT* s, size_type pos = npos) const;
    138       constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;
    139       constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;
    140       constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const;
    141       constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const;
    142       constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept;
    143       constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;
    144       constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const;
    145       constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const;
    146 
    147      private:
    148       const_pointer data_;  // exposition only
    149       size_type     size_;  // exposition only
    150     };
    151 
    152   // 7.11, Hash support
    153   template <class T> struct hash;
    154   template <> struct hash<string_view>;
    155   template <> struct hash<u16string_view>;
    156   template <> struct hash<u32string_view>;
    157   template <> struct hash<wstring_view>;
    158 
    159   constexpr basic_string<char>     operator "" s( const char *str,     size_t len ); // C++17
    160   constexpr basic_string<wchar_t>  operator "" s( const wchar_t *str,  size_t len ); // C++17
    161   constexpr basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++17
    162   constexpr basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++17
    163 
    164 }  // namespace std
    165 
    166 
    167 */
    168 
    169 #include <__config>
    170 
    171 #include <__string>
    172 #include <algorithm>
    173 #include <iterator>
    174 #include <limits>
    175 #include <stdexcept>
    176 #include <__debug>
    177 
    178 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
    179 #pragma GCC system_header
    180 #endif
    181 
    182 _LIBCPP_BEGIN_NAMESPACE_STD
    183 
    184 template<class _CharT, class _Traits = char_traits<_CharT> >
    185 class _LIBCPP_TEMPLATE_VIS basic_string_view {
    186 public:
    187 	// types
    188 	typedef _Traits                                    traits_type;
    189 	typedef _CharT                                     value_type;
    190 	typedef const _CharT*                              pointer;
    191 	typedef const _CharT*                              const_pointer;
    192 	typedef const _CharT&                              reference;
    193 	typedef const _CharT&                              const_reference;
    194 	typedef const_pointer                              const_iterator; // See [string.view.iterators]
    195 	typedef const_iterator                             iterator;
    196 	typedef _VSTD::reverse_iterator<const_iterator>    const_reverse_iterator;
    197 	typedef const_reverse_iterator                     reverse_iterator;
    198 	typedef size_t                                     size_type;
    199 	typedef ptrdiff_t                                  difference_type;
    200 	static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1);
    201 
    202 	// [string.view.cons], construct/copy
    203 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    204 	basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {}
    205 
    206 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    207 	basic_string_view(const basic_string_view&) _NOEXCEPT = default;
    208 
    209 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    210 	basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
    211 
    212 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    213 	basic_string_view(const _CharT* __s, size_type __len)
    214 		: __data(__s), __size(__len)
    215 	{
    216 // #if _LIBCPP_STD_VER > 11
    217 //         _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr");
    218 // #endif
    219 	}
    220 
    221 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    222 	basic_string_view(const _CharT* __s)
    223 		: __data(__s), __size(_Traits::length(__s)) {}
    224 
    225 	// [string.view.iterators], iterators
    226 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    227 	const_iterator begin()  const _NOEXCEPT { return cbegin(); }
    228 
    229 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    230 	const_iterator end()    const _NOEXCEPT { return cend(); }
    231 
    232 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    233 	const_iterator cbegin() const _NOEXCEPT { return __data; }
    234 
    235 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    236 	const_iterator cend()   const _NOEXCEPT { return __data + __size; }
    237 
    238 	_LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
    239 	const_reverse_iterator rbegin()   const _NOEXCEPT { return const_reverse_iterator(cend()); }
    240 
    241 	_LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
    242 	const_reverse_iterator rend()     const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
    243 
    244 	_LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
    245 	const_reverse_iterator crbegin()  const _NOEXCEPT { return const_reverse_iterator(cend()); }
    246 
    247 	_LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
    248 	const_reverse_iterator crend()    const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
    249 
    250 	// [string.view.capacity], capacity
    251 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    252 	size_type size()     const _NOEXCEPT { return __size; }
    253 
    254 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    255 	size_type length()   const _NOEXCEPT { return __size; }
    256 
    257 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    258 	size_type max_size() const _NOEXCEPT { return numeric_limits<size_type>::max(); }
    259 
    260 	_LIBCPP_CONSTEXPR bool _LIBCPP_INLINE_VISIBILITY
    261 	empty()         const _NOEXCEPT { return __size == 0; }
    262 
    263 	// [string.view.access], element access
    264 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    265 	const_reference operator[](size_type __pos) const _NOEXCEPT { return __data[__pos]; }
    266 
    267 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    268 	const_reference at(size_type __pos) const
    269 	{
    270 		return __pos >= size()
    271 			? (__throw_out_of_range("string_view::at"), __data[0])
    272 			: __data[__pos];
    273 	}
    274 
    275 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    276 	const_reference front() const
    277 	{
    278 		return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data[0];
    279 	}
    280 
    281 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    282 	const_reference back() const
    283 	{
    284 		return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data[__size-1];
    285 	}
    286 
    287 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    288 	const_pointer data() const _NOEXCEPT { return __data; }
    289 
    290 	// [string.view.modifiers], modifiers:
    291 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    292 	void clear() _NOEXCEPT
    293 	{
    294 		__data = nullptr;
    295 		__size = 0;
    296 	}
    297 
    298 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    299 	void remove_prefix(size_type __n) _NOEXCEPT
    300 	{
    301 		_LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()");
    302 		__data += __n;
    303 		__size -= __n;
    304 	}
    305 
    306 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    307 	void remove_suffix(size_type __n) _NOEXCEPT
    308 	{
    309 		_LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()");
    310 		__size -= __n;
    311 	}
    312 
    313 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    314 	void swap(basic_string_view& __other) _NOEXCEPT
    315 	{
    316 		const value_type *__p = __data;
    317 		__data = __other.__data;
    318 		__other.__data = __p;
    319 
    320 		size_type __sz = __size;
    321 		__size = __other.__size;
    322 		__other.__size = __sz;
    323 	}
    324 
    325 	_LIBCPP_INLINE_VISIBILITY
    326 	size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
    327 	{
    328 		if (__pos > size())
    329 			__throw_out_of_range("string_view::copy");
    330 		size_type __rlen = _VSTD::min(__n, size() - __pos);
    331 		_Traits::copy(__s, data() + __pos, __rlen);
    332 		return __rlen;
    333 	}
    334 
    335 	_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
    336 	basic_string_view substr(size_type __pos = 0, size_type __n = npos) const
    337 	{
    338 		return __pos > size()
    339 			? (__throw_out_of_range("string_view::substr"), basic_string_view())
    340 			: basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos));
    341 	}
    342 
    343 	_LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT
    344 	{
    345 		size_type __rlen = _VSTD::min( size(), __sv.size());
    346 		int __retval = _Traits::compare(data(), __sv.data(), __rlen);
    347 		if ( __retval == 0 ) // first __rlen chars matched
    348 			__retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 );
    349 		return __retval;
    350 	}
    351 
    352 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    353 	int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const
    354 	{
    355 		return substr(__pos1, __n1).compare(__sv);
    356 	}
    357 
    358 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    359 	int compare(                       size_type __pos1, size_type __n1, 
    360 				basic_string_view _sv, size_type __pos2, size_type __n2) const
    361 	{
    362 		return substr(__pos1, __n1).compare(_sv.substr(__pos2, __n2));
    363 	}
    364 
    365 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    366 	int compare(const _CharT* __s) const _NOEXCEPT
    367 	{
    368 		return compare(basic_string_view(__s));
    369 	}
    370 
    371 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    372 	int compare(size_type __pos1, size_type __n1, const _CharT* __s) const
    373 	{
    374 		return substr(__pos1, __n1).compare(basic_string_view(__s));
    375 	}
    376 
    377 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    378 	int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
    379 	{
    380 		return substr(__pos1, __n1).compare(basic_string_view(__s, __n2));
    381 	}
    382 
    383 	// find
    384 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    385 	size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
    386 	{
    387 		_LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
    388 		return __str_find<value_type, size_type, traits_type, npos>
    389 			(data(), size(), __s.data(), __pos, __s.size());
    390 	}
    391 
    392 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    393 	size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT
    394 	{
    395 		return __str_find<value_type, size_type, traits_type, npos>
    396 			(data(), size(), __c, __pos);
    397 	}
    398 
    399 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    400 	size_type find(const _CharT* __s, size_type __pos, size_type __n) const
    401 	{
    402 		_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
    403 		return __str_find<value_type, size_type, traits_type, npos>
    404 			(data(), size(), __s, __pos, __n);
    405 	}
    406 
    407 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    408 	size_type find(const _CharT* __s, size_type __pos = 0) const
    409 	{
    410 		_LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr");
    411 		return __str_find<value_type, size_type, traits_type, npos>
    412 			(data(), size(), __s, __pos, traits_type::length(__s));
    413 	}
    414 
    415 	// rfind
    416 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    417 	size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT
    418 	{
    419 		_LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
    420 		return __str_rfind<value_type, size_type, traits_type, npos>
    421 			(data(), size(), __s.data(), __pos, __s.size());
    422 	}
    423 
    424 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    425 	size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT
    426 	{
    427 		return __str_rfind<value_type, size_type, traits_type, npos>
    428 			(data(), size(), __c, __pos);
    429 	}
    430 
    431 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    432 	size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const
    433 	{
    434 		_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
    435 		return __str_rfind<value_type, size_type, traits_type, npos>
    436 			(data(), size(), __s, __pos, __n);
    437 	}
    438 
    439 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    440 	size_type rfind(const _CharT* __s, size_type __pos=npos) const
    441 	{
    442 		_LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr");
    443 		return __str_rfind<value_type, size_type, traits_type, npos>
    444 			(data(), size(), __s, __pos, traits_type::length(__s));
    445 	}
    446 
    447 	// find_first_of
    448 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    449 	size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
    450 	{
    451 		_LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
    452 		return __str_find_first_of<value_type, size_type, traits_type, npos>
    453 			(data(), size(), __s.data(), __pos, __s.size());
    454 	}
    455 
    456 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    457 	size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT
    458 	{ return find(__c, __pos); }
    459 
    460 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    461 	size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
    462 	{
    463 		_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
    464 		return __str_find_first_of<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 find_first_of(const _CharT* __s, size_type __pos=0) const
    470 	{
    471 		_LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr");
    472 		return __str_find_first_of<value_type, size_type, traits_type, npos>
    473 			(data(), size(), __s, __pos, traits_type::length(__s));
    474 	}
    475 
    476 	// find_last_of
    477 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    478 	size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
    479 	{
    480 		_LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
    481 		return __str_find_last_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_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT
    487 	{ return rfind(__c, __pos); }
    488 
    489 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    490 	size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
    491 	{
    492 		_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
    493 		return __str_find_last_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_last_of(const _CharT* __s, size_type __pos=npos) const
    499 	{
    500 		_LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr");
    501 		return __str_find_last_of<value_type, size_type, traits_type, npos>
    502 			(data(), size(), __s, __pos, traits_type::length(__s));
    503 	}
    504 
    505 	// find_first_not_of
    506 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    507 	size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT
    508 	{
    509 		_LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
    510 		return __str_find_first_not_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_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT
    516 	{
    517 		return __str_find_first_not_of<value_type, size_type, traits_type, npos>
    518 			(data(), size(), __c, __pos);
    519 	}
    520 
    521 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    522 	size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
    523 	{
    524 		_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
    525 		return __str_find_first_not_of<value_type, size_type, traits_type, npos>
    526 			(data(), size(), __s, __pos, __n);
    527 	}
    528 
    529 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    530 	size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const
    531 	{
    532 		_LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
    533 		return __str_find_first_not_of<value_type, size_type, traits_type, npos>
    534 			(data(), size(), __s, __pos, traits_type::length(__s));
    535 	}
    536 
    537 	// find_last_not_of
    538 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    539 	size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
    540 	{
    541 		_LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
    542 		return __str_find_last_not_of<value_type, size_type, traits_type, npos>
    543 			(data(), size(), __s.data(), __pos, __s.size());
    544 	}
    545 
    546 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    547 	size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT
    548 	{
    549 		return __str_find_last_not_of<value_type, size_type, traits_type, npos>
    550 			(data(), size(), __c, __pos);
    551 	}
    552 
    553 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    554 	size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
    555 	{
    556 		_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
    557 		return __str_find_last_not_of<value_type, size_type, traits_type, npos>
    558 			(data(), size(), __s, __pos, __n);
    559 	}
    560 
    561 	_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    562 	size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const
    563 	{
    564 		_LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
    565 		return __str_find_last_not_of<value_type, size_type, traits_type, npos>
    566 			(data(), size(), __s, __pos, traits_type::length(__s));
    567 	}
    568 
    569 private:
    570 	const   value_type* __data;
    571 	size_type           __size;
    572 };
    573 
    574 
    575 // [string.view.comparison]
    576 // operator ==
    577 template<class _CharT, class _Traits>
    578 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    579 bool operator==(basic_string_view<_CharT, _Traits> __lhs,
    580 				basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    581 {
    582 	if ( __lhs.size() != __rhs.size()) return false;
    583 	return __lhs.compare(__rhs) == 0;
    584 }
    585 
    586 template<class _CharT, class _Traits>
    587 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    588 bool operator==(basic_string_view<_CharT, _Traits> __lhs,
    589 				typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
    590 {
    591 	if ( __lhs.size() != __rhs.size()) return false;
    592 	return __lhs.compare(__rhs) == 0;
    593 }
    594 
    595 template<class _CharT, class _Traits>
    596 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    597 bool operator==(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
    598 				basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    599 {
    600 	if ( __lhs.size() != __rhs.size()) return false;
    601 	return __lhs.compare(__rhs) == 0;
    602 }
    603 
    604 
    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, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    609 {
    610 	if ( __lhs.size() != __rhs.size())
    611 		return true;
    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 common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
    619 {
    620 	if ( __lhs.size() != __rhs.size())
    621 		return true;
    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 common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
    628 				basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    629 {
    630 	if ( __lhs.size() != __rhs.size())
    631 		return true;
    632 	return __lhs.compare(__rhs) != 0;
    633 }
    634 
    635 
    636 // operator <
    637 template<class _CharT, class _Traits>
    638 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    639 bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    640 {
    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 common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
    648 {
    649 	return __lhs.compare(__rhs) < 0;
    650 }
    651 
    652 template<class _CharT, class _Traits>
    653 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    654 bool operator<(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
    655 				basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    656 {
    657 	return __lhs.compare(__rhs) < 0;
    658 }
    659 
    660 
    661 // operator >
    662 template<class _CharT, class _Traits>
    663 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    664 bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    665 {
    666 	return __lhs.compare(__rhs) > 0;
    667 }
    668 
    669 template<class _CharT, class _Traits>
    670 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    671 bool operator>(basic_string_view<_CharT, _Traits> __lhs,
    672 				typename common_type<basic_string_view<_CharT, _Traits> >::type __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>(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
    680 				basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    681 {
    682 	return __lhs.compare(__rhs) > 0;
    683 }
    684 
    685 
    686 // operator <=
    687 template<class _CharT, class _Traits>
    688 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    689 bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    690 {
    691 	return __lhs.compare(__rhs) <= 0;
    692 }
    693 
    694 template<class _CharT, class _Traits>
    695 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    696 bool operator<=(basic_string_view<_CharT, _Traits> __lhs,
    697 				typename common_type<basic_string_view<_CharT, _Traits> >::type __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<=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
    705 				basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    706 {
    707 	return __lhs.compare(__rhs) <= 0;
    708 }
    709 
    710 
    711 // operator >=
    712 template<class _CharT, class _Traits>
    713 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    714 bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    715 {
    716 	return __lhs.compare(__rhs) >= 0;
    717 }
    718 
    719 
    720 template<class _CharT, class _Traits>
    721 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    722 bool operator>=(basic_string_view<_CharT, _Traits> __lhs,
    723 				typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
    724 {
    725 	return __lhs.compare(__rhs) >= 0;
    726 }
    727 
    728 template<class _CharT, class _Traits>
    729 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
    730 bool operator>=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, 
    731 				basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
    732 {
    733 	return __lhs.compare(__rhs) >= 0;
    734 }
    735 
    736 typedef basic_string_view<char>     string_view;
    737 typedef basic_string_view<char16_t> u16string_view;
    738 typedef basic_string_view<char32_t> u32string_view;
    739 typedef basic_string_view<wchar_t>  wstring_view;
    740 
    741 // [string.view.hash]
    742 template<class _CharT, class _Traits>
    743 struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, _Traits> >
    744     : public unary_function<basic_string_view<_CharT, _Traits>, size_t>
    745 {
    746     size_t operator()(const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT;
    747 };
    748 
    749 template<class _CharT, class _Traits>
    750 size_t
    751 hash<basic_string_view<_CharT, _Traits> >::operator()(
    752         const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT
    753 {
    754     return __do_string_hash(__val.data(), __val.data() + __val.size());
    755 }
    756 
    757 
    758 #if _LIBCPP_STD_VER > 11 
    759 inline namespace literals
    760 {
    761   inline namespace string_view_literals
    762   {
    763     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
    764     basic_string_view<char> operator "" sv(const char *__str, size_t __len)
    765     {
    766         return basic_string_view<char> (__str, __len);
    767     }
    768 
    769     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
    770     basic_string_view<wchar_t> operator "" sv(const wchar_t *__str, size_t __len)
    771     {
    772         return basic_string_view<wchar_t> (__str, __len);
    773     }
    774 
    775     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
    776     basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len)
    777     {
    778         return basic_string_view<char16_t> (__str, __len);
    779     }
    780 
    781     inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
    782     basic_string_view<char32_t> operator "" sv(const char32_t *__str, size_t __len)
    783     {
    784         return basic_string_view<char32_t> (__str, __len);
    785     }
    786   }
    787 }
    788 #endif
    789 _LIBCPP_END_NAMESPACE_STD
    790 
    791 #endif // _LIBCPP_STRING_VIEW
    792