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