]>
Commit | Line | Data |
---|---|---|
1 | // Debugging string implementation -*- C++ -*- | |
2 | ||
3 | // Copyright (C) 2003-2025 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 debug/string | |
26 | * This file is a GNU debug extension to the Standard C++ Library. | |
27 | */ | |
28 | ||
29 | #ifndef _GLIBCXX_DEBUG_STRING | |
30 | #define _GLIBCXX_DEBUG_STRING 1 | |
31 | ||
32 | #ifdef _GLIBCXX_SYSHDR | |
33 | #pragma GCC system_header | |
34 | #endif | |
35 | ||
36 | #include <string> | |
37 | #include <debug/safe_sequence.h> | |
38 | #include <debug/safe_container.h> | |
39 | #include <debug/safe_iterator.h> | |
40 | ||
41 | #define _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_Cond,_File,_Line,_Func) \ | |
42 | if (! (_Cond)) \ | |
43 | __gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func) \ | |
44 | ._M_message(#_Cond)._M_error() | |
45 | ||
46 | #if _GLIBCXX_USE_CXX11_ABI && __cplusplus >= 201103 | |
47 | # define _GLIBCXX_INSERT_RETURNS_ITERATOR 1 | |
48 | # define _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(expr) expr | |
49 | #else | |
50 | # define _GLIBCXX_INSERT_RETURNS_ITERATOR 0 | |
51 | # define _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(expr) | |
52 | #endif | |
53 | ||
54 | #ifdef _GLIBCXX_DEBUG_PEDANTIC | |
55 | # if __cplusplus < 201103L | |
56 | # define __glibcxx_check_string(_String) \ | |
57 | _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != 0, \ | |
58 | __FILE__, __LINE__, \ | |
59 | __PRETTY_FUNCTION__); | |
60 | # define __glibcxx_check_string_len(_String,_Len) \ | |
61 | _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != 0 || _Len == 0, \ | |
62 | __FILE__, __LINE__, \ | |
63 | __PRETTY_FUNCTION__); | |
64 | # else | |
65 | # define __glibcxx_check_string(_String) \ | |
66 | _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != nullptr, \ | |
67 | __FILE__, __LINE__, \ | |
68 | __PRETTY_FUNCTION__); | |
69 | # define __glibcxx_check_string_len(_String,_Len) \ | |
70 | _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_String != nullptr || _Len == 0, \ | |
71 | __FILE__, __LINE__, \ | |
72 | __PRETTY_FUNCTION__); | |
73 | # endif | |
74 | #else | |
75 | # define __glibcxx_check_string(_String) | |
76 | # define __glibcxx_check_string_len(_String,_Len) | |
77 | #endif | |
78 | ||
79 | namespace __gnu_debug | |
80 | { | |
81 | /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ | |
82 | template<typename _CharT, typename _Integer> | |
83 | inline const _CharT* | |
84 | __check_string(const _CharT* __s, | |
85 | _Integer __n __attribute__((__unused__)), | |
86 | const char* __file __attribute__((__unused__)), | |
87 | unsigned int __line __attribute__((__unused__)), | |
88 | const char* __function __attribute__((__unused__))) | |
89 | { | |
90 | #ifdef _GLIBCXX_DEBUG_PEDANTIC | |
91 | # if __cplusplus < 201103L | |
92 | _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != 0 || __n == 0, | |
93 | __file, __line, __function); | |
94 | # else | |
95 | _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != nullptr || __n == 0, | |
96 | __file, __line, __function); | |
97 | # endif | |
98 | #endif | |
99 | return __s; | |
100 | } | |
101 | ||
102 | /** Checks that __s is non-NULL and then returns __s. */ | |
103 | template<typename _CharT> | |
104 | inline const _CharT* | |
105 | __check_string(const _CharT* __s, | |
106 | const char* __file __attribute__((__unused__)), | |
107 | unsigned int __line __attribute__((__unused__)), | |
108 | const char* __function __attribute__((__unused__))) | |
109 | { | |
110 | #ifdef _GLIBCXX_DEBUG_PEDANTIC | |
111 | # if __cplusplus < 201103L | |
112 | _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != 0, | |
113 | __file, __line, __function); | |
114 | # else | |
115 | _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != nullptr, | |
116 | __file, __line, __function); | |
117 | # endif | |
118 | #endif | |
119 | return __s; | |
120 | } | |
121 | ||
122 | #define __glibcxx_check_string_n_constructor(_Str, _Size) \ | |
123 | __check_string(_Str, _Size, __FILE__, __LINE__, __PRETTY_FUNCTION__) | |
124 | ||
125 | #define __glibcxx_check_string_constructor(_Str) \ | |
126 | __check_string(_Str, __FILE__, __LINE__, __PRETTY_FUNCTION__) | |
127 | ||
128 | /// Class std::basic_string with safety/checking/debug instrumentation. | |
129 | template<typename _CharT, typename _Traits = std::char_traits<_CharT>, | |
130 | typename _Allocator = std::allocator<_CharT> > | |
131 | class basic_string | |
132 | : public __gnu_debug::_Safe_container< | |
133 | basic_string<_CharT, _Traits, _Allocator>, | |
134 | _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>, | |
135 | public std::basic_string<_CharT, _Traits, _Allocator> | |
136 | { | |
137 | typedef std::basic_string<_CharT, _Traits, _Allocator> _Base; | |
138 | typedef __gnu_debug::_Safe_container< | |
139 | basic_string, _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)> | |
140 | _Safe; | |
141 | ||
142 | template<typename _ItT, typename _SeqT, typename _CatT> | |
143 | friend class ::__gnu_debug::_Safe_iterator; | |
144 | ||
145 | // type used for positions in insert, erase etc. | |
146 | typedef __gnu_debug::_Safe_iterator< | |
147 | typename _Base::__const_iterator, basic_string> __const_iterator; | |
148 | ||
149 | public: | |
150 | // types: | |
151 | typedef _Traits traits_type; | |
152 | typedef typename _Traits::char_type value_type; | |
153 | typedef _Allocator allocator_type; | |
154 | typedef typename _Base::size_type size_type; | |
155 | typedef typename _Base::difference_type difference_type; | |
156 | typedef typename _Base::reference reference; | |
157 | typedef typename _Base::const_reference const_reference; | |
158 | typedef typename _Base::pointer pointer; | |
159 | typedef typename _Base::const_pointer const_pointer; | |
160 | ||
161 | typedef __gnu_debug::_Safe_iterator< | |
162 | typename _Base::iterator, basic_string> iterator; | |
163 | typedef __gnu_debug::_Safe_iterator< | |
164 | typename _Base::const_iterator, basic_string> const_iterator; | |
165 | ||
166 | typedef std::reverse_iterator<iterator> reverse_iterator; | |
167 | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | |
168 | ||
169 | using _Base::npos; | |
170 | ||
171 | // 21.3.1 construct/copy/destroy: | |
172 | ||
173 | explicit | |
174 | basic_string(const _Allocator& __a) _GLIBCXX_NOEXCEPT | |
175 | : _Base(__a) { } | |
176 | ||
177 | #if __cplusplus < 201103L | |
178 | basic_string() : _Base() { } | |
179 | ||
180 | basic_string(const basic_string& __str) | |
181 | : _Base(__str) { } | |
182 | ||
183 | ~basic_string() { } | |
184 | #else | |
185 | basic_string() = default; | |
186 | basic_string(const basic_string&) = default; | |
187 | basic_string(basic_string&&) = default; | |
188 | ||
189 | basic_string(std::initializer_list<_CharT> __l, | |
190 | const _Allocator& __a = _Allocator()) | |
191 | : _Base(__l, __a) | |
192 | { } | |
193 | ||
194 | basic_string(const basic_string& __s, const _Allocator& __a) | |
195 | : _Base(__s, __a) { } | |
196 | ||
197 | basic_string(basic_string&& __s, const _Allocator& __a) | |
198 | noexcept( | |
199 | std::is_nothrow_constructible<_Base, _Base, const _Allocator&>::value ) | |
200 | : _Safe(std::move(__s), __a), | |
201 | _Base(std::move(__s), __a) | |
202 | { } | |
203 | ||
204 | ~basic_string() = default; | |
205 | ||
206 | // Provides conversion from a normal-mode string to a debug-mode string | |
207 | basic_string(_Base&& __base) noexcept | |
208 | : _Base(std::move(__base)) { } | |
209 | #endif // C++11 | |
210 | ||
211 | // Provides conversion from a normal-mode string to a debug-mode string | |
212 | basic_string(const _Base& __base) | |
213 | : _Base(__base) { } | |
214 | ||
215 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
216 | // 42. string ctors specify wrong default allocator | |
217 | basic_string(const basic_string& __str, size_type __pos, | |
218 | size_type __n = _Base::npos, | |
219 | const _Allocator& __a = _Allocator()) | |
220 | : _Base(__str, __pos, __n, __a) { } | |
221 | ||
222 | basic_string(const _CharT* __s, size_type __n, | |
223 | const _Allocator& __a = _Allocator()) | |
224 | : _Base(__glibcxx_check_string_n_constructor(__s, __n), __n, __a) { } | |
225 | ||
226 | basic_string(const _CharT* __s, const _Allocator& __a = _Allocator()) | |
227 | : _Base(__glibcxx_check_string_constructor(__s), __a) | |
228 | { } | |
229 | ||
230 | basic_string(size_type __n, _CharT __c, | |
231 | const _Allocator& __a = _Allocator()) | |
232 | : _Base(__n, __c, __a) { } | |
233 | ||
234 | template<typename _InputIterator> | |
235 | basic_string(_InputIterator __begin, _InputIterator __end, | |
236 | const _Allocator& __a = _Allocator()) | |
237 | : _Base(__gnu_debug::__base( | |
238 | __glibcxx_check_valid_constructor_range(__begin, __end)), | |
239 | __gnu_debug::__base(__end), __a) { } | |
240 | ||
241 | #if __cplusplus >= 201103L | |
242 | basic_string& | |
243 | operator=(const basic_string&) = default; | |
244 | ||
245 | basic_string& | |
246 | operator=(basic_string&&) = default; | |
247 | #endif | |
248 | ||
249 | basic_string& | |
250 | operator=(const _CharT* __s) | |
251 | { | |
252 | __glibcxx_check_string(__s); | |
253 | _Base::operator=(__s); | |
254 | this->_M_invalidate_all(); | |
255 | return *this; | |
256 | } | |
257 | ||
258 | basic_string& | |
259 | operator=(_CharT __c) | |
260 | { | |
261 | _Base::operator=(__c); | |
262 | this->_M_invalidate_all(); | |
263 | return *this; | |
264 | } | |
265 | ||
266 | #if __cplusplus >= 201103L | |
267 | basic_string& | |
268 | operator=(std::initializer_list<_CharT> __l) | |
269 | { | |
270 | _Base::operator=(__l); | |
271 | this->_M_invalidate_all(); | |
272 | return *this; | |
273 | } | |
274 | #endif // C++11 | |
275 | ||
276 | // 21.3.2 iterators: | |
277 | iterator | |
278 | begin() // _GLIBCXX_NOEXCEPT | |
279 | { return iterator(_Base::begin(), this); } | |
280 | ||
281 | const_iterator | |
282 | begin() const _GLIBCXX_NOEXCEPT | |
283 | { return const_iterator(_Base::begin(), this); } | |
284 | ||
285 | iterator | |
286 | end() // _GLIBCXX_NOEXCEPT | |
287 | { return iterator(_Base::end(), this); } | |
288 | ||
289 | const_iterator | |
290 | end() const _GLIBCXX_NOEXCEPT | |
291 | { return const_iterator(_Base::end(), this); } | |
292 | ||
293 | reverse_iterator | |
294 | rbegin() // _GLIBCXX_NOEXCEPT | |
295 | { return reverse_iterator(end()); } | |
296 | ||
297 | const_reverse_iterator | |
298 | rbegin() const _GLIBCXX_NOEXCEPT | |
299 | { return const_reverse_iterator(end()); } | |
300 | ||
301 | reverse_iterator | |
302 | rend() // _GLIBCXX_NOEXCEPT | |
303 | { return reverse_iterator(begin()); } | |
304 | ||
305 | const_reverse_iterator | |
306 | rend() const _GLIBCXX_NOEXCEPT | |
307 | { return const_reverse_iterator(begin()); } | |
308 | ||
309 | #if __cplusplus >= 201103L | |
310 | const_iterator | |
311 | cbegin() const noexcept | |
312 | { return const_iterator(_Base::begin(), this); } | |
313 | ||
314 | const_iterator | |
315 | cend() const noexcept | |
316 | { return const_iterator(_Base::end(), this); } | |
317 | ||
318 | const_reverse_iterator | |
319 | crbegin() const noexcept | |
320 | { return const_reverse_iterator(end()); } | |
321 | ||
322 | const_reverse_iterator | |
323 | crend() const noexcept | |
324 | { return const_reverse_iterator(begin()); } | |
325 | #endif | |
326 | ||
327 | // 21.3.3 capacity: | |
328 | using _Base::size; | |
329 | using _Base::length; | |
330 | using _Base::max_size; | |
331 | ||
332 | void | |
333 | resize(size_type __n, _CharT __c) | |
334 | { | |
335 | _Base::resize(__n, __c); | |
336 | this->_M_invalidate_all(); | |
337 | } | |
338 | ||
339 | void | |
340 | resize(size_type __n) | |
341 | { this->resize(__n, _CharT()); } | |
342 | ||
343 | #if __cplusplus >= 201103L | |
344 | void | |
345 | shrink_to_fit() noexcept | |
346 | { | |
347 | if (capacity() > size()) | |
348 | { | |
349 | __try | |
350 | { | |
351 | reserve(0); | |
352 | this->_M_invalidate_all(); | |
353 | } | |
354 | __catch(...) | |
355 | { } | |
356 | } | |
357 | } | |
358 | #endif | |
359 | ||
360 | using _Base::capacity; | |
361 | using _Base::reserve; | |
362 | ||
363 | void | |
364 | clear() // _GLIBCXX_NOEXCEPT | |
365 | { | |
366 | _Base::clear(); | |
367 | this->_M_invalidate_all(); | |
368 | } | |
369 | ||
370 | using _Base::empty; | |
371 | ||
372 | // 21.3.4 element access: | |
373 | const_reference | |
374 | operator[](size_type __pos) const _GLIBCXX_NOEXCEPT | |
375 | { | |
376 | _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(), | |
377 | _M_message(__gnu_debug::__msg_subscript_oob) | |
378 | ._M_sequence(*this, "this") | |
379 | ._M_integer(__pos, "__pos") | |
380 | ._M_integer(this->size(), "size")); | |
381 | return _Base::operator[](__pos); | |
382 | } | |
383 | ||
384 | reference | |
385 | operator[](size_type __pos) // _GLIBCXX_NOEXCEPT | |
386 | { | |
387 | #if __cplusplus < 201103L && defined(_GLIBCXX_DEBUG_PEDANTIC) | |
388 | __glibcxx_check_subscript(__pos); | |
389 | #else | |
390 | // as an extension v3 allows s[s.size()] when s is non-const. | |
391 | _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(), | |
392 | _M_message(__gnu_debug::__msg_subscript_oob) | |
393 | ._M_sequence(*this, "this") | |
394 | ._M_integer(__pos, "__pos") | |
395 | ._M_integer(this->size(), "size")); | |
396 | #endif | |
397 | return _Base::operator[](__pos); | |
398 | } | |
399 | ||
400 | using _Base::at; | |
401 | ||
402 | #if __cplusplus >= 201103L | |
403 | using _Base::front; | |
404 | using _Base::back; | |
405 | #endif | |
406 | ||
407 | // 21.3.5 modifiers: | |
408 | basic_string& | |
409 | operator+=(const basic_string& __str) | |
410 | { | |
411 | _Base::operator+=(__str); | |
412 | this->_M_invalidate_all(); | |
413 | return *this; | |
414 | } | |
415 | ||
416 | basic_string& | |
417 | operator+=(const _CharT* __s) | |
418 | { | |
419 | __glibcxx_check_string(__s); | |
420 | _Base::operator+=(__s); | |
421 | this->_M_invalidate_all(); | |
422 | return *this; | |
423 | } | |
424 | ||
425 | basic_string& | |
426 | operator+=(_CharT __c) | |
427 | { | |
428 | _Base::operator+=(__c); | |
429 | this->_M_invalidate_all(); | |
430 | return *this; | |
431 | } | |
432 | ||
433 | #if __cplusplus >= 201103L | |
434 | basic_string& | |
435 | operator+=(std::initializer_list<_CharT> __l) | |
436 | { | |
437 | _Base::operator+=(__l); | |
438 | this->_M_invalidate_all(); | |
439 | return *this; | |
440 | } | |
441 | #endif // C++11 | |
442 | ||
443 | basic_string& | |
444 | append(const basic_string& __str) | |
445 | { | |
446 | _Base::append(__str); | |
447 | this->_M_invalidate_all(); | |
448 | return *this; | |
449 | } | |
450 | ||
451 | basic_string& | |
452 | append(const basic_string& __str, size_type __pos, size_type __n) | |
453 | { | |
454 | _Base::append(__str, __pos, __n); | |
455 | this->_M_invalidate_all(); | |
456 | return *this; | |
457 | } | |
458 | ||
459 | basic_string& | |
460 | append(const _CharT* __s, size_type __n) | |
461 | { | |
462 | __glibcxx_check_string_len(__s, __n); | |
463 | _Base::append(__s, __n); | |
464 | this->_M_invalidate_all(); | |
465 | return *this; | |
466 | } | |
467 | ||
468 | basic_string& | |
469 | append(const _CharT* __s) | |
470 | { | |
471 | __glibcxx_check_string(__s); | |
472 | _Base::append(__s); | |
473 | this->_M_invalidate_all(); | |
474 | return *this; | |
475 | } | |
476 | ||
477 | basic_string& | |
478 | append(size_type __n, _CharT __c) | |
479 | { | |
480 | _Base::append(__n, __c); | |
481 | this->_M_invalidate_all(); | |
482 | return *this; | |
483 | } | |
484 | ||
485 | template<typename _InputIterator> | |
486 | basic_string& | |
487 | append(_InputIterator __first, _InputIterator __last) | |
488 | { | |
489 | typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; | |
490 | __glibcxx_check_valid_range2(__first, __last, __dist); | |
491 | ||
492 | if (__dist.second >= __dp_sign) | |
493 | _Base::append(__gnu_debug::__unsafe(__first), | |
494 | __gnu_debug::__unsafe(__last)); | |
495 | else | |
496 | _Base::append(__first, __last); | |
497 | ||
498 | this->_M_invalidate_all(); | |
499 | return *this; | |
500 | } | |
501 | ||
502 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
503 | // 7. string clause minor problems | |
504 | void | |
505 | push_back(_CharT __c) | |
506 | { | |
507 | _Base::push_back(__c); | |
508 | this->_M_invalidate_all(); | |
509 | } | |
510 | ||
511 | basic_string& | |
512 | assign(const basic_string& __x) | |
513 | { | |
514 | _Base::assign(__x); | |
515 | this->_M_invalidate_all(); | |
516 | return *this; | |
517 | } | |
518 | ||
519 | #if __cplusplus >= 201103L | |
520 | basic_string& | |
521 | assign(basic_string&& __x) | |
522 | noexcept(noexcept(std::declval<_Base&>().assign(std::move(__x)))) | |
523 | { | |
524 | _Base::assign(std::move(__x)); | |
525 | this->_M_invalidate_all(); | |
526 | return *this; | |
527 | } | |
528 | #endif // C++11 | |
529 | ||
530 | basic_string& | |
531 | assign(const basic_string& __str, size_type __pos, size_type __n) | |
532 | { | |
533 | _Base::assign(__str, __pos, __n); | |
534 | this->_M_invalidate_all(); | |
535 | return *this; | |
536 | } | |
537 | ||
538 | basic_string& | |
539 | assign(const _CharT* __s, size_type __n) | |
540 | { | |
541 | __glibcxx_check_string_len(__s, __n); | |
542 | _Base::assign(__s, __n); | |
543 | this->_M_invalidate_all(); | |
544 | return *this; | |
545 | } | |
546 | ||
547 | basic_string& | |
548 | assign(const _CharT* __s) | |
549 | { | |
550 | __glibcxx_check_string(__s); | |
551 | _Base::assign(__s); | |
552 | this->_M_invalidate_all(); | |
553 | return *this; | |
554 | } | |
555 | ||
556 | basic_string& | |
557 | assign(size_type __n, _CharT __c) | |
558 | { | |
559 | _Base::assign(__n, __c); | |
560 | this->_M_invalidate_all(); | |
561 | return *this; | |
562 | } | |
563 | ||
564 | template<typename _InputIterator> | |
565 | basic_string& | |
566 | assign(_InputIterator __first, _InputIterator __last) | |
567 | { | |
568 | typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; | |
569 | __glibcxx_check_valid_range2(__first, __last, __dist); | |
570 | ||
571 | if (__dist.second >= __dp_sign) | |
572 | _Base::assign(__gnu_debug::__unsafe(__first), | |
573 | __gnu_debug::__unsafe(__last)); | |
574 | else | |
575 | _Base::assign(__first, __last); | |
576 | ||
577 | this->_M_invalidate_all(); | |
578 | return *this; | |
579 | } | |
580 | ||
581 | #if __cplusplus >= 201103L | |
582 | basic_string& | |
583 | assign(std::initializer_list<_CharT> __l) | |
584 | { | |
585 | _Base::assign(__l); | |
586 | this->_M_invalidate_all(); | |
587 | return *this; | |
588 | } | |
589 | #endif // C++11 | |
590 | ||
591 | basic_string& | |
592 | insert(size_type __pos1, const basic_string& __str) | |
593 | { | |
594 | _Base::insert(__pos1, __str); | |
595 | this->_M_invalidate_all(); | |
596 | return *this; | |
597 | } | |
598 | ||
599 | basic_string& | |
600 | insert(size_type __pos1, const basic_string& __str, | |
601 | size_type __pos2, size_type __n) | |
602 | { | |
603 | _Base::insert(__pos1, __str, __pos2, __n); | |
604 | this->_M_invalidate_all(); | |
605 | return *this; | |
606 | } | |
607 | ||
608 | basic_string& | |
609 | insert(size_type __pos, const _CharT* __s, size_type __n) | |
610 | { | |
611 | __glibcxx_check_string(__s); | |
612 | _Base::insert(__pos, __s, __n); | |
613 | this->_M_invalidate_all(); | |
614 | return *this; | |
615 | } | |
616 | ||
617 | basic_string& | |
618 | insert(size_type __pos, const _CharT* __s) | |
619 | { | |
620 | __glibcxx_check_string(__s); | |
621 | _Base::insert(__pos, __s); | |
622 | this->_M_invalidate_all(); | |
623 | return *this; | |
624 | } | |
625 | ||
626 | basic_string& | |
627 | insert(size_type __pos, size_type __n, _CharT __c) | |
628 | { | |
629 | _Base::insert(__pos, __n, __c); | |
630 | this->_M_invalidate_all(); | |
631 | return *this; | |
632 | } | |
633 | ||
634 | iterator | |
635 | insert(__const_iterator __p, _CharT __c) | |
636 | { | |
637 | __glibcxx_check_insert(__p); | |
638 | typename _Base::iterator __res = _Base::insert(__p.base(), __c); | |
639 | this->_M_invalidate_all(); | |
640 | return iterator(__res, this); | |
641 | } | |
642 | ||
643 | #if __cplusplus >= 201103L | |
644 | iterator | |
645 | insert(const_iterator __p, size_type __n, _CharT __c) | |
646 | { | |
647 | __glibcxx_check_insert(__p); | |
648 | #if _GLIBCXX_USE_CXX11_ABI | |
649 | typename _Base::iterator __res = _Base::insert(__p.base(), __n, __c); | |
650 | #else | |
651 | const size_type __offset = __p.base() - _Base::cbegin(); | |
652 | _Base::insert(_Base::begin() + __offset, __n, __c); | |
653 | typename _Base::iterator __res = _Base::begin() + __offset; | |
654 | #endif | |
655 | this->_M_invalidate_all(); | |
656 | return iterator(__res, this); | |
657 | } | |
658 | #else | |
659 | void | |
660 | insert(iterator __p, size_type __n, _CharT __c) | |
661 | { | |
662 | __glibcxx_check_insert(__p); | |
663 | _Base::insert(__p.base(), __n, __c); | |
664 | this->_M_invalidate_all(); | |
665 | } | |
666 | #endif | |
667 | ||
668 | template<typename _InputIterator> | |
669 | iterator | |
670 | insert(__const_iterator __p, | |
671 | _InputIterator __first, _InputIterator __last) | |
672 | { | |
673 | typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; | |
674 | __glibcxx_check_insert_range(__p, __first, __last, __dist); | |
675 | ||
676 | typename _Base::iterator __res; | |
677 | #if ! _GLIBCXX_INSERT_RETURNS_ITERATOR | |
678 | const size_type __offset = __p.base() - _Base::begin(); | |
679 | #endif | |
680 | if (__dist.second >= __dp_sign) | |
681 | { | |
682 | _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(__res =) | |
683 | _Base::insert(__p.base(), __gnu_debug::__unsafe(__first), | |
684 | __gnu_debug::__unsafe(__last)); | |
685 | } | |
686 | else | |
687 | { | |
688 | _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(__res =) | |
689 | _Base::insert(__p.base(), __first, __last); | |
690 | } | |
691 | ||
692 | #if ! _GLIBCXX_INSERT_RETURNS_ITERATOR | |
693 | __res = _Base::begin() + __offset; | |
694 | #endif | |
695 | this->_M_invalidate_all(); | |
696 | return iterator(__res, this); | |
697 | } | |
698 | ||
699 | #if __cplusplus >= 201103L | |
700 | iterator | |
701 | insert(const_iterator __p, std::initializer_list<_CharT> __l) | |
702 | { | |
703 | __glibcxx_check_insert(__p); | |
704 | #if _GLIBCXX_USE_CXX11_ABI | |
705 | const auto __res = _Base::insert(__p.base(), __l); | |
706 | #else | |
707 | const size_type __offset = __p.base() - _Base::cbegin(); | |
708 | _Base::insert(_Base::begin() + __offset, __l); | |
709 | auto __res = _Base::begin() + __offset; | |
710 | #endif | |
711 | this->_M_invalidate_all(); | |
712 | return iterator(__res, this); | |
713 | } | |
714 | #endif // C++11 | |
715 | ||
716 | basic_string& | |
717 | erase(size_type __pos = 0, size_type __n = _Base::npos) | |
718 | { | |
719 | _Base::erase(__pos, __n); | |
720 | this->_M_invalidate_all(); | |
721 | return *this; | |
722 | } | |
723 | ||
724 | iterator | |
725 | erase(__const_iterator __position) | |
726 | { | |
727 | __glibcxx_check_erase(__position); | |
728 | typename _Base::iterator __res = _Base::erase(__position.base()); | |
729 | this->_M_invalidate_all(); | |
730 | return iterator(__res, this); | |
731 | } | |
732 | ||
733 | iterator | |
734 | erase(__const_iterator __first, __const_iterator __last) | |
735 | { | |
736 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
737 | // 151. can't currently clear() empty container | |
738 | __glibcxx_check_erase_range(__first, __last); | |
739 | typename _Base::iterator __res = _Base::erase(__first.base(), | |
740 | __last.base()); | |
741 | this->_M_invalidate_all(); | |
742 | return iterator(__res, this); | |
743 | } | |
744 | ||
745 | #if __cplusplus >= 201103L | |
746 | void | |
747 | pop_back() // noexcept | |
748 | { | |
749 | __glibcxx_check_nonempty(); | |
750 | _Base::pop_back(); | |
751 | this->_M_invalidate_all(); | |
752 | } | |
753 | #endif // C++11 | |
754 | ||
755 | basic_string& | |
756 | replace(size_type __pos1, size_type __n1, const basic_string& __str) | |
757 | { | |
758 | _Base::replace(__pos1, __n1, __str); | |
759 | this->_M_invalidate_all(); | |
760 | return *this; | |
761 | } | |
762 | ||
763 | basic_string& | |
764 | replace(size_type __pos1, size_type __n1, const basic_string& __str, | |
765 | size_type __pos2, size_type __n2) | |
766 | { | |
767 | _Base::replace(__pos1, __n1, __str, __pos2, __n2); | |
768 | this->_M_invalidate_all(); | |
769 | return *this; | |
770 | } | |
771 | ||
772 | basic_string& | |
773 | replace(size_type __pos, size_type __n1, const _CharT* __s, | |
774 | size_type __n2) | |
775 | { | |
776 | __glibcxx_check_string_len(__s, __n2); | |
777 | _Base::replace(__pos, __n1, __s, __n2); | |
778 | this->_M_invalidate_all(); | |
779 | return *this; | |
780 | } | |
781 | ||
782 | basic_string& | |
783 | replace(size_type __pos, size_type __n1, const _CharT* __s) | |
784 | { | |
785 | __glibcxx_check_string(__s); | |
786 | _Base::replace(__pos, __n1, __s); | |
787 | this->_M_invalidate_all(); | |
788 | return *this; | |
789 | } | |
790 | ||
791 | basic_string& | |
792 | replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) | |
793 | { | |
794 | _Base::replace(__pos, __n1, __n2, __c); | |
795 | this->_M_invalidate_all(); | |
796 | return *this; | |
797 | } | |
798 | ||
799 | basic_string& | |
800 | replace(__const_iterator __i1, __const_iterator __i2, | |
801 | const basic_string& __str) | |
802 | { | |
803 | __glibcxx_check_erase_range(__i1, __i2); | |
804 | _Base::replace(__i1.base(), __i2.base(), __str); | |
805 | this->_M_invalidate_all(); | |
806 | return *this; | |
807 | } | |
808 | ||
809 | basic_string& | |
810 | replace(__const_iterator __i1, __const_iterator __i2, | |
811 | const _CharT* __s, size_type __n) | |
812 | { | |
813 | __glibcxx_check_erase_range(__i1, __i2); | |
814 | __glibcxx_check_string_len(__s, __n); | |
815 | _Base::replace(__i1.base(), __i2.base(), __s, __n); | |
816 | this->_M_invalidate_all(); | |
817 | return *this; | |
818 | } | |
819 | ||
820 | basic_string& | |
821 | replace(__const_iterator __i1, __const_iterator __i2, | |
822 | const _CharT* __s) | |
823 | { | |
824 | __glibcxx_check_erase_range(__i1, __i2); | |
825 | __glibcxx_check_string(__s); | |
826 | _Base::replace(__i1.base(), __i2.base(), __s); | |
827 | this->_M_invalidate_all(); | |
828 | return *this; | |
829 | } | |
830 | ||
831 | basic_string& | |
832 | replace(__const_iterator __i1, __const_iterator __i2, | |
833 | size_type __n, _CharT __c) | |
834 | { | |
835 | __glibcxx_check_erase_range(__i1, __i2); | |
836 | _Base::replace(__i1.base(), __i2.base(), __n, __c); | |
837 | this->_M_invalidate_all(); | |
838 | return *this; | |
839 | } | |
840 | ||
841 | template<typename _InputIterator> | |
842 | basic_string& | |
843 | replace(__const_iterator __i1, __const_iterator __i2, | |
844 | _InputIterator __j1, _InputIterator __j2) | |
845 | { | |
846 | __glibcxx_check_erase_range(__i1, __i2); | |
847 | ||
848 | typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; | |
849 | __glibcxx_check_valid_range2(__j1, __j2, __dist); | |
850 | ||
851 | if (__dist.second >= __dp_sign) | |
852 | _Base::replace(__i1.base(), __i2.base(), | |
853 | __gnu_debug::__unsafe(__j1), | |
854 | __gnu_debug::__unsafe(__j2)); | |
855 | else | |
856 | _Base::replace(__i1.base(), __i2.base(), __j1, __j2); | |
857 | ||
858 | this->_M_invalidate_all(); | |
859 | return *this; | |
860 | } | |
861 | ||
862 | #if __cplusplus >= 201103L | |
863 | basic_string& | |
864 | replace(__const_iterator __i1, __const_iterator __i2, | |
865 | std::initializer_list<_CharT> __l) | |
866 | { | |
867 | __glibcxx_check_erase_range(__i1, __i2); | |
868 | _Base::replace(__i1.base(), __i2.base(), __l); | |
869 | this->_M_invalidate_all(); | |
870 | return *this; | |
871 | } | |
872 | #endif // C++11 | |
873 | ||
874 | size_type | |
875 | copy(_CharT* __s, size_type __n, size_type __pos = 0) const | |
876 | { | |
877 | __glibcxx_check_string_len(__s, __n); | |
878 | return _Base::copy(__s, __n, __pos); | |
879 | } | |
880 | ||
881 | void | |
882 | swap(basic_string& __x) | |
883 | _GLIBCXX_NOEXCEPT_IF(std::__is_nothrow_swappable<_Base>::value) | |
884 | { | |
885 | _Safe::_M_swap(__x); | |
886 | _Base::swap(__x); | |
887 | } | |
888 | ||
889 | // 21.3.6 string operations: | |
890 | const _CharT* | |
891 | c_str() const _GLIBCXX_NOEXCEPT | |
892 | { | |
893 | const _CharT* __res = _Base::c_str(); | |
894 | this->_M_invalidate_all(); | |
895 | return __res; | |
896 | } | |
897 | ||
898 | const _CharT* | |
899 | data() const _GLIBCXX_NOEXCEPT | |
900 | { | |
901 | const _CharT* __res = _Base::data(); | |
902 | this->_M_invalidate_all(); | |
903 | return __res; | |
904 | } | |
905 | ||
906 | using _Base::get_allocator; | |
907 | ||
908 | using _Base::find; | |
909 | ||
910 | _GLIBCXX20_CONSTEXPR | |
911 | size_type | |
912 | find(const _CharT* __s, size_type __pos, size_type __n) const | |
913 | _GLIBCXX_NOEXCEPT | |
914 | { | |
915 | __glibcxx_check_string(__s); | |
916 | return _Base::find(__s, __pos, __n); | |
917 | } | |
918 | ||
919 | _GLIBCXX20_CONSTEXPR | |
920 | size_type | |
921 | find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT | |
922 | { | |
923 | __glibcxx_check_string(__s); | |
924 | return _Base::find(__s, __pos); | |
925 | } | |
926 | ||
927 | using _Base::rfind; | |
928 | ||
929 | _GLIBCXX20_CONSTEXPR | |
930 | size_type | |
931 | rfind(const _CharT* __s, size_type __pos, size_type __n) const | |
932 | { | |
933 | __glibcxx_check_string_len(__s, __n); | |
934 | return _Base::rfind(__s, __pos, __n); | |
935 | } | |
936 | ||
937 | _GLIBCXX20_CONSTEXPR | |
938 | size_type | |
939 | rfind(const _CharT* __s, size_type __pos = _Base::npos) const | |
940 | { | |
941 | __glibcxx_check_string(__s); | |
942 | return _Base::rfind(__s, __pos); | |
943 | } | |
944 | ||
945 | using _Base::find_first_of; | |
946 | ||
947 | _GLIBCXX20_CONSTEXPR | |
948 | size_type | |
949 | find_first_of(const _CharT* __s, size_type __pos, size_type __n) const | |
950 | _GLIBCXX_NOEXCEPT | |
951 | { | |
952 | __glibcxx_check_string(__s); | |
953 | return _Base::find_first_of(__s, __pos, __n); | |
954 | } | |
955 | ||
956 | _GLIBCXX20_CONSTEXPR | |
957 | size_type | |
958 | find_first_of(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT | |
959 | { | |
960 | __glibcxx_check_string(__s); | |
961 | return _Base::find_first_of(__s, __pos); | |
962 | } | |
963 | ||
964 | using _Base::find_last_of; | |
965 | ||
966 | _GLIBCXX20_CONSTEXPR | |
967 | size_type | |
968 | find_last_of(const _CharT* __s, size_type __pos, size_type __n) const | |
969 | _GLIBCXX_NOEXCEPT | |
970 | { | |
971 | __glibcxx_check_string(__s); | |
972 | return _Base::find_last_of(__s, __pos, __n); | |
973 | } | |
974 | ||
975 | _GLIBCXX20_CONSTEXPR | |
976 | size_type | |
977 | find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const | |
978 | _GLIBCXX_NOEXCEPT | |
979 | { | |
980 | __glibcxx_check_string(__s); | |
981 | return _Base::find_last_of(__s, __pos); | |
982 | } | |
983 | ||
984 | using _Base::find_first_not_of; | |
985 | ||
986 | _GLIBCXX20_CONSTEXPR | |
987 | size_type | |
988 | find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const | |
989 | _GLIBCXX_NOEXCEPT | |
990 | { | |
991 | __glibcxx_check_string_len(__s, __n); | |
992 | return _Base::find_first_not_of(__s, __pos, __n); | |
993 | } | |
994 | ||
995 | _GLIBCXX20_CONSTEXPR | |
996 | size_type | |
997 | find_first_not_of(const _CharT* __s, size_type __pos = 0) const | |
998 | _GLIBCXX_NOEXCEPT | |
999 | { | |
1000 | __glibcxx_check_string(__s); | |
1001 | return _Base::find_first_not_of(__s, __pos); | |
1002 | } | |
1003 | ||
1004 | using _Base::find_last_not_of; | |
1005 | ||
1006 | _GLIBCXX20_CONSTEXPR | |
1007 | size_type | |
1008 | find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const | |
1009 | _GLIBCXX_NOEXCEPT | |
1010 | { | |
1011 | __glibcxx_check_string(__s); | |
1012 | return _Base::find_last_not_of(__s, __pos, __n); | |
1013 | } | |
1014 | ||
1015 | _GLIBCXX20_CONSTEXPR | |
1016 | size_type | |
1017 | find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const | |
1018 | _GLIBCXX_NOEXCEPT | |
1019 | { | |
1020 | __glibcxx_check_string(__s); | |
1021 | return _Base::find_last_not_of(__s, __pos); | |
1022 | } | |
1023 | ||
1024 | basic_string | |
1025 | substr(size_type __pos = 0, size_type __n = _Base::npos) const | |
1026 | { return basic_string(_Base::substr(__pos, __n)); } | |
1027 | ||
1028 | using _Base::compare; | |
1029 | ||
1030 | _GLIBCXX20_CONSTEXPR | |
1031 | int | |
1032 | compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT | |
1033 | { | |
1034 | __glibcxx_check_string(__s); | |
1035 | return _Base::compare(__s); | |
1036 | } | |
1037 | ||
1038 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
1039 | // 5. string::compare specification questionable | |
1040 | _GLIBCXX20_CONSTEXPR | |
1041 | int | |
1042 | compare(size_type __pos1, size_type __n1, const _CharT* __s) const | |
1043 | { | |
1044 | __glibcxx_check_string(__s); | |
1045 | return _Base::compare(__pos1, __n1, __s); | |
1046 | } | |
1047 | ||
1048 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
1049 | // 5. string::compare specification questionable | |
1050 | _GLIBCXX20_CONSTEXPR | |
1051 | int | |
1052 | compare(size_type __pos1, size_type __n1,const _CharT* __s, | |
1053 | size_type __n2) const | |
1054 | { | |
1055 | __glibcxx_check_string_len(__s, __n2); | |
1056 | return _Base::compare(__pos1, __n1, __s, __n2); | |
1057 | } | |
1058 | ||
1059 | _Base& | |
1060 | _M_base() _GLIBCXX_NOEXCEPT { return *this; } | |
1061 | ||
1062 | const _Base& | |
1063 | _M_base() const _GLIBCXX_NOEXCEPT { return *this; } | |
1064 | ||
1065 | using _Safe::_M_invalidate_all; | |
1066 | }; | |
1067 | ||
1068 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1069 | inline basic_string<_CharT,_Traits,_Allocator> | |
1070 | operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1071 | const basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1072 | { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } | |
1073 | ||
1074 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1075 | inline basic_string<_CharT,_Traits,_Allocator> | |
1076 | operator+(const _CharT* __lhs, | |
1077 | const basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1078 | { | |
1079 | __glibcxx_check_string(__lhs); | |
1080 | return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; | |
1081 | } | |
1082 | ||
1083 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1084 | inline basic_string<_CharT,_Traits,_Allocator> | |
1085 | operator+(_CharT __lhs, | |
1086 | const basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1087 | { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; } | |
1088 | ||
1089 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1090 | inline basic_string<_CharT,_Traits,_Allocator> | |
1091 | operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1092 | const _CharT* __rhs) | |
1093 | { | |
1094 | __glibcxx_check_string(__rhs); | |
1095 | return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; | |
1096 | } | |
1097 | ||
1098 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1099 | inline basic_string<_CharT,_Traits,_Allocator> | |
1100 | operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1101 | _CharT __rhs) | |
1102 | { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; } | |
1103 | ||
1104 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1105 | inline bool | |
1106 | operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1107 | const basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1108 | { return __lhs._M_base() == __rhs._M_base(); } | |
1109 | ||
1110 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1111 | inline bool | |
1112 | operator==(const _CharT* __lhs, | |
1113 | const basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1114 | { | |
1115 | __glibcxx_check_string(__lhs); | |
1116 | return __lhs == __rhs._M_base(); | |
1117 | } | |
1118 | ||
1119 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1120 | inline bool | |
1121 | operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1122 | const _CharT* __rhs) | |
1123 | { | |
1124 | __glibcxx_check_string(__rhs); | |
1125 | return __lhs._M_base() == __rhs; | |
1126 | } | |
1127 | ||
1128 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1129 | inline bool | |
1130 | operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1131 | const basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1132 | { return __lhs._M_base() != __rhs._M_base(); } | |
1133 | ||
1134 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1135 | inline bool | |
1136 | operator!=(const _CharT* __lhs, | |
1137 | const basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1138 | { | |
1139 | __glibcxx_check_string(__lhs); | |
1140 | return __lhs != __rhs._M_base(); | |
1141 | } | |
1142 | ||
1143 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1144 | inline bool | |
1145 | operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1146 | const _CharT* __rhs) | |
1147 | { | |
1148 | __glibcxx_check_string(__rhs); | |
1149 | return __lhs._M_base() != __rhs; | |
1150 | } | |
1151 | ||
1152 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1153 | inline bool | |
1154 | operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1155 | const basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1156 | { return __lhs._M_base() < __rhs._M_base(); } | |
1157 | ||
1158 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1159 | inline bool | |
1160 | operator<(const _CharT* __lhs, | |
1161 | const basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1162 | { | |
1163 | __glibcxx_check_string(__lhs); | |
1164 | return __lhs < __rhs._M_base(); | |
1165 | } | |
1166 | ||
1167 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1168 | inline bool | |
1169 | operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1170 | const _CharT* __rhs) | |
1171 | { | |
1172 | __glibcxx_check_string(__rhs); | |
1173 | return __lhs._M_base() < __rhs; | |
1174 | } | |
1175 | ||
1176 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1177 | inline bool | |
1178 | operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1179 | const basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1180 | { return __lhs._M_base() <= __rhs._M_base(); } | |
1181 | ||
1182 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1183 | inline bool | |
1184 | operator<=(const _CharT* __lhs, | |
1185 | const basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1186 | { | |
1187 | __glibcxx_check_string(__lhs); | |
1188 | return __lhs <= __rhs._M_base(); | |
1189 | } | |
1190 | ||
1191 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1192 | inline bool | |
1193 | operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1194 | const _CharT* __rhs) | |
1195 | { | |
1196 | __glibcxx_check_string(__rhs); | |
1197 | return __lhs._M_base() <= __rhs; | |
1198 | } | |
1199 | ||
1200 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1201 | inline bool | |
1202 | operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1203 | const basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1204 | { return __lhs._M_base() >= __rhs._M_base(); } | |
1205 | ||
1206 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1207 | inline bool | |
1208 | operator>=(const _CharT* __lhs, | |
1209 | const basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1210 | { | |
1211 | __glibcxx_check_string(__lhs); | |
1212 | return __lhs >= __rhs._M_base(); | |
1213 | } | |
1214 | ||
1215 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1216 | inline bool | |
1217 | operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1218 | const _CharT* __rhs) | |
1219 | { | |
1220 | __glibcxx_check_string(__rhs); | |
1221 | return __lhs._M_base() >= __rhs; | |
1222 | } | |
1223 | ||
1224 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1225 | inline bool | |
1226 | operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1227 | const basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1228 | { return __lhs._M_base() > __rhs._M_base(); } | |
1229 | ||
1230 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1231 | inline bool | |
1232 | operator>(const _CharT* __lhs, | |
1233 | const basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1234 | { | |
1235 | __glibcxx_check_string(__lhs); | |
1236 | return __lhs > __rhs._M_base(); | |
1237 | } | |
1238 | ||
1239 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1240 | inline bool | |
1241 | operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1242 | const _CharT* __rhs) | |
1243 | { | |
1244 | __glibcxx_check_string(__rhs); | |
1245 | return __lhs._M_base() > __rhs; | |
1246 | } | |
1247 | ||
1248 | // 21.3.7.8: | |
1249 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1250 | inline void | |
1251 | swap(basic_string<_CharT,_Traits,_Allocator>& __lhs, | |
1252 | basic_string<_CharT,_Traits,_Allocator>& __rhs) | |
1253 | { __lhs.swap(__rhs); } | |
1254 | ||
1255 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1256 | std::basic_ostream<_CharT, _Traits>& | |
1257 | operator<<(std::basic_ostream<_CharT, _Traits>& __os, | |
1258 | const basic_string<_CharT, _Traits, _Allocator>& __str) | |
1259 | { return __os << __str._M_base(); } | |
1260 | ||
1261 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1262 | std::basic_istream<_CharT,_Traits>& | |
1263 | operator>>(std::basic_istream<_CharT,_Traits>& __is, | |
1264 | basic_string<_CharT,_Traits,_Allocator>& __str) | |
1265 | { | |
1266 | std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base(); | |
1267 | __str._M_invalidate_all(); | |
1268 | return __res; | |
1269 | } | |
1270 | ||
1271 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1272 | std::basic_istream<_CharT,_Traits>& | |
1273 | getline(std::basic_istream<_CharT,_Traits>& __is, | |
1274 | basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim) | |
1275 | { | |
1276 | std::basic_istream<_CharT,_Traits>& __res = getline(__is, | |
1277 | __str._M_base(), | |
1278 | __delim); | |
1279 | __str._M_invalidate_all(); | |
1280 | return __res; | |
1281 | } | |
1282 | ||
1283 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1284 | std::basic_istream<_CharT,_Traits>& | |
1285 | getline(std::basic_istream<_CharT,_Traits>& __is, | |
1286 | basic_string<_CharT,_Traits,_Allocator>& __str) | |
1287 | { | |
1288 | std::basic_istream<_CharT,_Traits>& __res = getline(__is, | |
1289 | __str._M_base()); | |
1290 | __str._M_invalidate_all(); | |
1291 | return __res; | |
1292 | } | |
1293 | ||
1294 | typedef basic_string<char> string; | |
1295 | ||
1296 | typedef basic_string<wchar_t> wstring; | |
1297 | ||
1298 | #ifdef _GLIBCXX_USE_CHAR8_T | |
1299 | /// A string of @c char8_t | |
1300 | typedef basic_string<char8_t> u8string; | |
1301 | #endif | |
1302 | ||
1303 | #if __cplusplus >= 201103L | |
1304 | /// A string of @c char16_t | |
1305 | typedef basic_string<char16_t> u16string; | |
1306 | ||
1307 | /// A string of @c char32_t | |
1308 | typedef basic_string<char32_t> u32string; | |
1309 | #endif | |
1310 | ||
1311 | template<typename _CharT, typename _Traits, typename _Allocator> | |
1312 | struct _Insert_range_from_self_is_safe< | |
1313 | __gnu_debug::basic_string<_CharT, _Traits, _Allocator> > | |
1314 | { enum { __value = 1 }; }; | |
1315 | ||
1316 | } // namespace __gnu_debug | |
1317 | ||
1318 | #if __cplusplus >= 201103L | |
1319 | namespace std _GLIBCXX_VISIBILITY(default) | |
1320 | { | |
1321 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
1322 | ||
1323 | /// std::hash specialization for __gnu_debug::basic_string. | |
1324 | template<typename _CharT> | |
1325 | struct hash<__gnu_debug::basic_string<_CharT>> | |
1326 | : public hash<std::basic_string<_CharT>> | |
1327 | { }; | |
1328 | ||
1329 | template<typename _CharT> | |
1330 | struct __is_fast_hash<hash<__gnu_debug::basic_string<_CharT>>> | |
1331 | : __is_fast_hash<hash<std::basic_string<_CharT>>> | |
1332 | { }; | |
1333 | ||
1334 | _GLIBCXX_END_NAMESPACE_VERSION | |
1335 | } | |
1336 | #endif /* C++11 */ | |
1337 | ||
1338 | #undef _GLIBCXX_INSERT_RETURNS_ITERATOR | |
1339 | #undef _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY | |
1340 | ||
1341 | #endif |