1 | // Components for manipulating non-owning sequences of characters -*- C++ -*-
|
---|
2 |
|
---|
3 | // Copyright (C) 2013-2021 Free Software Foundation, Inc.
|
---|
4 | //
|
---|
5 | // This file is part of the GNU ISO C++ Library. This library is free
|
---|
6 | // software; you can redistribute it and/or modify it under the
|
---|
7 | // terms of the GNU General Public License as published by the
|
---|
8 | // Free Software Foundation; either version 3, or (at your option)
|
---|
9 | // any later version.
|
---|
10 |
|
---|
11 | // This library is distributed in the hope that it will be useful,
|
---|
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
14 | // GNU General Public License for more details.
|
---|
15 |
|
---|
16 | // Under Section 7 of GPL version 3, you are granted additional
|
---|
17 | // permissions described in the GCC Runtime Library Exception, version
|
---|
18 | // 3.1, as published by the Free Software Foundation.
|
---|
19 |
|
---|
20 | // You should have received a copy of the GNU General Public License and
|
---|
21 | // a copy of the GCC Runtime Library Exception along with this program;
|
---|
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
---|
23 | // <http://www.gnu.org/licenses/>.
|
---|
24 |
|
---|
25 | /** @file include/string_view
|
---|
26 | * This is a Standard C++ Library header.
|
---|
27 | */
|
---|
28 |
|
---|
29 | //
|
---|
30 | // N3762 basic_string_view library
|
---|
31 | //
|
---|
32 |
|
---|
33 | #ifndef _GLIBCXX_STRING_VIEW
|
---|
34 | #define _GLIBCXX_STRING_VIEW 1
|
---|
35 |
|
---|
36 | #pragma GCC system_header
|
---|
37 |
|
---|
38 | #if __cplusplus >= 201703L
|
---|
39 |
|
---|
40 | #include <iosfwd>
|
---|
41 | #include <bits/char_traits.h>
|
---|
42 | #include <bits/functional_hash.h>
|
---|
43 | #include <bits/range_access.h>
|
---|
44 | #include <bits/ostream_insert.h>
|
---|
45 | #include <ext/numeric_traits.h>
|
---|
46 |
|
---|
47 | #if __cplusplus >= 202002L
|
---|
48 | # include <bits/ranges_base.h>
|
---|
49 | #endif
|
---|
50 |
|
---|
51 | namespace std _GLIBCXX_VISIBILITY(default)
|
---|
52 | {
|
---|
53 | _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
---|
54 |
|
---|
55 | # define __cpp_lib_string_view 201803L
|
---|
56 | #if __cplusplus > 201703L
|
---|
57 | # define __cpp_lib_constexpr_string_view 201811L
|
---|
58 | #endif
|
---|
59 |
|
---|
60 | // Helper for basic_string and basic_string_view members.
|
---|
61 | constexpr size_t
|
---|
62 | __sv_check(size_t __size, size_t __pos, const char* __s)
|
---|
63 | {
|
---|
64 | if (__pos > __size)
|
---|
65 | __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > __size "
|
---|
66 | "(which is %zu)"), __s, __pos, __size);
|
---|
67 | return __pos;
|
---|
68 | }
|
---|
69 |
|
---|
70 | // Helper for basic_string members.
|
---|
71 | // NB: __sv_limit doesn't check for a bad __pos value.
|
---|
72 | constexpr size_t
|
---|
73 | __sv_limit(size_t __size, size_t __pos, size_t __off) noexcept
|
---|
74 | {
|
---|
75 | const bool __testoff = __off < __size - __pos;
|
---|
76 | return __testoff ? __off : __size - __pos;
|
---|
77 | }
|
---|
78 |
|
---|
79 | /**
|
---|
80 | * @class basic_string_view <string_view>
|
---|
81 | * @brief A non-owning reference to a string.
|
---|
82 | *
|
---|
83 | * @ingroup strings
|
---|
84 | * @ingroup sequences
|
---|
85 | *
|
---|
86 | * @tparam _CharT Type of character
|
---|
87 | * @tparam _Traits Traits for character type, defaults to
|
---|
88 | * char_traits<_CharT>.
|
---|
89 | *
|
---|
90 | * A basic_string_view looks like this:
|
---|
91 | *
|
---|
92 | * @code
|
---|
93 | * _CharT* _M_str
|
---|
94 | * size_t _M_len
|
---|
95 | * @endcode
|
---|
96 | */
|
---|
97 | template<typename _CharT, typename _Traits = std::char_traits<_CharT>>
|
---|
98 | class basic_string_view
|
---|
99 | {
|
---|
100 | static_assert(!is_array_v<_CharT>);
|
---|
101 | static_assert(is_trivial_v<_CharT> && is_standard_layout_v<_CharT>);
|
---|
102 | static_assert(is_same_v<_CharT, typename _Traits::char_type>);
|
---|
103 |
|
---|
104 | public:
|
---|
105 |
|
---|
106 | // types
|
---|
107 | using traits_type = _Traits;
|
---|
108 | using value_type = _CharT;
|
---|
109 | using pointer = value_type*;
|
---|
110 | using const_pointer = const value_type*;
|
---|
111 | using reference = value_type&;
|
---|
112 | using const_reference = const value_type&;
|
---|
113 | using const_iterator = const value_type*;
|
---|
114 | using iterator = const_iterator;
|
---|
115 | using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
---|
116 | using reverse_iterator = const_reverse_iterator;
|
---|
117 | using size_type = size_t;
|
---|
118 | using difference_type = ptrdiff_t;
|
---|
119 | static constexpr size_type npos = size_type(-1);
|
---|
120 |
|
---|
121 | // [string.view.cons], construction and assignment
|
---|
122 |
|
---|
123 | constexpr
|
---|
124 | basic_string_view() noexcept
|
---|
125 | : _M_len{0}, _M_str{nullptr}
|
---|
126 | { }
|
---|
127 |
|
---|
128 | constexpr basic_string_view(const basic_string_view&) noexcept = default;
|
---|
129 |
|
---|
130 | __attribute__((__nonnull__)) constexpr
|
---|
131 | basic_string_view(const _CharT* __str) noexcept
|
---|
132 | : _M_len{traits_type::length(__str)},
|
---|
133 | _M_str{__str}
|
---|
134 | { }
|
---|
135 |
|
---|
136 | constexpr
|
---|
137 | basic_string_view(const _CharT* __str, size_type __len) noexcept
|
---|
138 | : _M_len{__len}, _M_str{__str}
|
---|
139 | { }
|
---|
140 |
|
---|
141 | #if __cplusplus >= 202002L && __cpp_lib_concepts
|
---|
142 | template<contiguous_iterator _It, sized_sentinel_for<_It> _End>
|
---|
143 | requires same_as<iter_value_t<_It>, _CharT>
|
---|
144 | && (!convertible_to<_End, size_type>)
|
---|
145 | constexpr
|
---|
146 | basic_string_view(_It __first, _End __last)
|
---|
147 | : _M_len(__last - __first), _M_str(std::to_address(__first))
|
---|
148 | { }
|
---|
149 |
|
---|
150 | #if __cplusplus > 202002L
|
---|
151 | template<typename _Range, typename _DRange = remove_cvref_t<_Range>>
|
---|
152 | requires (!is_same_v<_DRange, basic_string_view>)
|
---|
153 | && ranges::contiguous_range<_Range>
|
---|
154 | && ranges::sized_range<_Range>
|
---|
155 | && is_same_v<ranges::range_value_t<_Range>, _CharT>
|
---|
156 | && (!is_convertible_v<_Range, const _CharT*>)
|
---|
157 | && (!requires (_DRange& __d) {
|
---|
158 | __d.operator ::std::basic_string_view<_CharT, _Traits>();
|
---|
159 | })
|
---|
160 | && (!requires { typename _DRange::traits_type; }
|
---|
161 | || is_same_v<typename _DRange::traits_type, _Traits>)
|
---|
162 | constexpr
|
---|
163 | basic_string_view(_Range&& __r)
|
---|
164 | noexcept(noexcept(ranges::size(__r)) && noexcept(ranges::data(__r)))
|
---|
165 | : _M_len(ranges::size(__r)), _M_str(ranges::data(__r))
|
---|
166 | { }
|
---|
167 | #endif // C++23
|
---|
168 | #endif // C++20
|
---|
169 |
|
---|
170 | constexpr basic_string_view&
|
---|
171 | operator=(const basic_string_view&) noexcept = default;
|
---|
172 |
|
---|
173 | // [string.view.iterators], iterator support
|
---|
174 |
|
---|
175 | constexpr const_iterator
|
---|
176 | begin() const noexcept
|
---|
177 | { return this->_M_str; }
|
---|
178 |
|
---|
179 | constexpr const_iterator
|
---|
180 | end() const noexcept
|
---|
181 | { return this->_M_str + this->_M_len; }
|
---|
182 |
|
---|
183 | constexpr const_iterator
|
---|
184 | cbegin() const noexcept
|
---|
185 | { return this->_M_str; }
|
---|
186 |
|
---|
187 | constexpr const_iterator
|
---|
188 | cend() const noexcept
|
---|
189 | { return this->_M_str + this->_M_len; }
|
---|
190 |
|
---|
191 | constexpr const_reverse_iterator
|
---|
192 | rbegin() const noexcept
|
---|
193 | { return const_reverse_iterator(this->end()); }
|
---|
194 |
|
---|
195 | constexpr const_reverse_iterator
|
---|
196 | rend() const noexcept
|
---|
197 | { return const_reverse_iterator(this->begin()); }
|
---|
198 |
|
---|
199 | constexpr const_reverse_iterator
|
---|
200 | crbegin() const noexcept
|
---|
201 | { return const_reverse_iterator(this->end()); }
|
---|
202 |
|
---|
203 | constexpr const_reverse_iterator
|
---|
204 | crend() const noexcept
|
---|
205 | { return const_reverse_iterator(this->begin()); }
|
---|
206 |
|
---|
207 | // [string.view.capacity], capacity
|
---|
208 |
|
---|
209 | constexpr size_type
|
---|
210 | size() const noexcept
|
---|
211 | { return this->_M_len; }
|
---|
212 |
|
---|
213 | constexpr size_type
|
---|
214 | length() const noexcept
|
---|
215 | { return _M_len; }
|
---|
216 |
|
---|
217 | constexpr size_type
|
---|
218 | max_size() const noexcept
|
---|
219 | {
|
---|
220 | return (npos - sizeof(size_type) - sizeof(void*))
|
---|
221 | / sizeof(value_type) / 4;
|
---|
222 | }
|
---|
223 |
|
---|
224 | [[nodiscard]] constexpr bool
|
---|
225 | empty() const noexcept
|
---|
226 | { return this->_M_len == 0; }
|
---|
227 |
|
---|
228 | // [string.view.access], element access
|
---|
229 |
|
---|
230 | constexpr const_reference
|
---|
231 | operator[](size_type __pos) const noexcept
|
---|
232 | {
|
---|
233 | __glibcxx_assert(__pos < this->_M_len);
|
---|
234 | return *(this->_M_str + __pos);
|
---|
235 | }
|
---|
236 |
|
---|
237 | constexpr const_reference
|
---|
238 | at(size_type __pos) const
|
---|
239 | {
|
---|
240 | if (__pos >= _M_len)
|
---|
241 | __throw_out_of_range_fmt(__N("basic_string_view::at: __pos "
|
---|
242 | "(which is %zu) >= this->size() "
|
---|
243 | "(which is %zu)"), __pos, this->size());
|
---|
244 | return *(this->_M_str + __pos);
|
---|
245 | }
|
---|
246 |
|
---|
247 | constexpr const_reference
|
---|
248 | front() const noexcept
|
---|
249 | {
|
---|
250 | __glibcxx_assert(this->_M_len > 0);
|
---|
251 | return *this->_M_str;
|
---|
252 | }
|
---|
253 |
|
---|
254 | constexpr const_reference
|
---|
255 | back() const noexcept
|
---|
256 | {
|
---|
257 | __glibcxx_assert(this->_M_len > 0);
|
---|
258 | return *(this->_M_str + this->_M_len - 1);
|
---|
259 | }
|
---|
260 |
|
---|
261 | constexpr const_pointer
|
---|
262 | data() const noexcept
|
---|
263 | { return this->_M_str; }
|
---|
264 |
|
---|
265 | // [string.view.modifiers], modifiers:
|
---|
266 |
|
---|
267 | constexpr void
|
---|
268 | remove_prefix(size_type __n) noexcept
|
---|
269 | {
|
---|
270 | __glibcxx_assert(this->_M_len >= __n);
|
---|
271 | this->_M_str += __n;
|
---|
272 | this->_M_len -= __n;
|
---|
273 | }
|
---|
274 |
|
---|
275 | constexpr void
|
---|
276 | remove_suffix(size_type __n) noexcept
|
---|
277 | { this->_M_len -= __n; }
|
---|
278 |
|
---|
279 | constexpr void
|
---|
280 | swap(basic_string_view& __sv) noexcept
|
---|
281 | {
|
---|
282 | auto __tmp = *this;
|
---|
283 | *this = __sv;
|
---|
284 | __sv = __tmp;
|
---|
285 | }
|
---|
286 |
|
---|
287 | // [string.view.ops], string operations:
|
---|
288 |
|
---|
289 | _GLIBCXX20_CONSTEXPR
|
---|
290 | size_type
|
---|
291 | copy(_CharT* __str, size_type __n, size_type __pos = 0) const
|
---|
292 | {
|
---|
293 | __glibcxx_requires_string_len(__str, __n);
|
---|
294 | __pos = std::__sv_check(size(), __pos, "basic_string_view::copy");
|
---|
295 | const size_type __rlen = std::min(__n, _M_len - __pos);
|
---|
296 | // _GLIBCXX_RESOLVE_LIB_DEFECTS
|
---|
297 | // 2777. basic_string_view::copy should use char_traits::copy
|
---|
298 | traits_type::copy(__str, data() + __pos, __rlen);
|
---|
299 | return __rlen;
|
---|
300 | }
|
---|
301 |
|
---|
302 | constexpr basic_string_view
|
---|
303 | substr(size_type __pos = 0, size_type __n = npos) const noexcept(false)
|
---|
304 | {
|
---|
305 | __pos = std::__sv_check(size(), __pos, "basic_string_view::substr");
|
---|
306 | const size_type __rlen = std::min(__n, _M_len - __pos);
|
---|
307 | return basic_string_view{_M_str + __pos, __rlen};
|
---|
308 | }
|
---|
309 |
|
---|
310 | constexpr int
|
---|
311 | compare(basic_string_view __str) const noexcept
|
---|
312 | {
|
---|
313 | const size_type __rlen = std::min(this->_M_len, __str._M_len);
|
---|
314 | int __ret = traits_type::compare(this->_M_str, __str._M_str, __rlen);
|
---|
315 | if (__ret == 0)
|
---|
316 | __ret = _S_compare(this->_M_len, __str._M_len);
|
---|
317 | return __ret;
|
---|
318 | }
|
---|
319 |
|
---|
320 | constexpr int
|
---|
321 | compare(size_type __pos1, size_type __n1, basic_string_view __str) const
|
---|
322 | { return this->substr(__pos1, __n1).compare(__str); }
|
---|
323 |
|
---|
324 | constexpr int
|
---|
325 | compare(size_type __pos1, size_type __n1,
|
---|
326 | basic_string_view __str, size_type __pos2, size_type __n2) const
|
---|
327 | {
|
---|
328 | return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2));
|
---|
329 | }
|
---|
330 |
|
---|
331 | __attribute__((__nonnull__)) constexpr int
|
---|
332 | compare(const _CharT* __str) const noexcept
|
---|
333 | { return this->compare(basic_string_view{__str}); }
|
---|
334 |
|
---|
335 | __attribute__((__nonnull__)) constexpr int
|
---|
336 | compare(size_type __pos1, size_type __n1, const _CharT* __str) const
|
---|
337 | { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
|
---|
338 |
|
---|
339 | constexpr int
|
---|
340 | compare(size_type __pos1, size_type __n1,
|
---|
341 | const _CharT* __str, size_type __n2) const noexcept(false)
|
---|
342 | {
|
---|
343 | return this->substr(__pos1, __n1)
|
---|
344 | .compare(basic_string_view(__str, __n2));
|
---|
345 | }
|
---|
346 |
|
---|
347 | #if __cplusplus > 201703L
|
---|
348 | #define __cpp_lib_starts_ends_with 201711L
|
---|
349 | constexpr bool
|
---|
350 | starts_with(basic_string_view __x) const noexcept
|
---|
351 | { return this->substr(0, __x.size()) == __x; }
|
---|
352 |
|
---|
353 | constexpr bool
|
---|
354 | starts_with(_CharT __x) const noexcept
|
---|
355 | { return !this->empty() && traits_type::eq(this->front(), __x); }
|
---|
356 |
|
---|
357 | constexpr bool
|
---|
358 | starts_with(const _CharT* __x) const noexcept
|
---|
359 | { return this->starts_with(basic_string_view(__x)); }
|
---|
360 |
|
---|
361 | constexpr bool
|
---|
362 | ends_with(basic_string_view __x) const noexcept
|
---|
363 | {
|
---|
364 | const auto __len = this->size();
|
---|
365 | const auto __xlen = __x.size();
|
---|
366 | return __len >= __xlen
|
---|
367 | && traits_type::compare(end() - __xlen, __x.data(), __xlen) == 0;
|
---|
368 | }
|
---|
369 |
|
---|
370 | constexpr bool
|
---|
371 | ends_with(_CharT __x) const noexcept
|
---|
372 | { return !this->empty() && traits_type::eq(this->back(), __x); }
|
---|
373 |
|
---|
374 | constexpr bool
|
---|
375 | ends_with(const _CharT* __x) const noexcept
|
---|
376 | { return this->ends_with(basic_string_view(__x)); }
|
---|
377 | #endif // C++20
|
---|
378 |
|
---|
379 | #if __cplusplus > 202002L
|
---|
380 | #define __cpp_lib_string_contains 202011L
|
---|
381 | constexpr bool
|
---|
382 | contains(basic_string_view __x) const noexcept
|
---|
383 | { return this->find(__x) != npos; }
|
---|
384 |
|
---|
385 | constexpr bool
|
---|
386 | contains(_CharT __x) const noexcept
|
---|
387 | { return this->find(__x) != npos; }
|
---|
388 |
|
---|
389 | constexpr bool
|
---|
390 | contains(const _CharT* __x) const noexcept
|
---|
391 | { return this->find(__x) != npos; }
|
---|
392 | #endif // C++23
|
---|
393 |
|
---|
394 | // [string.view.find], searching
|
---|
395 |
|
---|
396 | constexpr size_type
|
---|
397 | find(basic_string_view __str, size_type __pos = 0) const noexcept
|
---|
398 | { return this->find(__str._M_str, __pos, __str._M_len); }
|
---|
399 |
|
---|
400 | constexpr size_type
|
---|
401 | find(_CharT __c, size_type __pos = 0) const noexcept;
|
---|
402 |
|
---|
403 | constexpr size_type
|
---|
404 | find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
|
---|
405 |
|
---|
406 | __attribute__((__nonnull__)) constexpr size_type
|
---|
407 | find(const _CharT* __str, size_type __pos = 0) const noexcept
|
---|
408 | { return this->find(__str, __pos, traits_type::length(__str)); }
|
---|
409 |
|
---|
410 | constexpr size_type
|
---|
411 | rfind(basic_string_view __str, size_type __pos = npos) const noexcept
|
---|
412 | { return this->rfind(__str._M_str, __pos, __str._M_len); }
|
---|
413 |
|
---|
414 | constexpr size_type
|
---|
415 | rfind(_CharT __c, size_type __pos = npos) const noexcept;
|
---|
416 |
|
---|
417 | constexpr size_type
|
---|
418 | rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
|
---|
419 |
|
---|
420 | __attribute__((__nonnull__)) constexpr size_type
|
---|
421 | rfind(const _CharT* __str, size_type __pos = npos) const noexcept
|
---|
422 | { return this->rfind(__str, __pos, traits_type::length(__str)); }
|
---|
423 |
|
---|
424 | constexpr size_type
|
---|
425 | find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept
|
---|
426 | { return this->find_first_of(__str._M_str, __pos, __str._M_len); }
|
---|
427 |
|
---|
428 | constexpr size_type
|
---|
429 | find_first_of(_CharT __c, size_type __pos = 0) const noexcept
|
---|
430 | { return this->find(__c, __pos); }
|
---|
431 |
|
---|
432 | constexpr size_type
|
---|
433 | find_first_of(const _CharT* __str, size_type __pos,
|
---|
434 | size_type __n) const noexcept;
|
---|
435 |
|
---|
436 | __attribute__((__nonnull__)) constexpr size_type
|
---|
437 | find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept
|
---|
438 | { return this->find_first_of(__str, __pos, traits_type::length(__str)); }
|
---|
439 |
|
---|
440 | constexpr size_type
|
---|
441 | find_last_of(basic_string_view __str,
|
---|
442 | size_type __pos = npos) const noexcept
|
---|
443 | { return this->find_last_of(__str._M_str, __pos, __str._M_len); }
|
---|
444 |
|
---|
445 | constexpr size_type
|
---|
446 | find_last_of(_CharT __c, size_type __pos=npos) const noexcept
|
---|
447 | { return this->rfind(__c, __pos); }
|
---|
448 |
|
---|
449 | constexpr size_type
|
---|
450 | find_last_of(const _CharT* __str, size_type __pos,
|
---|
451 | size_type __n) const noexcept;
|
---|
452 |
|
---|
453 | __attribute__((__nonnull__)) constexpr size_type
|
---|
454 | find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
|
---|
455 | { return this->find_last_of(__str, __pos, traits_type::length(__str)); }
|
---|
456 |
|
---|
457 | constexpr size_type
|
---|
458 | find_first_not_of(basic_string_view __str,
|
---|
459 | size_type __pos = 0) const noexcept
|
---|
460 | { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); }
|
---|
461 |
|
---|
462 | constexpr size_type
|
---|
463 | find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept;
|
---|
464 |
|
---|
465 | constexpr size_type
|
---|
466 | find_first_not_of(const _CharT* __str,
|
---|
467 | size_type __pos, size_type __n) const noexcept;
|
---|
468 |
|
---|
469 | __attribute__((__nonnull__)) constexpr size_type
|
---|
470 | find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept
|
---|
471 | {
|
---|
472 | return this->find_first_not_of(__str, __pos,
|
---|
473 | traits_type::length(__str));
|
---|
474 | }
|
---|
475 |
|
---|
476 | constexpr size_type
|
---|
477 | find_last_not_of(basic_string_view __str,
|
---|
478 | size_type __pos = npos) const noexcept
|
---|
479 | { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); }
|
---|
480 |
|
---|
481 | constexpr size_type
|
---|
482 | find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept;
|
---|
483 |
|
---|
484 | constexpr size_type
|
---|
485 | find_last_not_of(const _CharT* __str,
|
---|
486 | size_type __pos, size_type __n) const noexcept;
|
---|
487 |
|
---|
488 | __attribute__((__nonnull__)) constexpr size_type
|
---|
489 | find_last_not_of(const _CharT* __str,
|
---|
490 | size_type __pos = npos) const noexcept
|
---|
491 | {
|
---|
492 | return this->find_last_not_of(__str, __pos,
|
---|
493 | traits_type::length(__str));
|
---|
494 | }
|
---|
495 |
|
---|
496 | private:
|
---|
497 |
|
---|
498 | static constexpr int
|
---|
499 | _S_compare(size_type __n1, size_type __n2) noexcept
|
---|
500 | {
|
---|
501 | using __limits = __gnu_cxx::__int_traits<int>;
|
---|
502 | const difference_type __diff = __n1 - __n2;
|
---|
503 | if (__diff > __limits::__max)
|
---|
504 | return __limits::__max;
|
---|
505 | if (__diff < __limits::__min)
|
---|
506 | return __limits::__min;
|
---|
507 | return static_cast<int>(__diff);
|
---|
508 | }
|
---|
509 |
|
---|
510 | size_t _M_len;
|
---|
511 | const _CharT* _M_str;
|
---|
512 | };
|
---|
513 |
|
---|
514 | #if __cplusplus > 201703L && __cpp_lib_concepts && __cpp_deduction_guides
|
---|
515 | template<contiguous_iterator _It, sized_sentinel_for<_It> _End>
|
---|
516 | basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>;
|
---|
517 |
|
---|
518 | #if __cplusplus > 202002L
|
---|
519 | template<ranges::contiguous_range _Range>
|
---|
520 | basic_string_view(_Range&&)
|
---|
521 | -> basic_string_view<ranges::range_value_t<_Range>>;
|
---|
522 | #endif
|
---|
523 | #endif
|
---|
524 |
|
---|
525 | // [string.view.comparison], non-member basic_string_view comparison function
|
---|
526 |
|
---|
527 | // Several of these functions use type_identity_t to create a non-deduced
|
---|
528 | // context, so that only one argument participates in template argument
|
---|
529 | // deduction and the other argument gets implicitly converted to the deduced
|
---|
530 | // type (see N3766).
|
---|
531 |
|
---|
532 | template<typename _CharT, typename _Traits>
|
---|
533 | constexpr bool
|
---|
534 | operator==(basic_string_view<_CharT, _Traits> __x,
|
---|
535 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
536 | { return __x.size() == __y.size() && __x.compare(__y) == 0; }
|
---|
537 |
|
---|
538 | template<typename _CharT, typename _Traits>
|
---|
539 | constexpr bool
|
---|
540 | operator==(basic_string_view<_CharT, _Traits> __x,
|
---|
541 | __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
|
---|
542 | noexcept
|
---|
543 | { return __x.size() == __y.size() && __x.compare(__y) == 0; }
|
---|
544 |
|
---|
545 | #if __cpp_lib_three_way_comparison
|
---|
546 | template<typename _CharT, typename _Traits>
|
---|
547 | constexpr auto
|
---|
548 | operator<=>(basic_string_view<_CharT, _Traits> __x,
|
---|
549 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
550 | -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
|
---|
551 | { return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); }
|
---|
552 |
|
---|
553 | template<typename _CharT, typename _Traits>
|
---|
554 | constexpr auto
|
---|
555 | operator<=>(basic_string_view<_CharT, _Traits> __x,
|
---|
556 | __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
|
---|
557 | noexcept
|
---|
558 | -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
|
---|
559 | { return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); }
|
---|
560 | #else
|
---|
561 | template<typename _CharT, typename _Traits>
|
---|
562 | constexpr bool
|
---|
563 | operator==(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
|
---|
564 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
565 | { return __x.size() == __y.size() && __x.compare(__y) == 0; }
|
---|
566 |
|
---|
567 | template<typename _CharT, typename _Traits>
|
---|
568 | constexpr bool
|
---|
569 | operator!=(basic_string_view<_CharT, _Traits> __x,
|
---|
570 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
571 | { return !(__x == __y); }
|
---|
572 |
|
---|
573 | template<typename _CharT, typename _Traits>
|
---|
574 | constexpr bool
|
---|
575 | operator!=(basic_string_view<_CharT, _Traits> __x,
|
---|
576 | __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
|
---|
577 | noexcept
|
---|
578 | { return !(__x == __y); }
|
---|
579 |
|
---|
580 | template<typename _CharT, typename _Traits>
|
---|
581 | constexpr bool
|
---|
582 | operator!=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
|
---|
583 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
584 | { return !(__x == __y); }
|
---|
585 |
|
---|
586 | template<typename _CharT, typename _Traits>
|
---|
587 | constexpr bool
|
---|
588 | operator< (basic_string_view<_CharT, _Traits> __x,
|
---|
589 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
590 | { return __x.compare(__y) < 0; }
|
---|
591 |
|
---|
592 | template<typename _CharT, typename _Traits>
|
---|
593 | constexpr bool
|
---|
594 | operator< (basic_string_view<_CharT, _Traits> __x,
|
---|
595 | __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
|
---|
596 | noexcept
|
---|
597 | { return __x.compare(__y) < 0; }
|
---|
598 |
|
---|
599 | template<typename _CharT, typename _Traits>
|
---|
600 | constexpr bool
|
---|
601 | operator< (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
|
---|
602 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
603 | { return __x.compare(__y) < 0; }
|
---|
604 |
|
---|
605 | template<typename _CharT, typename _Traits>
|
---|
606 | constexpr bool
|
---|
607 | operator> (basic_string_view<_CharT, _Traits> __x,
|
---|
608 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
609 | { return __x.compare(__y) > 0; }
|
---|
610 |
|
---|
611 | template<typename _CharT, typename _Traits>
|
---|
612 | constexpr bool
|
---|
613 | operator> (basic_string_view<_CharT, _Traits> __x,
|
---|
614 | __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
|
---|
615 | noexcept
|
---|
616 | { return __x.compare(__y) > 0; }
|
---|
617 |
|
---|
618 | template<typename _CharT, typename _Traits>
|
---|
619 | constexpr bool
|
---|
620 | operator> (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
|
---|
621 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
622 | { return __x.compare(__y) > 0; }
|
---|
623 |
|
---|
624 | template<typename _CharT, typename _Traits>
|
---|
625 | constexpr bool
|
---|
626 | operator<=(basic_string_view<_CharT, _Traits> __x,
|
---|
627 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
628 | { return __x.compare(__y) <= 0; }
|
---|
629 |
|
---|
630 | template<typename _CharT, typename _Traits>
|
---|
631 | constexpr bool
|
---|
632 | operator<=(basic_string_view<_CharT, _Traits> __x,
|
---|
633 | __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
|
---|
634 | noexcept
|
---|
635 | { return __x.compare(__y) <= 0; }
|
---|
636 |
|
---|
637 | template<typename _CharT, typename _Traits>
|
---|
638 | constexpr bool
|
---|
639 | operator<=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
|
---|
640 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
641 | { return __x.compare(__y) <= 0; }
|
---|
642 |
|
---|
643 | template<typename _CharT, typename _Traits>
|
---|
644 | constexpr bool
|
---|
645 | operator>=(basic_string_view<_CharT, _Traits> __x,
|
---|
646 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
647 | { return __x.compare(__y) >= 0; }
|
---|
648 |
|
---|
649 | template<typename _CharT, typename _Traits>
|
---|
650 | constexpr bool
|
---|
651 | operator>=(basic_string_view<_CharT, _Traits> __x,
|
---|
652 | __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
|
---|
653 | noexcept
|
---|
654 | { return __x.compare(__y) >= 0; }
|
---|
655 |
|
---|
656 | template<typename _CharT, typename _Traits>
|
---|
657 | constexpr bool
|
---|
658 | operator>=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
|
---|
659 | basic_string_view<_CharT, _Traits> __y) noexcept
|
---|
660 | { return __x.compare(__y) >= 0; }
|
---|
661 | #endif // three-way comparison
|
---|
662 |
|
---|
663 | // [string.view.io], Inserters and extractors
|
---|
664 | template<typename _CharT, typename _Traits>
|
---|
665 | inline basic_ostream<_CharT, _Traits>&
|
---|
666 | operator<<(basic_ostream<_CharT, _Traits>& __os,
|
---|
667 | basic_string_view<_CharT,_Traits> __str)
|
---|
668 | { return __ostream_insert(__os, __str.data(), __str.size()); }
|
---|
669 |
|
---|
670 |
|
---|
671 | // basic_string_view typedef names
|
---|
672 |
|
---|
673 | using string_view = basic_string_view<char>;
|
---|
674 | #ifdef _GLIBCXX_USE_WCHAR_T
|
---|
675 | using wstring_view = basic_string_view<wchar_t>;
|
---|
676 | #endif
|
---|
677 | #ifdef _GLIBCXX_USE_CHAR8_T
|
---|
678 | using u8string_view = basic_string_view<char8_t>;
|
---|
679 | #endif
|
---|
680 | using u16string_view = basic_string_view<char16_t>;
|
---|
681 | using u32string_view = basic_string_view<char32_t>;
|
---|
682 |
|
---|
683 | // [string.view.hash], hash support:
|
---|
684 |
|
---|
685 | template<typename _Tp>
|
---|
686 | struct hash;
|
---|
687 |
|
---|
688 | template<>
|
---|
689 | struct hash<string_view>
|
---|
690 | : public __hash_base<size_t, string_view>
|
---|
691 | {
|
---|
692 | size_t
|
---|
693 | operator()(const string_view& __str) const noexcept
|
---|
694 | { return std::_Hash_impl::hash(__str.data(), __str.length()); }
|
---|
695 | };
|
---|
696 |
|
---|
697 | template<>
|
---|
698 | struct __is_fast_hash<hash<string_view>> : std::false_type
|
---|
699 | { };
|
---|
700 |
|
---|
701 | #ifdef _GLIBCXX_USE_WCHAR_T
|
---|
702 | template<>
|
---|
703 | struct hash<wstring_view>
|
---|
704 | : public __hash_base<size_t, wstring_view>
|
---|
705 | {
|
---|
706 | size_t
|
---|
707 | operator()(const wstring_view& __s) const noexcept
|
---|
708 | { return std::_Hash_impl::hash(__s.data(),
|
---|
709 | __s.length() * sizeof(wchar_t)); }
|
---|
710 | };
|
---|
711 |
|
---|
712 | template<>
|
---|
713 | struct __is_fast_hash<hash<wstring_view>> : std::false_type
|
---|
714 | { };
|
---|
715 | #endif
|
---|
716 |
|
---|
717 | #ifdef _GLIBCXX_USE_CHAR8_T
|
---|
718 | template<>
|
---|
719 | struct hash<u8string_view>
|
---|
720 | : public __hash_base<size_t, u8string_view>
|
---|
721 | {
|
---|
722 | size_t
|
---|
723 | operator()(const u8string_view& __str) const noexcept
|
---|
724 | { return std::_Hash_impl::hash(__str.data(), __str.length()); }
|
---|
725 | };
|
---|
726 |
|
---|
727 | template<>
|
---|
728 | struct __is_fast_hash<hash<u8string_view>> : std::false_type
|
---|
729 | { };
|
---|
730 | #endif
|
---|
731 |
|
---|
732 | template<>
|
---|
733 | struct hash<u16string_view>
|
---|
734 | : public __hash_base<size_t, u16string_view>
|
---|
735 | {
|
---|
736 | size_t
|
---|
737 | operator()(const u16string_view& __s) const noexcept
|
---|
738 | { return std::_Hash_impl::hash(__s.data(),
|
---|
739 | __s.length() * sizeof(char16_t)); }
|
---|
740 | };
|
---|
741 |
|
---|
742 | template<>
|
---|
743 | struct __is_fast_hash<hash<u16string_view>> : std::false_type
|
---|
744 | { };
|
---|
745 |
|
---|
746 | template<>
|
---|
747 | struct hash<u32string_view>
|
---|
748 | : public __hash_base<size_t, u32string_view>
|
---|
749 | {
|
---|
750 | size_t
|
---|
751 | operator()(const u32string_view& __s) const noexcept
|
---|
752 | { return std::_Hash_impl::hash(__s.data(),
|
---|
753 | __s.length() * sizeof(char32_t)); }
|
---|
754 | };
|
---|
755 |
|
---|
756 | template<>
|
---|
757 | struct __is_fast_hash<hash<u32string_view>> : std::false_type
|
---|
758 | { };
|
---|
759 |
|
---|
760 | inline namespace literals
|
---|
761 | {
|
---|
762 | inline namespace string_view_literals
|
---|
763 | {
|
---|
764 | #pragma GCC diagnostic push
|
---|
765 | #pragma GCC diagnostic ignored "-Wliteral-suffix"
|
---|
766 | inline constexpr basic_string_view<char>
|
---|
767 | operator""sv(const char* __str, size_t __len) noexcept
|
---|
768 | { return basic_string_view<char>{__str, __len}; }
|
---|
769 |
|
---|
770 | #ifdef _GLIBCXX_USE_WCHAR_T
|
---|
771 | inline constexpr basic_string_view<wchar_t>
|
---|
772 | operator""sv(const wchar_t* __str, size_t __len) noexcept
|
---|
773 | { return basic_string_view<wchar_t>{__str, __len}; }
|
---|
774 | #endif
|
---|
775 |
|
---|
776 | #ifdef _GLIBCXX_USE_CHAR8_T
|
---|
777 | inline constexpr basic_string_view<char8_t>
|
---|
778 | operator""sv(const char8_t* __str, size_t __len) noexcept
|
---|
779 | { return basic_string_view<char8_t>{__str, __len}; }
|
---|
780 | #endif
|
---|
781 |
|
---|
782 | inline constexpr basic_string_view<char16_t>
|
---|
783 | operator""sv(const char16_t* __str, size_t __len) noexcept
|
---|
784 | { return basic_string_view<char16_t>{__str, __len}; }
|
---|
785 |
|
---|
786 | inline constexpr basic_string_view<char32_t>
|
---|
787 | operator""sv(const char32_t* __str, size_t __len) noexcept
|
---|
788 | { return basic_string_view<char32_t>{__str, __len}; }
|
---|
789 |
|
---|
790 | #pragma GCC diagnostic pop
|
---|
791 | } // namespace string_literals
|
---|
792 | } // namespace literals
|
---|
793 |
|
---|
794 | #if __cpp_lib_concepts
|
---|
795 | namespace ranges
|
---|
796 | {
|
---|
797 | // Opt-in to borrowed_range concept
|
---|
798 | template<typename _CharT, typename _Traits>
|
---|
799 | inline constexpr bool
|
---|
800 | enable_borrowed_range<basic_string_view<_CharT, _Traits>> = true;
|
---|
801 |
|
---|
802 | // Opt-in to view concept
|
---|
803 | template<typename _CharT, typename _Traits>
|
---|
804 | inline constexpr bool
|
---|
805 | enable_view<basic_string_view<_CharT, _Traits>> = true;
|
---|
806 | }
|
---|
807 | #endif
|
---|
808 | _GLIBCXX_END_NAMESPACE_VERSION
|
---|
809 | } // namespace std
|
---|
810 |
|
---|
811 | #include <bits/string_view.tcc>
|
---|
812 |
|
---|
813 | #endif // __cplusplus <= 201402L
|
---|
814 |
|
---|
815 | #endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW
|
---|