]>
Commit | Line | Data |
---|---|---|
2fd2d470 | 1 | // Components for manipulating non-owning sequences of characters -*- C++ -*- |
2 | ||
f1717362 | 3 | // Copyright (C) 2013-2016 Free Software Foundation, Inc. |
2fd2d470 | 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 experimental/string_view | |
91315195 | 26 | * This is a TS C++ Library header. |
2fd2d470 | 27 | */ |
28 | ||
29 | // | |
503add89 | 30 | // N3762 basic_string_view library |
2fd2d470 | 31 | // |
32 | ||
33 | #ifndef _GLIBCXX_EXPERIMENTAL_STRING_VIEW | |
34 | #define _GLIBCXX_EXPERIMENTAL_STRING_VIEW 1 | |
35 | ||
36 | #pragma GCC system_header | |
37 | ||
38 | #if __cplusplus <= 201103L | |
39 | # include <bits/c++14_warning.h> | |
40 | #else | |
41 | ||
2fd2d470 | 42 | #include <string> |
43 | #include <limits> | |
44 | ||
7f8a3f49 | 45 | namespace std _GLIBCXX_VISIBILITY(default) |
2fd2d470 | 46 | { |
47 | namespace experimental | |
48 | { | |
0a394876 | 49 | inline namespace fundamentals_v1 |
50 | { | |
2fd2d470 | 51 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
52 | ||
82fe3c60 | 53 | #define __cpp_lib_experimental_string_view 201411 |
a5118bd7 | 54 | |
2fd2d470 | 55 | /** |
8787f26b | 56 | * @class basic_string_view <experimental/string_view> |
2fd2d470 | 57 | * @brief A non-owning reference to a string. |
58 | * | |
59 | * @ingroup strings | |
60 | * @ingroup sequences | |
8787f26b | 61 | * @ingroup experimental |
2fd2d470 | 62 | * |
63 | * @tparam _CharT Type of character | |
64 | * @tparam _Traits Traits for character type, defaults to | |
65 | * char_traits<_CharT>. | |
66 | * | |
67 | * A basic_string_view looks like this: | |
68 | * | |
69 | * @code | |
70 | * _CharT* _M_str | |
71 | * size_t _M_len | |
72 | * @endcode | |
73 | */ | |
4f3db60b | 74 | template<typename _CharT, typename _Traits = std::char_traits<_CharT>> |
2fd2d470 | 75 | class basic_string_view |
76 | { | |
2fd2d470 | 77 | public: |
78 | ||
79 | // types | |
80 | using traits_type = _Traits; | |
81 | using value_type = _CharT; | |
82 | using pointer = const _CharT*; | |
83 | using const_pointer = const _CharT*; | |
84 | using reference = const _CharT&; | |
85 | using const_reference = const _CharT&; | |
86 | using const_iterator = const _CharT*; | |
87 | using iterator = const_iterator; | |
88 | using const_reverse_iterator = std::reverse_iterator<const_iterator>; | |
89 | using reverse_iterator = const_reverse_iterator; | |
90 | using size_type = size_t; | |
91 | using difference_type = ptrdiff_t; | |
92 | static constexpr size_type npos = size_type(-1); | |
93 | ||
94 | // [string.view.cons], construct/copy | |
95 | ||
96 | constexpr | |
97 | basic_string_view() noexcept | |
4f3db60b | 98 | : _M_len{0}, _M_str{nullptr} |
2fd2d470 | 99 | { } |
100 | ||
101 | constexpr basic_string_view(const basic_string_view&) noexcept = default; | |
102 | ||
103 | template<typename _Allocator> | |
8cf2895d | 104 | basic_string_view(const basic_string<_CharT, _Traits, |
105 | _Allocator>& __str) noexcept | |
2fd2d470 | 106 | : _M_len{__str.length()}, _M_str{__str.data()} |
107 | { } | |
108 | ||
109 | constexpr basic_string_view(const _CharT* __str) | |
7f8a3f49 | 110 | : _M_len{__str == nullptr ? 0 : traits_type::length(__str)}, |
4f3db60b | 111 | _M_str{__str} |
2fd2d470 | 112 | { } |
113 | ||
114 | constexpr basic_string_view(const _CharT* __str, size_type __len) | |
4f3db60b | 115 | : _M_len{__len}, |
116 | _M_str{__str} | |
2fd2d470 | 117 | { } |
118 | ||
119 | basic_string_view& | |
120 | operator=(const basic_string_view&) noexcept = default; | |
121 | ||
122 | // [string.view.iterators], iterators | |
123 | ||
124 | constexpr const_iterator | |
125 | begin() const noexcept | |
126 | { return this->_M_str; } | |
127 | ||
128 | constexpr const_iterator | |
129 | end() const noexcept | |
130 | { return this->_M_str + this->_M_len; } | |
131 | ||
132 | constexpr const_iterator | |
133 | cbegin() const noexcept | |
134 | { return this->_M_str; } | |
135 | ||
136 | constexpr const_iterator | |
137 | cend() const noexcept | |
138 | { return this->_M_str + this->_M_len; } | |
139 | ||
140 | const_reverse_iterator | |
141 | rbegin() const noexcept | |
4f3db60b | 142 | { return const_reverse_iterator(this->end()); } |
2fd2d470 | 143 | |
144 | const_reverse_iterator | |
145 | rend() const noexcept | |
4f3db60b | 146 | { return const_reverse_iterator(this->begin()); } |
2fd2d470 | 147 | |
148 | const_reverse_iterator | |
149 | crbegin() const noexcept | |
4f3db60b | 150 | { return const_reverse_iterator(this->end()); } |
2fd2d470 | 151 | |
152 | const_reverse_iterator | |
153 | crend() const noexcept | |
4f3db60b | 154 | { return const_reverse_iterator(this->begin()); } |
2fd2d470 | 155 | |
156 | // [string.view.capacity], capacity | |
157 | ||
158 | constexpr size_type | |
159 | size() const noexcept | |
160 | { return this->_M_len; } | |
161 | ||
162 | constexpr size_type | |
163 | length() const noexcept | |
164 | { return _M_len; } | |
165 | ||
166 | constexpr size_type | |
167 | max_size() const noexcept | |
4f3db60b | 168 | { |
169 | return (npos - sizeof(size_type) - sizeof(void*)) | |
170 | / sizeof(value_type) / 4; | |
171 | } | |
2fd2d470 | 172 | |
173 | constexpr bool | |
174 | empty() const noexcept | |
175 | { return this->_M_len == 0; } | |
176 | ||
177 | // [string.view.access], element access | |
178 | ||
179 | constexpr const _CharT& | |
180 | operator[](size_type __pos) const | |
181 | { | |
de01d860 | 182 | // TODO: Assert to restore in a way compatible with the constexpr. |
6b5e6f09 | 183 | // __glibcxx_assert(__pos < this->_M_len); |
2fd2d470 | 184 | return *(this->_M_str + __pos); |
185 | } | |
186 | ||
187 | constexpr const _CharT& | |
188 | at(size_type __pos) const | |
189 | { | |
190 | return __pos < this->_M_len | |
191 | ? *(this->_M_str + __pos) | |
192 | : (__throw_out_of_range_fmt(__N("basic_string_view::at: __pos " | |
193 | "(which is %zu) >= this->size() " | |
194 | "(which is %zu)"), | |
195 | __pos, this->size()), | |
4f3db60b | 196 | *this->_M_str); |
2fd2d470 | 197 | } |
198 | ||
199 | constexpr const _CharT& | |
200 | front() const | |
201 | { | |
de01d860 | 202 | // TODO: Assert to restore in a way compatible with the constexpr. |
6b5e6f09 | 203 | // __glibcxx_assert(this->_M_len > 0); |
2fd2d470 | 204 | return *this->_M_str; |
205 | } | |
206 | ||
207 | constexpr const _CharT& | |
208 | back() const | |
209 | { | |
de01d860 | 210 | // TODO: Assert to restore in a way compatible with the constexpr. |
6b5e6f09 | 211 | // __glibcxx_assert(this->_M_len > 0); |
2fd2d470 | 212 | return *(this->_M_str + this->_M_len - 1); |
213 | } | |
214 | ||
215 | constexpr const _CharT* | |
216 | data() const noexcept | |
217 | { return this->_M_str; } | |
218 | ||
219 | // [string.view.modifiers], modifiers: | |
4f3db60b | 220 | |
2fd2d470 | 221 | void |
222 | remove_prefix(size_type __n) | |
223 | { | |
6b5e6f09 | 224 | __glibcxx_assert(this->_M_len >= __n); |
2fd2d470 | 225 | this->_M_str += __n; |
226 | this->_M_len -= __n; | |
227 | } | |
228 | ||
229 | void | |
230 | remove_suffix(size_type __n) | |
231 | { this->_M_len -= __n; } | |
232 | ||
233 | void | |
234 | swap(basic_string_view& __sv) noexcept | |
235 | { | |
236 | std::swap(this->_M_len, __sv._M_len); | |
237 | std::swap(this->_M_str, __sv._M_str); | |
238 | } | |
239 | ||
240 | ||
241 | // [string.view.ops], string operations: | |
242 | ||
243 | template<typename _Allocator> | |
244 | explicit operator basic_string<_CharT, _Traits, _Allocator>() const | |
245 | { | |
4f3db60b | 246 | return { this->_M_str, this->_M_len }; |
247 | } | |
248 | ||
249 | template<typename _Allocator = std::allocator<_CharT>> | |
250 | basic_string<_CharT, _Traits, _Allocator> | |
251 | to_string(const _Allocator& __alloc = _Allocator()) const | |
252 | { | |
253 | return { this->_M_str, this->_M_len, __alloc }; | |
2fd2d470 | 254 | } |
255 | ||
256 | size_type | |
257 | copy(_CharT* __str, size_type __n, size_type __pos = 0) const | |
258 | { | |
259 | __glibcxx_requires_string_len(__str, __n); | |
887e376f | 260 | if (__pos > this->_M_len) |
261 | __throw_out_of_range_fmt(__N("basic_string_view::copy: __pos " | |
262 | "(which is %zu) > this->size() " | |
2fd2d470 | 263 | "(which is %zu)"), |
264 | __pos, this->size()); | |
265 | size_type __rlen{std::min(__n, size_type{this->_M_len - __pos})}; | |
266 | for (auto __begin = this->_M_str + __pos, | |
887e376f | 267 | __end = __begin + __rlen; __begin != __end;) |
2fd2d470 | 268 | *__str++ = *__begin++; |
269 | return __rlen; | |
270 | } | |
271 | ||
272 | ||
273 | // [string.view.ops], string operations: | |
274 | ||
275 | constexpr basic_string_view | |
276 | substr(size_type __pos, size_type __n=npos) const | |
277 | { | |
887e376f | 278 | return __pos <= this->_M_len |
2fd2d470 | 279 | ? basic_string_view{this->_M_str + __pos, |
280 | std::min(__n, size_type{this->_M_len - __pos})} | |
887e376f | 281 | : (__throw_out_of_range_fmt(__N("basic_string_view::substr: __pos " |
282 | "(which is %zu) > this->size() " | |
2fd2d470 | 283 | "(which is %zu)"), |
284 | __pos, this->size()), basic_string_view{}); | |
285 | } | |
286 | ||
287 | int | |
288 | compare(basic_string_view __str) const noexcept | |
289 | { | |
290 | int __ret = traits_type::compare(this->_M_str, __str._M_str, | |
291 | std::min(this->_M_len, __str._M_len)); | |
292 | if (__ret == 0) | |
293 | __ret = _S_compare(this->_M_len, __str._M_len); | |
294 | return __ret; | |
295 | } | |
296 | ||
297 | int | |
298 | compare(size_type __pos1, size_type __n1, basic_string_view __str) const | |
299 | { return this->substr(__pos1, __n1).compare(__str); } | |
300 | ||
301 | int | |
302 | compare(size_type __pos1, size_type __n1, | |
303 | basic_string_view __str, size_type __pos2, size_type __n2) const | |
304 | { return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); } | |
305 | ||
306 | int | |
307 | compare(const _CharT* __str) const noexcept | |
308 | { return this->compare(basic_string_view{__str}); } | |
309 | ||
310 | int | |
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 | int | |
315 | compare(size_type __pos1, size_type __n1, | |
316 | const _CharT* __str, size_type __n2) const | |
317 | { | |
318 | return this->substr(__pos1, __n1) | |
319 | .compare(basic_string_view(__str, __n2)); | |
320 | } | |
321 | ||
322 | size_type | |
323 | find(basic_string_view __str, size_type __pos = 0) const noexcept | |
324 | { return this->find(__str._M_str, __pos, __str._M_len); } | |
325 | ||
326 | size_type | |
327 | find(_CharT __c, size_type __pos=0) const noexcept; | |
328 | ||
329 | size_type | |
379f3e0a | 330 | find(const _CharT* __str, size_type __pos, size_type __n) const noexcept; |
2fd2d470 | 331 | |
332 | size_type | |
333 | find(const _CharT* __str, size_type __pos=0) const noexcept | |
334 | { return this->find(__str, __pos, traits_type::length(__str)); } | |
335 | ||
336 | size_type | |
337 | rfind(basic_string_view __str, size_type __pos = npos) const noexcept | |
338 | { return this->rfind(__str._M_str, __pos, __str._M_len); } | |
339 | ||
340 | size_type | |
341 | rfind(_CharT __c, size_type __pos = npos) const noexcept; | |
342 | ||
343 | size_type | |
379f3e0a | 344 | rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept; |
2fd2d470 | 345 | |
346 | size_type | |
347 | rfind(const _CharT* __str, size_type __pos = npos) const noexcept | |
348 | { return this->rfind(__str, __pos, traits_type::length(__str)); } | |
349 | ||
350 | size_type | |
351 | find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept | |
352 | { return this->find_first_of(__str._M_str, __pos, __str._M_len); } | |
353 | ||
354 | size_type | |
355 | find_first_of(_CharT __c, size_type __pos = 0) const noexcept | |
356 | { return this->find(__c, __pos); } | |
357 | ||
358 | size_type | |
359 | find_first_of(const _CharT* __str, size_type __pos, size_type __n) const; | |
360 | ||
361 | size_type | |
362 | find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept | |
363 | { return this->find_first_of(__str, __pos, traits_type::length(__str)); } | |
364 | ||
365 | size_type | |
366 | find_last_of(basic_string_view __str, | |
367 | size_type __pos = npos) const noexcept | |
368 | { return this->find_last_of(__str._M_str, __pos, __str._M_len); } | |
369 | ||
370 | size_type | |
371 | find_last_of(_CharT __c, size_type __pos=npos) const noexcept | |
372 | { return this->rfind(__c, __pos); } | |
373 | ||
374 | size_type | |
375 | find_last_of(const _CharT* __str, size_type __pos, size_type __n) const; | |
376 | ||
377 | size_type | |
378 | find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept | |
379 | { return this->find_last_of(__str, __pos, traits_type::length(__str)); } | |
380 | ||
381 | size_type | |
382 | find_first_not_of(basic_string_view __str, | |
383 | size_type __pos = 0) const noexcept | |
384 | { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); } | |
385 | ||
386 | size_type | |
387 | find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept; | |
388 | ||
389 | size_type | |
390 | find_first_not_of(const _CharT* __str, | |
391 | size_type __pos, size_type __n) const; | |
392 | ||
393 | size_type | |
394 | find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept | |
395 | { | |
396 | return this->find_first_not_of(__str, __pos, | |
397 | traits_type::length(__str)); | |
398 | } | |
399 | ||
400 | size_type | |
401 | find_last_not_of(basic_string_view __str, | |
402 | size_type __pos = npos) const noexcept | |
403 | { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); } | |
404 | ||
405 | size_type | |
406 | find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept; | |
407 | ||
408 | size_type | |
409 | find_last_not_of(const _CharT* __str, | |
410 | size_type __pos, size_type __n) const; | |
411 | ||
412 | size_type | |
413 | find_last_not_of(const _CharT* __str, | |
414 | size_type __pos = npos) const noexcept | |
415 | { | |
416 | return this->find_last_not_of(__str, __pos, | |
417 | traits_type::length(__str)); | |
418 | } | |
419 | ||
420 | private: | |
7f8a3f49 | 421 | |
2fd2d470 | 422 | static constexpr const int |
423 | _S_compare(size_type __n1, size_type __n2) noexcept | |
424 | { | |
425 | return difference_type{__n1 - __n2} > std::numeric_limits<int>::max() | |
426 | ? std::numeric_limits<int>::max() | |
427 | : difference_type{__n1 - __n2} < std::numeric_limits<int>::min() | |
428 | ? std::numeric_limits<int>::min() | |
429 | : static_cast<int>(difference_type{__n1 - __n2}); | |
430 | } | |
431 | ||
432 | size_t _M_len; | |
433 | const _CharT* _M_str; | |
434 | }; | |
435 | ||
436 | ||
437 | // [string.view.comparison], non-member basic_string_view comparison functions | |
438 | ||
439 | namespace __detail | |
440 | { | |
441 | // Identity transform to make ADL work with just one argument. | |
442 | // See n3766.html. | |
443 | template<typename _Tp = void> | |
444 | struct __identity | |
445 | { typedef _Tp type; }; | |
446 | ||
447 | template<> | |
448 | struct __identity<void>; | |
449 | ||
450 | template<typename _Tp> | |
451 | using __idt = typename __identity<_Tp>::type; | |
452 | } | |
453 | ||
454 | template<typename _CharT, typename _Traits> | |
4f3db60b | 455 | inline bool |
2fd2d470 | 456 | operator==(basic_string_view<_CharT, _Traits> __x, |
457 | basic_string_view<_CharT, _Traits> __y) noexcept | |
458 | { return __x.compare(__y) == 0; } | |
459 | ||
460 | template<typename _CharT, typename _Traits> | |
4f3db60b | 461 | inline bool |
2fd2d470 | 462 | operator==(basic_string_view<_CharT, _Traits> __x, |
463 | __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept | |
464 | { return __x.compare(__y) == 0; } | |
465 | ||
466 | template<typename _CharT, typename _Traits> | |
4f3db60b | 467 | inline bool |
2fd2d470 | 468 | operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, |
469 | basic_string_view<_CharT, _Traits> __y) noexcept | |
470 | { return __x.compare(__y) == 0; } | |
471 | ||
472 | template<typename _CharT, typename _Traits> | |
4f3db60b | 473 | inline bool |
2fd2d470 | 474 | operator!=(basic_string_view<_CharT, _Traits> __x, |
475 | basic_string_view<_CharT, _Traits> __y) noexcept | |
476 | { return !(__x == __y); } | |
477 | ||
478 | template<typename _CharT, typename _Traits> | |
4f3db60b | 479 | inline bool |
2fd2d470 | 480 | operator!=(basic_string_view<_CharT, _Traits> __x, |
481 | __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept | |
482 | { return !(__x == __y); } | |
483 | ||
484 | template<typename _CharT, typename _Traits> | |
4f3db60b | 485 | inline bool |
2fd2d470 | 486 | operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, |
487 | basic_string_view<_CharT, _Traits> __y) noexcept | |
488 | { return !(__x == __y); } | |
489 | ||
490 | template<typename _CharT, typename _Traits> | |
4f3db60b | 491 | inline bool |
2fd2d470 | 492 | operator< (basic_string_view<_CharT, _Traits> __x, |
493 | basic_string_view<_CharT, _Traits> __y) noexcept | |
494 | { return __x.compare(__y) < 0; } | |
495 | ||
496 | template<typename _CharT, typename _Traits> | |
4f3db60b | 497 | inline bool |
2fd2d470 | 498 | operator< (basic_string_view<_CharT, _Traits> __x, |
499 | __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept | |
500 | { return __x.compare(__y) < 0; } | |
501 | ||
502 | template<typename _CharT, typename _Traits> | |
4f3db60b | 503 | inline bool |
2fd2d470 | 504 | operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x, |
505 | basic_string_view<_CharT, _Traits> __y) noexcept | |
506 | { return __x.compare(__y) < 0; } | |
507 | ||
508 | template<typename _CharT, typename _Traits> | |
4f3db60b | 509 | inline bool |
2fd2d470 | 510 | operator> (basic_string_view<_CharT, _Traits> __x, |
511 | basic_string_view<_CharT, _Traits> __y) noexcept | |
512 | { return __x.compare(__y) > 0; } | |
513 | ||
514 | template<typename _CharT, typename _Traits> | |
4f3db60b | 515 | inline bool |
2fd2d470 | 516 | operator> (basic_string_view<_CharT, _Traits> __x, |
517 | __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept | |
518 | { return __x.compare(__y) > 0; } | |
519 | ||
520 | template<typename _CharT, typename _Traits> | |
4f3db60b | 521 | inline bool |
2fd2d470 | 522 | operator> (__detail::__idt<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> | |
4f3db60b | 527 | inline bool |
2fd2d470 | 528 | operator<=(basic_string_view<_CharT, _Traits> __x, |
529 | basic_string_view<_CharT, _Traits> __y) noexcept | |
530 | { return __x.compare(__y) <= 0; } | |
531 | ||
532 | template<typename _CharT, typename _Traits> | |
4f3db60b | 533 | inline bool |
2fd2d470 | 534 | operator<=(basic_string_view<_CharT, _Traits> __x, |
535 | __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept | |
536 | { return __x.compare(__y) <= 0; } | |
537 | ||
538 | template<typename _CharT, typename _Traits> | |
4f3db60b | 539 | inline bool |
2fd2d470 | 540 | operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, |
541 | basic_string_view<_CharT, _Traits> __y) noexcept | |
542 | { return __x.compare(__y) <= 0; } | |
543 | ||
544 | template<typename _CharT, typename _Traits> | |
4f3db60b | 545 | inline bool |
2fd2d470 | 546 | operator>=(basic_string_view<_CharT, _Traits> __x, |
547 | basic_string_view<_CharT, _Traits> __y) noexcept | |
548 | { return __x.compare(__y) >= 0; } | |
549 | ||
550 | template<typename _CharT, typename _Traits> | |
4f3db60b | 551 | inline bool |
2fd2d470 | 552 | operator>=(basic_string_view<_CharT, _Traits> __x, |
553 | __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept | |
554 | { return __x.compare(__y) >= 0; } | |
555 | ||
556 | template<typename _CharT, typename _Traits> | |
4f3db60b | 557 | inline bool |
2fd2d470 | 558 | operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, |
559 | basic_string_view<_CharT, _Traits> __y) noexcept | |
560 | { return __x.compare(__y) >= 0; } | |
561 | ||
4f3db60b | 562 | // [string.view.io], Inserters and extractors |
2fd2d470 | 563 | template<typename _CharT, typename _Traits> |
4f3db60b | 564 | inline basic_ostream<_CharT, _Traits>& |
565 | operator<<(basic_ostream<_CharT, _Traits>& __os, | |
566 | basic_string_view<_CharT,_Traits> __str) | |
567 | { return __ostream_insert(__os, __str.data(), __str.size()); } | |
2fd2d470 | 568 | |
569 | ||
570 | // basic_string_view typedef names | |
571 | ||
572 | using string_view = basic_string_view<char>; | |
573 | #ifdef _GLIBCXX_USE_WCHAR_T | |
574 | using wstring_view = basic_string_view<wchar_t>; | |
575 | #endif | |
576 | #ifdef _GLIBCXX_USE_C99_STDINT_TR1 | |
577 | using u16string_view = basic_string_view<char16_t>; | |
578 | using u32string_view = basic_string_view<char32_t>; | |
579 | #endif | |
580 | ||
581 | _GLIBCXX_END_NAMESPACE_VERSION | |
0a394876 | 582 | } // namespace fundamentals_v1 |
2fd2d470 | 583 | } // namespace experimental |
584 | ||
585 | ||
586 | // [string.view.hash], hash support: | |
587 | ||
588 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
589 | template<typename _Tp> | |
590 | struct hash; | |
591 | ||
592 | template<> | |
593 | struct hash<experimental::string_view> | |
594 | : public __hash_base<size_t, experimental::string_view> | |
595 | { | |
596 | size_t | |
597 | operator()(const experimental::string_view& __str) const noexcept | |
598 | { return std::_Hash_impl::hash(__str.data(), __str.length()); } | |
599 | }; | |
600 | ||
601 | template<> | |
602 | struct __is_fast_hash<hash<experimental::string_view>> : std::false_type | |
603 | { }; | |
604 | ||
605 | #ifdef _GLIBCXX_USE_WCHAR_T | |
606 | template<> | |
607 | struct hash<experimental::wstring_view> | |
608 | : public __hash_base<size_t, wstring> | |
609 | { | |
610 | size_t | |
611 | operator()(const experimental::wstring_view& __s) const noexcept | |
612 | { return std::_Hash_impl::hash(__s.data(), | |
613 | __s.length() * sizeof(wchar_t)); } | |
614 | }; | |
615 | ||
616 | template<> | |
617 | struct __is_fast_hash<hash<experimental::wstring_view>> : std::false_type | |
618 | { }; | |
619 | #endif | |
620 | ||
621 | #ifdef _GLIBCXX_USE_C99_STDINT_TR1 | |
622 | template<> | |
623 | struct hash<experimental::u16string_view> | |
624 | : public __hash_base<size_t, experimental::u16string_view> | |
625 | { | |
626 | size_t | |
627 | operator()(const experimental::u16string_view& __s) const noexcept | |
628 | { return std::_Hash_impl::hash(__s.data(), | |
629 | __s.length() * sizeof(char16_t)); } | |
630 | }; | |
631 | ||
632 | template<> | |
633 | struct __is_fast_hash<hash<experimental::u16string_view>> : std::false_type | |
634 | { }; | |
635 | ||
636 | template<> | |
637 | struct hash<experimental::u32string_view> | |
638 | : public __hash_base<size_t, experimental::u32string_view> | |
639 | { | |
640 | size_t | |
641 | operator()(const experimental::u32string_view& __s) const noexcept | |
642 | { return std::_Hash_impl::hash(__s.data(), | |
643 | __s.length() * sizeof(char32_t)); } | |
644 | }; | |
645 | ||
646 | template<> | |
647 | struct __is_fast_hash<hash<experimental::u32string_view>> : std::false_type | |
648 | { }; | |
649 | #endif | |
650 | _GLIBCXX_END_NAMESPACE_VERSION | |
651 | ||
652 | namespace experimental | |
653 | { | |
654 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
655 | ||
656 | // I added these EMSR. | |
657 | inline namespace literals | |
658 | { | |
659 | inline namespace string_view_literals | |
660 | { | |
661 | ||
85ace2a1 | 662 | inline constexpr basic_string_view<char> |
2fd2d470 | 663 | operator""sv(const char* __str, size_t __len) |
664 | { return basic_string_view<char>{__str, __len}; } | |
665 | ||
666 | #ifdef _GLIBCXX_USE_WCHAR_T | |
85ace2a1 | 667 | inline constexpr basic_string_view<wchar_t> |
2fd2d470 | 668 | operator""sv(const wchar_t* __str, size_t __len) |
669 | { return basic_string_view<wchar_t>{__str, __len}; } | |
670 | #endif | |
671 | ||
672 | #ifdef _GLIBCXX_USE_C99_STDINT_TR1 | |
85ace2a1 | 673 | inline constexpr basic_string_view<char16_t> |
2fd2d470 | 674 | operator""sv(const char16_t* __str, size_t __len) |
675 | { return basic_string_view<char16_t>{__str, __len}; } | |
676 | ||
85ace2a1 | 677 | inline constexpr basic_string_view<char32_t> |
2fd2d470 | 678 | operator""sv(const char32_t* __str, size_t __len) |
679 | { return basic_string_view<char32_t>{__str, __len}; } | |
680 | #endif | |
681 | ||
682 | } | |
683 | } | |
684 | ||
685 | _GLIBCXX_END_NAMESPACE_VERSION | |
686 | } // namespace experimental | |
687 | } // namespace std | |
688 | ||
5fd1372f | 689 | #include <experimental/bits/string_view.tcc> |
2fd2d470 | 690 | |
691 | #endif // __cplusplus <= 201103L | |
692 | ||
693 | #endif // _GLIBCXX_EXPERIMENTAL_STRING_VIEW |