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