1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_STRING_VIEW
11#define _LIBCPP_STRING_VIEW
12
13/*
14
15 string_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 template<class charT, class traits>
24 inline constexpr bool ranges::enable_view<basic_string_view<charT, traits>> = true;
25
26 template<class charT, class traits>
27 inline constexpr bool ranges::enable_borrowed_range<basic_string_view<charT, traits>> = true; // C++20
28
29 // 7.9, basic_string_view non-member comparison functions
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 template<class charT, class traits>
43 constexpr bool operator<=(basic_string_view<charT, traits> x,
44 basic_string_view<charT, traits> y) noexcept;
45 template<class charT, class traits>
46 constexpr bool operator>=(basic_string_view<charT, traits> x,
47 basic_string_view<charT, traits> y) noexcept;
48 // see below, sufficient additional overloads of comparison functions
49
50 // 7.10, Inserters and extractors
51 template<class charT, class traits>
52 basic_ostream<charT, traits>&
53 operator<<(basic_ostream<charT, traits>& os,
54 basic_string_view<charT, traits> str);
55
56 // basic_string_view typedef names
57 typedef basic_string_view<char> string_view;
58 typedef basic_string_view<char8_t> u8string_view; // C++20
59 typedef basic_string_view<char16_t> u16string_view;
60 typedef basic_string_view<char32_t> u32string_view;
61 typedef basic_string_view<wchar_t> wstring_view;
62
63 template<class charT, class traits = char_traits<charT>>
64 class basic_string_view {
65 public:
66 // types
67 typedef traits traits_type;
68 typedef charT value_type;
69 typedef charT* pointer;
70 typedef const charT* const_pointer;
71 typedef charT& reference;
72 typedef const charT& const_reference;
73 typedef implementation-defined const_iterator;
74 typedef const_iterator iterator;
75 typedef reverse_iterator<const_iterator> const_reverse_iterator;
76 typedef const_reverse_iterator reverse_iterator;
77 typedef size_t size_type;
78 typedef ptrdiff_t difference_type;
79 static constexpr size_type npos = size_type(-1);
80
81 // 7.3, basic_string_view constructors and assignment operators
82 constexpr basic_string_view() noexcept;
83 constexpr basic_string_view(const basic_string_view&) noexcept = default;
84 basic_string_view& operator=(const basic_string_view&) noexcept = default;
85 template<class Allocator>
86 constexpr basic_string_view(const charT* str);
87 basic_string_view(nullptr_t) = delete; // C++2b
88 constexpr basic_string_view(const charT* str, size_type len);
89 template <class It, class End>
90 constexpr basic_string_view(It begin, End end); // C++20
91 template <class Range>
92 constexpr basic_string_view(Range&& r); // C++23
93
94 // 7.4, basic_string_view iterator support
95 constexpr const_iterator begin() const noexcept;
96 constexpr const_iterator end() const noexcept;
97 constexpr const_iterator cbegin() const noexcept;
98 constexpr const_iterator cend() const noexcept;
99 const_reverse_iterator rbegin() const noexcept;
100 const_reverse_iterator rend() const noexcept;
101 const_reverse_iterator crbegin() const noexcept;
102 const_reverse_iterator crend() const noexcept;
103
104 // 7.5, basic_string_view capacity
105 constexpr size_type size() const noexcept;
106 constexpr size_type length() const noexcept;
107 constexpr size_type max_size() const noexcept;
108 constexpr bool empty() const noexcept;
109
110 // 7.6, basic_string_view element access
111 constexpr const_reference operator[](size_type pos) const;
112 constexpr const_reference at(size_type pos) const;
113 constexpr const_reference front() const;
114 constexpr const_reference back() const;
115 constexpr const_pointer data() const noexcept;
116
117 // 7.7, basic_string_view modifiers
118 constexpr void remove_prefix(size_type n);
119 constexpr void remove_suffix(size_type n);
120 constexpr void swap(basic_string_view& s) noexcept;
121
122 size_type copy(charT* s, size_type n, size_type pos = 0) const; // constexpr in C++20
123
124 constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
125 constexpr int compare(basic_string_view s) const noexcept;
126 constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const;
127 constexpr int compare(size_type pos1, size_type n1,
128 basic_string_view s, size_type pos2, size_type n2) const;
129 constexpr int compare(const charT* s) const;
130 constexpr int compare(size_type pos1, size_type n1, const charT* s) const;
131 constexpr int compare(size_type pos1, size_type n1,
132 const charT* s, size_type n2) const;
133 constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept;
134 constexpr size_type find(charT c, size_type pos = 0) const noexcept;
135 constexpr size_type find(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
136 constexpr size_type find(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension
137 constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept;
138 constexpr size_type rfind(charT c, size_type pos = npos) const noexcept;
139 constexpr size_type rfind(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
140 constexpr size_type rfind(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension
141 constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept;
142 constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept;
143 constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
144 constexpr size_type find_first_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension
145 constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept;
146 constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept;
147 constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
148 constexpr size_type find_last_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension
149 constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept;
150 constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept;
151 constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
152 constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const noexcept; // noexcept as an extension
153 constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept;
154 constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept;
155 constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const noexcept; // noexcept as an extension
156 constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const noexcept; // noexcept as an extension
157
158 constexpr bool starts_with(basic_string_view s) const noexcept; // C++20
159 constexpr bool starts_with(charT c) const noexcept; // C++20
160 constexpr bool starts_with(const charT* s) const; // C++20
161 constexpr bool ends_with(basic_string_view s) const noexcept; // C++20
162 constexpr bool ends_with(charT c) const noexcept; // C++20
163 constexpr bool ends_with(const charT* s) const; // C++20
164
165 constexpr bool contains(basic_string_view s) const noexcept; // C++2b
166 constexpr bool contains(charT c) const noexcept; // C++2b
167 constexpr bool contains(const charT* s) const; // C++2b
168
169 private:
170 const_pointer data_; // exposition only
171 size_type size_; // exposition only
172 };
173
174 // basic_string_view deduction guides
175 template<class It, class End>
176 basic_string_view(It, End) -> basic_string_view<iter_value_t<It>>; // C++20
177 template<class Range>
178 basic_string_view(Range&&) -> basic_string_view<ranges::range_value_t<Range>>; // C++23
179
180 // 7.11, Hash support
181 template <class T> struct hash;
182 template <> struct hash<string_view>;
183 template <> struct hash<u8string_view>; // C++20
184 template <> struct hash<u16string_view>;
185 template <> struct hash<u32string_view>;
186 template <> struct hash<wstring_view>;
187
188 constexpr basic_string_view<char> operator "" sv( const char *str, size_t len ) noexcept;
189 constexpr basic_string_view<wchar_t> operator "" sv( const wchar_t *str, size_t len ) noexcept;
190 constexpr basic_string_view<char8_t> operator "" sv( const char8_t *str, size_t len ) noexcept; // C++20
191 constexpr basic_string_view<char16_t> operator "" sv( const char16_t *str, size_t len ) noexcept;
192 constexpr basic_string_view<char32_t> operator "" sv( const char32_t *str, size_t len ) noexcept;
193
194} // namespace std
195
196
197*/
198
199#include <__algorithm/min.h>
200#include <__assert> // all public C++ headers provide the assertion handler
201#include <__config>
202#include <__functional/hash.h>
203#include <__functional/unary_function.h>
204#include <__fwd/string_view.h>
205#include <__iterator/concepts.h>
206#include <__iterator/readable_traits.h>
207#include <__iterator/reverse_iterator.h>
208#include <__memory/pointer_traits.h>
209#include <__ranges/concepts.h>
210#include <__ranges/data.h>
211#include <__ranges/enable_borrowed_range.h>
212#include <__ranges/enable_view.h>
213#include <__ranges/size.h>
214#include <__string/char_traits.h>
215#include <iosfwd>
216#include <limits>
217#include <stdexcept>
218#include <type_traits>
219#include <version>
220
221#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
222# include <algorithm>
223# include <functional>
224# include <iterator>
225#endif
226
227// standard-mandated includes
228
229// [iterator.range]
230#include <__iterator/access.h>
231#include <__iterator/data.h>
232#include <__iterator/empty.h>
233#include <__iterator/reverse_access.h>
234#include <__iterator/size.h>
235
236// [string.view.synop]
237#include <compare>
238
239#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
240# pragma GCC system_header
241#endif
242
243_LIBCPP_PUSH_MACROS
244#include <__undef_macros>
245
246
247_LIBCPP_BEGIN_NAMESPACE_STD
248
249// TODO: This is a workaround for some vendors to carry a downstream diff to accept `nullptr` in
250// string_view constructors. This can be refactored when this exact form isn't needed anymore.
251template <class _Traits>
252_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
253inline size_t __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT {
254 // This needs to be a single statement for C++11 constexpr
255 return _LIBCPP_ASSERT(__s != nullptr, "null pointer passed to non-null argument of char_traits<...>::length"), _Traits::length(__s);
256}
257
258template<class _CharT, class _Traits>
259class
260 _LIBCPP_PREFERRED_NAME(string_view)
261#ifndef _LIBCPP_HAS_NO_CHAR8_T
262 _LIBCPP_PREFERRED_NAME(u8string_view)
263#endif
264 _LIBCPP_PREFERRED_NAME(u16string_view)
265 _LIBCPP_PREFERRED_NAME(u32string_view)
266 _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstring_view))
267 basic_string_view {
268public:
269 // types
270 typedef _Traits traits_type;
271 typedef _CharT value_type;
272 typedef _CharT* pointer;
273 typedef const _CharT* const_pointer;
274 typedef _CharT& reference;
275 typedef const _CharT& const_reference;
276 typedef const_pointer const_iterator; // See [string.view.iterators]
277 typedef const_iterator iterator;
278 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
279 typedef const_reverse_iterator reverse_iterator;
280 typedef size_t size_type;
281 typedef ptrdiff_t difference_type;
282 static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1);
283
284 static_assert((!is_array<value_type>::value), "Character type of basic_string_view must not be an array");
285 static_assert(( is_standard_layout<value_type>::value), "Character type of basic_string_view must be standard-layout");
286 static_assert(( is_trivial<value_type>::value), "Character type of basic_string_view must be trivial");
287 static_assert((is_same<_CharT, typename traits_type::char_type>::value),
288 "traits_type::char_type must be the same type as CharT");
289
290 // [string.view.cons], construct/copy
291 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
292 basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {}
293
294 _LIBCPP_INLINE_VISIBILITY
295 basic_string_view(const basic_string_view&) _NOEXCEPT = default;
296
297 _LIBCPP_INLINE_VISIBILITY
298 basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default;
299
300 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
301 basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT
302 : __data(__s), __size(__len)
303 {
304#if _LIBCPP_STD_VER > 11
305 _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr");
306#endif
307 }
308
309#if _LIBCPP_STD_VER > 17
310 template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
311 requires (is_same_v<iter_value_t<_It>, _CharT> && !is_convertible_v<_End, size_type>)
312 constexpr _LIBCPP_HIDE_FROM_ABI basic_string_view(_It __begin, _End __end)
313 : __data(_VSTD::to_address(__begin)), __size(__end - __begin)
314 {
315 _LIBCPP_ASSERT((__end - __begin) >= 0, "std::string_view::string_view(iterator, sentinel) received invalid range");
316 }
317#endif // _LIBCPP_STD_VER > 17
318
319#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
320 template <class _Range>
321 requires (
322 !is_same_v<remove_cvref_t<_Range>, basic_string_view> &&
323 ranges::contiguous_range<_Range> &&
324 ranges::sized_range<_Range> &&
325 is_same_v<ranges::range_value_t<_Range>, _CharT> &&
326 !is_convertible_v<_Range, const _CharT*> &&
327 (!requires(remove_cvref_t<_Range>& __d) {
328 __d.operator _VSTD::basic_string_view<_CharT, _Traits>();
329 }) &&
330 (!requires {
331 typename remove_reference_t<_Range>::traits_type;
332 } || is_same_v<typename remove_reference_t<_Range>::traits_type, _Traits>)
333 )
334 constexpr _LIBCPP_HIDE_FROM_ABI
335 basic_string_view(_Range&& __r) : __data(ranges::data(__r)), __size(ranges::size(__r)) {}
336#endif // _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
337
338 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
339 basic_string_view(const _CharT* __s)
340 : __data(__s), __size(_VSTD::__char_traits_length_checked<_Traits>(__s)) {}
341
342#if _LIBCPP_STD_VER > 20
343 basic_string_view(nullptr_t) = delete;
344#endif
345
346 // [string.view.iterators], iterators
347 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
348 const_iterator begin() const _NOEXCEPT { return cbegin(); }
349
350 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
351 const_iterator end() const _NOEXCEPT { return cend(); }
352
353 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
354 const_iterator cbegin() const _NOEXCEPT { return __data; }
355
356 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
357 const_iterator cend() const _NOEXCEPT { return __data + __size; }
358
359 _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
360 const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); }
361
362 _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
363 const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
364
365 _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
366 const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); }
367
368 _LIBCPP_CONSTEXPR_AFTER_CXX14 _LIBCPP_INLINE_VISIBILITY
369 const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); }
370
371 // [string.view.capacity], capacity
372 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
373 size_type size() const _NOEXCEPT { return __size; }
374
375 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
376 size_type length() const _NOEXCEPT { return __size; }
377
378 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
379 size_type max_size() const _NOEXCEPT { return numeric_limits<size_type>::max() / sizeof(value_type); }
380
381 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
382 bool empty() const _NOEXCEPT { return __size == 0; }
383
384 // [string.view.access], element access
385 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
386 const_reference operator[](size_type __pos) const _NOEXCEPT {
387 return _LIBCPP_ASSERT(__pos < size(), "string_view[] index out of bounds"), __data[__pos];
388 }
389
390 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
391 const_reference at(size_type __pos) const
392 {
393 return __pos >= size()
394 ? (__throw_out_of_range(msg: "string_view::at"), __data[0])
395 : __data[__pos];
396 }
397
398 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
399 const_reference front() const _NOEXCEPT
400 {
401 return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data[0];
402 }
403
404 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
405 const_reference back() const _NOEXCEPT
406 {
407 return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data[__size-1];
408 }
409
410 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
411 const_pointer data() const _NOEXCEPT { return __data; }
412
413 // [string.view.modifiers], modifiers:
414 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
415 void remove_prefix(size_type __n) _NOEXCEPT
416 {
417 _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()");
418 __data += __n;
419 __size -= __n;
420 }
421
422 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
423 void remove_suffix(size_type __n) _NOEXCEPT
424 {
425 _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()");
426 __size -= __n;
427 }
428
429 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
430 void swap(basic_string_view& __other) _NOEXCEPT
431 {
432 const value_type *__p = __data;
433 __data = __other.__data;
434 __other.__data = __p;
435
436 size_type __sz = __size;
437 __size = __other.__size;
438 __other.__size = __sz;
439 }
440
441 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
442 size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
443 {
444 if (__pos > size())
445 __throw_out_of_range(msg: "string_view::copy");
446 size_type __rlen = _VSTD::min(__n, size() - __pos);
447 _Traits::copy(__s, data() + __pos, __rlen);
448 return __rlen;
449 }
450
451 _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY
452 basic_string_view substr(size_type __pos = 0, size_type __n = npos) const
453 {
454 return __pos > size()
455 ? (__throw_out_of_range(msg: "string_view::substr"), basic_string_view())
456 : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos));
457 }
458
459 _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT
460 {
461 size_type __rlen = _VSTD::min( size(), __sv.size());
462 int __retval = _Traits::compare(data(), __sv.data(), __rlen);
463 if ( __retval == 0 ) // first __rlen chars matched
464 __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 );
465 return __retval;
466 }
467
468 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
469 int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const
470 {
471 return substr(pos: __pos1, n: __n1).compare(__sv);
472 }
473
474 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
475 int compare( size_type __pos1, size_type __n1,
476 basic_string_view __sv, size_type __pos2, size_type __n2) const
477 {
478 return substr(pos: __pos1, n: __n1).compare(__sv.substr(__pos2, __n2));
479 }
480
481 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
482 int compare(const _CharT* __s) const _NOEXCEPT
483 {
484 return compare(basic_string_view(__s));
485 }
486
487 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
488 int compare(size_type __pos1, size_type __n1, const _CharT* __s) const
489 {
490 return substr(pos: __pos1, n: __n1).compare(basic_string_view(__s));
491 }
492
493 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
494 int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const
495 {
496 return substr(pos: __pos1, n: __n1).compare(basic_string_view(__s, __n2));
497 }
498
499 // find
500 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
501 size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
502 {
503 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
504 return __str_find<value_type, size_type, traits_type, npos>
505 (data(), size(), __s.data(), __pos, __s.size());
506 }
507
508 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
509 size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT
510 {
511 return __str_find<value_type, size_type, traits_type, npos>
512 (data(), size(), __c, __pos);
513 }
514
515 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
516 size_type find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
517 {
518 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr");
519 return __str_find<value_type, size_type, traits_type, npos>
520 (data(), size(), __s, __pos, __n);
521 }
522
523 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
524 size_type find(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT
525 {
526 _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr");
527 return __str_find<value_type, size_type, traits_type, npos>
528 (data(), size(), __s, __pos, traits_type::length(__s));
529 }
530
531 // rfind
532 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
533 size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT
534 {
535 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr");
536 return __str_rfind<value_type, size_type, traits_type, npos>
537 (data(), size(), __s.data(), __pos, __s.size());
538 }
539
540 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
541 size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT
542 {
543 return __str_rfind<value_type, size_type, traits_type, npos>
544 (data(), size(), __c, __pos);
545 }
546
547 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
548 size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
549 {
550 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr");
551 return __str_rfind<value_type, size_type, traits_type, npos>
552 (data(), size(), __s, __pos, __n);
553 }
554
555 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
556 size_type rfind(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
557 {
558 _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr");
559 return __str_rfind<value_type, size_type, traits_type, npos>
560 (data(), size(), __s, __pos, traits_type::length(__s));
561 }
562
563 // find_first_of
564 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
565 size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT
566 {
567 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr");
568 return __str_find_first_of<value_type, size_type, traits_type, npos>
569 (data(), size(), __s.data(), __pos, __s.size());
570 }
571
572 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
573 size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT
574 { return find(__c, __pos); }
575
576 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
577 size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
578 {
579 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr");
580 return __str_find_first_of<value_type, size_type, traits_type, npos>
581 (data(), size(), __s, __pos, __n);
582 }
583
584 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
585 size_type find_first_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT
586 {
587 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr");
588 return __str_find_first_of<value_type, size_type, traits_type, npos>
589 (data(), size(), __s, __pos, traits_type::length(__s));
590 }
591
592 // find_last_of
593 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
594 size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
595 {
596 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr");
597 return __str_find_last_of<value_type, size_type, traits_type, npos>
598 (data(), size(), __s.data(), __pos, __s.size());
599 }
600
601 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
602 size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT
603 { return rfind(__c, __pos); }
604
605 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
606 size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
607 {
608 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr");
609 return __str_find_last_of<value_type, size_type, traits_type, npos>
610 (data(), size(), __s, __pos, __n);
611 }
612
613 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
614 size_type find_last_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
615 {
616 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr");
617 return __str_find_last_of<value_type, size_type, traits_type, npos>
618 (data(), size(), __s, __pos, traits_type::length(__s));
619 }
620
621 // find_first_not_of
622 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
623 size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT
624 {
625 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr");
626 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
627 (data(), size(), __s.data(), __pos, __s.size());
628 }
629
630 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
631 size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT
632 {
633 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
634 (data(), size(), __c, __pos);
635 }
636
637 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
638 size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
639 {
640 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr");
641 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
642 (data(), size(), __s, __pos, __n);
643 }
644
645 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
646 size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT
647 {
648 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr");
649 return __str_find_first_not_of<value_type, size_type, traits_type, npos>
650 (data(), size(), __s, __pos, traits_type::length(__s));
651 }
652
653 // find_last_not_of
654 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
655 size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT
656 {
657 _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr");
658 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
659 (data(), size(), __s.data(), __pos, __s.size());
660 }
661
662 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
663 size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT
664 {
665 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
666 (data(), size(), __c, __pos);
667 }
668
669 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
670 size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT
671 {
672 _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr");
673 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
674 (data(), size(), __s, __pos, __n);
675 }
676
677 _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
678 size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT
679 {
680 _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr");
681 return __str_find_last_not_of<value_type, size_type, traits_type, npos>
682 (data(), size(), __s, __pos, traits_type::length(__s));
683 }
684
685#if _LIBCPP_STD_VER > 17
686 constexpr _LIBCPP_INLINE_VISIBILITY
687 bool starts_with(basic_string_view __s) const noexcept
688 { return size() >= __s.size() && compare(0, __s.size(), __s) == 0; }
689
690 constexpr _LIBCPP_INLINE_VISIBILITY
691 bool starts_with(value_type __c) const noexcept
692 { return !empty() && _Traits::eq(front(), __c); }
693
694 constexpr _LIBCPP_INLINE_VISIBILITY
695 bool starts_with(const value_type* __s) const noexcept
696 { return starts_with(basic_string_view(__s)); }
697
698 constexpr _LIBCPP_INLINE_VISIBILITY
699 bool ends_with(basic_string_view __s) const noexcept
700 { return size() >= __s.size() && compare(size() - __s.size(), npos, __s) == 0; }
701
702 constexpr _LIBCPP_INLINE_VISIBILITY
703 bool ends_with(value_type __c) const noexcept
704 { return !empty() && _Traits::eq(back(), __c); }
705
706 constexpr _LIBCPP_INLINE_VISIBILITY
707 bool ends_with(const value_type* __s) const noexcept
708 { return ends_with(basic_string_view(__s)); }
709#endif
710
711#if _LIBCPP_STD_VER > 20
712 constexpr _LIBCPP_INLINE_VISIBILITY
713 bool contains(basic_string_view __sv) const noexcept
714 { return find(__sv) != npos; }
715
716 constexpr _LIBCPP_INLINE_VISIBILITY
717 bool contains(value_type __c) const noexcept
718 { return find(__c) != npos; }
719
720 constexpr _LIBCPP_INLINE_VISIBILITY
721 bool contains(const value_type* __s) const
722 { return find(__s) != npos; }
723#endif
724
725private:
726 const value_type* __data;
727 size_type __size;
728};
729
730#if _LIBCPP_STD_VER > 17
731template <class _CharT, class _Traits>
732inline constexpr bool ranges::enable_view<basic_string_view<_CharT, _Traits>> = true;
733
734template <class _CharT, class _Traits>
735inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true;
736#endif // _LIBCPP_STD_VER > 17
737
738// [string.view.deduct]
739
740#if _LIBCPP_STD_VER > 17
741template <contiguous_iterator _It, sized_sentinel_for<_It> _End>
742 basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>;
743#endif // _LIBCPP_STD_VER > 17
744
745
746#if _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
747template <ranges::contiguous_range _Range>
748 basic_string_view(_Range) -> basic_string_view<ranges::range_value_t<_Range>>;
749#endif // _LIBCPP_STD_VER > 20 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
750
751// [string.view.comparison]
752// operator ==
753template<class _CharT, class _Traits>
754_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
755bool operator==(basic_string_view<_CharT, _Traits> __lhs,
756 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
757{
758 if ( __lhs.size() != __rhs.size()) return false;
759 return __lhs.compare(__rhs) == 0;
760}
761
762// The dummy default template parameters are used to work around a MSVC issue with mangling, see VSO-409326 for details.
763// This applies to the other sufficient overloads below for the other comparison operators.
764template<class _CharT, class _Traits, int = 1>
765_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
766bool operator==(basic_string_view<_CharT, _Traits> __lhs,
767 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
768{
769 if ( __lhs.size() != __rhs.size()) return false;
770 return __lhs.compare(__rhs) == 0;
771}
772
773template<class _CharT, class _Traits, int = 2>
774_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
775bool operator==(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
776 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
777{
778 if ( __lhs.size() != __rhs.size()) return false;
779 return __lhs.compare(__rhs) == 0;
780}
781
782
783// operator !=
784template<class _CharT, class _Traits>
785_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
786bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
787{
788 if ( __lhs.size() != __rhs.size())
789 return true;
790 return __lhs.compare(__rhs) != 0;
791}
792
793template<class _CharT, class _Traits, int = 1>
794_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
795bool operator!=(basic_string_view<_CharT, _Traits> __lhs,
796 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
797{
798 if ( __lhs.size() != __rhs.size())
799 return true;
800 return __lhs.compare(__rhs) != 0;
801}
802
803template<class _CharT, class _Traits, int = 2>
804_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
805bool operator!=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
806 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
807{
808 if ( __lhs.size() != __rhs.size())
809 return true;
810 return __lhs.compare(__rhs) != 0;
811}
812
813
814// operator <
815template<class _CharT, class _Traits>
816_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
817bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
818{
819 return __lhs.compare(__rhs) < 0;
820}
821
822template<class _CharT, class _Traits, int = 1>
823_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
824bool operator<(basic_string_view<_CharT, _Traits> __lhs,
825 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
826{
827 return __lhs.compare(__rhs) < 0;
828}
829
830template<class _CharT, class _Traits, int = 2>
831_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
832bool operator<(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
833 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
834{
835 return __lhs.compare(__rhs) < 0;
836}
837
838
839// operator >
840template<class _CharT, class _Traits>
841_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
842bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
843{
844 return __lhs.compare(__rhs) > 0;
845}
846
847template<class _CharT, class _Traits, int = 1>
848_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
849bool operator>(basic_string_view<_CharT, _Traits> __lhs,
850 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
851{
852 return __lhs.compare(__rhs) > 0;
853}
854
855template<class _CharT, class _Traits, int = 2>
856_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
857bool operator>(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
858 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
859{
860 return __lhs.compare(__rhs) > 0;
861}
862
863
864// operator <=
865template<class _CharT, class _Traits>
866_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
867bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
868{
869 return __lhs.compare(__rhs) <= 0;
870}
871
872template<class _CharT, class _Traits, int = 1>
873_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
874bool operator<=(basic_string_view<_CharT, _Traits> __lhs,
875 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
876{
877 return __lhs.compare(__rhs) <= 0;
878}
879
880template<class _CharT, class _Traits, int = 2>
881_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
882bool operator<=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
883 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
884{
885 return __lhs.compare(__rhs) <= 0;
886}
887
888
889// operator >=
890template<class _CharT, class _Traits>
891_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
892bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
893{
894 return __lhs.compare(__rhs) >= 0;
895}
896
897
898template<class _CharT, class _Traits, int = 1>
899_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
900bool operator>=(basic_string_view<_CharT, _Traits> __lhs,
901 typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT
902{
903 return __lhs.compare(__rhs) >= 0;
904}
905
906template<class _CharT, class _Traits, int = 2>
907_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
908bool operator>=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs,
909 basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT
910{
911 return __lhs.compare(__rhs) >= 0;
912}
913
914
915template<class _CharT, class _Traits>
916basic_ostream<_CharT, _Traits>&
917operator<<(basic_ostream<_CharT, _Traits>& __os,
918 basic_string_view<_CharT, _Traits> __str);
919
920// [string.view.hash]
921template<class _CharT>
922struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, char_traits<_CharT> > >
923 : public __unary_function<basic_string_view<_CharT, char_traits<_CharT> >, size_t>
924{
925 _LIBCPP_INLINE_VISIBILITY
926 size_t operator()(const basic_string_view<_CharT, char_traits<_CharT> > __val) const _NOEXCEPT {
927 return __do_string_hash(__val.data(), __val.data() + __val.size());
928 }
929};
930
931#if _LIBCPP_STD_VER > 11
932inline namespace literals
933{
934 inline namespace string_view_literals
935 {
936 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
937 basic_string_view<char> operator "" sv(const char *__str, size_t __len) _NOEXCEPT
938 {
939 return basic_string_view<char> (__str, __len);
940 }
941
942#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
943 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
944 basic_string_view<wchar_t> operator "" sv(const wchar_t *__str, size_t __len) _NOEXCEPT
945 {
946 return basic_string_view<wchar_t> (__str, __len);
947 }
948#endif
949
950#ifndef _LIBCPP_HAS_NO_CHAR8_T
951 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
952 basic_string_view<char8_t> operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT
953 {
954 return basic_string_view<char8_t> (__str, __len);
955 }
956#endif
957
958 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
959 basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT
960 {
961 return basic_string_view<char16_t> (__str, __len);
962 }
963
964 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
965 basic_string_view<char32_t> operator "" sv(const char32_t *__str, size_t __len) _NOEXCEPT
966 {
967 return basic_string_view<char32_t> (__str, __len);
968 }
969 } // namespace string_view_literals
970} // namespace literals
971#endif
972_LIBCPP_END_NAMESPACE_STD
973
974_LIBCPP_POP_MACROS
975
976#endif // _LIBCPP_STRING_VIEW
977

source code of flutter_engine/third_party/libcxx/include/string_view