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