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