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