libstdc++
debug/string
Go to the documentation of this file.
1// Debugging string implementation -*- C++ -*-
2
3// Copyright (C) 2003-2026 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>
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
79namespace __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
133 basic_string<_CharT, _Traits, _Allocator>,
134 _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>,
135 public std::basic_string<_CharT, _Traits, _Allocator>
136 {
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.
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
162 typename _Base::iterator, basic_string> 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
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(
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#if __cplusplus >= 201103L
235 template<typename _InputIterator,
236 typename = std::_RequireInputIter<_InputIterator>>
237#else
238 template<typename _InputIterator>
239#endif
240 basic_string(_InputIterator __begin, _InputIterator __end,
241 const _Allocator& __a = _Allocator())
242 : _Base(__gnu_debug::__base(
243 __glibcxx_check_valid_constructor_range(__begin, __end)),
244 __gnu_debug::__base(__end), __a) { }
245
246#if __cplusplus >= 201103L
247 basic_string&
248 operator=(const basic_string&) = default;
249
250 basic_string&
251 operator=(basic_string&&) = default;
252#endif
253
254 basic_string&
255 operator=(const _CharT* __s)
256 {
257 __glibcxx_check_string(__s);
258 _Base::operator=(__s);
259 this->_M_invalidate_all();
260 return *this;
261 }
262
263 basic_string&
264 operator=(_CharT __c)
265 {
266 _Base::operator=(__c);
267 this->_M_invalidate_all();
268 return *this;
269 }
270
271#if __cplusplus >= 201103L
272 basic_string&
273 operator=(std::initializer_list<_CharT> __l)
274 {
275 _Base::operator=(__l);
276 this->_M_invalidate_all();
277 return *this;
278 }
279#endif // C++11
280
281 // 21.3.2 iterators:
282 iterator
283 begin() // _GLIBCXX_NOEXCEPT
284 { return iterator(_Base::begin(), this); }
285
286 const_iterator
287 begin() const _GLIBCXX_NOEXCEPT
288 { return const_iterator(_Base::begin(), this); }
289
290 iterator
291 end() // _GLIBCXX_NOEXCEPT
292 { return iterator(_Base::end(), this); }
293
294 const_iterator
295 end() const _GLIBCXX_NOEXCEPT
296 { return const_iterator(_Base::end(), this); }
297
298 reverse_iterator
299 rbegin() // _GLIBCXX_NOEXCEPT
300 { return reverse_iterator(end()); }
301
302 const_reverse_iterator
303 rbegin() const _GLIBCXX_NOEXCEPT
304 { return const_reverse_iterator(end()); }
305
306 reverse_iterator
307 rend() // _GLIBCXX_NOEXCEPT
308 { return reverse_iterator(begin()); }
309
310 const_reverse_iterator
311 rend() const _GLIBCXX_NOEXCEPT
312 { return const_reverse_iterator(begin()); }
313
314#if __cplusplus >= 201103L
315 const_iterator
316 cbegin() const noexcept
317 { return const_iterator(_Base::begin(), this); }
318
319 const_iterator
320 cend() const noexcept
321 { return const_iterator(_Base::end(), this); }
322
323 const_reverse_iterator
324 crbegin() const noexcept
325 { return const_reverse_iterator(end()); }
326
327 const_reverse_iterator
328 crend() const noexcept
329 { return const_reverse_iterator(begin()); }
330#endif
331
332 // 21.3.3 capacity:
333 using _Base::size;
334 using _Base::length;
335 using _Base::max_size;
336
337 void
338 resize(size_type __n, _CharT __c)
339 {
340 _Base::resize(__n, __c);
341 this->_M_invalidate_all();
342 }
343
344 void
345 resize(size_type __n)
346 { this->resize(__n, _CharT()); }
347
348#if __cplusplus >= 201103L
349 void
350 shrink_to_fit() noexcept
351 {
352 if (capacity() > size())
353 {
354 __try
355 {
356 reserve(0);
357 this->_M_invalidate_all();
358 }
359 __catch(...)
360 { }
361 }
362 }
363#endif
364
365 using _Base::capacity;
366 using _Base::reserve;
367
368 void
369 clear() // _GLIBCXX_NOEXCEPT
370 {
371 _Base::clear();
372 this->_M_invalidate_all();
373 }
374
375 using _Base::empty;
376
377 // 21.3.4 element access:
378 const_reference
379 operator[](size_type __pos) const _GLIBCXX_NOEXCEPT
380 {
381 _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
382 _M_message(__gnu_debug::__msg_subscript_oob)
383 ._M_sequence(*this, "this")
384 ._M_integer(__pos, "__pos")
385 ._M_integer(this->size(), "size"));
386 return _Base::operator[](__pos);
387 }
388
389 reference
390 operator[](size_type __pos) // _GLIBCXX_NOEXCEPT
391 {
392#if __cplusplus < 201103L && defined(_GLIBCXX_DEBUG_PEDANTIC)
393 __glibcxx_check_subscript(__pos);
394#else
395 // as an extension v3 allows s[s.size()] when s is non-const.
396 _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
397 _M_message(__gnu_debug::__msg_subscript_oob)
398 ._M_sequence(*this, "this")
399 ._M_integer(__pos, "__pos")
400 ._M_integer(this->size(), "size"));
401#endif
402 return _Base::operator[](__pos);
403 }
404
405 using _Base::at;
406
407#if __cplusplus >= 201103L
408 using _Base::front;
409 using _Base::back;
410#endif
411
412 // 21.3.5 modifiers:
413 basic_string&
414 operator+=(const basic_string& __str)
415 {
416 _Base::operator+=(__str);
417 this->_M_invalidate_all();
418 return *this;
419 }
420
421 basic_string&
422 operator+=(const _CharT* __s)
423 {
424 __glibcxx_check_string(__s);
426 this->_M_invalidate_all();
427 return *this;
428 }
429
430 basic_string&
431 operator+=(_CharT __c)
432 {
434 this->_M_invalidate_all();
435 return *this;
436 }
437
438#if __cplusplus >= 201103L
439 basic_string&
440 operator+=(std::initializer_list<_CharT> __l)
441 {
443 this->_M_invalidate_all();
444 return *this;
445 }
446#endif // C++11
447
448 basic_string&
449 append(const basic_string& __str)
450 {
451 _Base::append(__str);
452 this->_M_invalidate_all();
453 return *this;
454 }
455
456 basic_string&
457 append(const basic_string& __str, size_type __pos, size_type __n)
458 {
459 _Base::append(__str, __pos, __n);
460 this->_M_invalidate_all();
461 return *this;
462 }
463
464 basic_string&
465 append(const _CharT* __s, size_type __n)
466 {
467 __glibcxx_check_string_len(__s, __n);
468 _Base::append(__s, __n);
469 this->_M_invalidate_all();
470 return *this;
471 }
472
473 basic_string&
474 append(const _CharT* __s)
475 {
476 __glibcxx_check_string(__s);
477 _Base::append(__s);
478 this->_M_invalidate_all();
479 return *this;
480 }
481
482 basic_string&
483 append(size_type __n, _CharT __c)
484 {
485 _Base::append(__n, __c);
486 this->_M_invalidate_all();
487 return *this;
488 }
489
490 template<typename _InputIterator>
491 basic_string&
492 append(_InputIterator __first, _InputIterator __last)
493 {
494 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
495 __glibcxx_check_valid_range2(__first, __last, __dist);
496
497 if (__dist.second >= __dp_sign)
498 _Base::append(__gnu_debug::__unsafe(__first),
499 __gnu_debug::__unsafe(__last));
500 else
501 _Base::append(__first, __last);
502
503 this->_M_invalidate_all();
504 return *this;
505 }
506
507 // _GLIBCXX_RESOLVE_LIB_DEFECTS
508 // 7. string clause minor problems
509 void
510 push_back(_CharT __c)
511 {
512 _Base::push_back(__c);
513 this->_M_invalidate_all();
514 }
515
516 basic_string&
517 assign(const basic_string& __x)
518 {
519 _Base::assign(__x);
520 this->_M_invalidate_all();
521 return *this;
522 }
523
524#if __cplusplus >= 201103L
525 basic_string&
526 assign(basic_string&& __x)
527 noexcept(noexcept(std::declval<_Base&>().assign(std::move(__x))))
528 {
530 this->_M_invalidate_all();
531 return *this;
532 }
533#endif // C++11
534
535 basic_string&
536 assign(const basic_string& __str, size_type __pos, size_type __n)
537 {
538 _Base::assign(__str, __pos, __n);
539 this->_M_invalidate_all();
540 return *this;
541 }
542
543 basic_string&
544 assign(const _CharT* __s, size_type __n)
545 {
546 __glibcxx_check_string_len(__s, __n);
547 _Base::assign(__s, __n);
548 this->_M_invalidate_all();
549 return *this;
550 }
551
552 basic_string&
553 assign(const _CharT* __s)
554 {
555 __glibcxx_check_string(__s);
556 _Base::assign(__s);
557 this->_M_invalidate_all();
558 return *this;
559 }
560
561 basic_string&
562 assign(size_type __n, _CharT __c)
563 {
564 _Base::assign(__n, __c);
565 this->_M_invalidate_all();
566 return *this;
567 }
568
569 template<typename _InputIterator>
570 basic_string&
571 assign(_InputIterator __first, _InputIterator __last)
572 {
573 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
574 __glibcxx_check_valid_range2(__first, __last, __dist);
575
576 if (__dist.second >= __dp_sign)
577 _Base::assign(__gnu_debug::__unsafe(__first),
578 __gnu_debug::__unsafe(__last));
579 else
580 _Base::assign(__first, __last);
581
582 this->_M_invalidate_all();
583 return *this;
584 }
585
586#if __cplusplus >= 201103L
587 basic_string&
589 {
590 _Base::assign(__l);
591 this->_M_invalidate_all();
592 return *this;
593 }
594#endif // C++11
595
596 basic_string&
597 insert(size_type __pos1, const basic_string& __str)
598 {
599 _Base::insert(__pos1, __str);
600 this->_M_invalidate_all();
601 return *this;
602 }
603
604 basic_string&
605 insert(size_type __pos1, const basic_string& __str,
606 size_type __pos2, size_type __n)
607 {
608 _Base::insert(__pos1, __str, __pos2, __n);
609 this->_M_invalidate_all();
610 return *this;
611 }
612
613 basic_string&
614 insert(size_type __pos, const _CharT* __s, size_type __n)
615 {
616 __glibcxx_check_string(__s);
617 _Base::insert(__pos, __s, __n);
618 this->_M_invalidate_all();
619 return *this;
620 }
621
622 basic_string&
623 insert(size_type __pos, const _CharT* __s)
624 {
625 __glibcxx_check_string(__s);
626 _Base::insert(__pos, __s);
627 this->_M_invalidate_all();
628 return *this;
629 }
630
631 basic_string&
632 insert(size_type __pos, size_type __n, _CharT __c)
633 {
634 _Base::insert(__pos, __n, __c);
635 this->_M_invalidate_all();
636 return *this;
637 }
638
639 iterator
640 insert(__const_iterator __p, _CharT __c)
641 {
643 typename _Base::iterator __res = _Base::insert(__p.base(), __c);
644 this->_M_invalidate_all();
645 return iterator(__res, this);
646 }
647
648#if __cplusplus >= 201103L
649 iterator
650 insert(const_iterator __p, size_type __n, _CharT __c)
651 {
653#if _GLIBCXX_USE_CXX11_ABI
654 typename _Base::iterator __res = _Base::insert(__p.base(), __n, __c);
655#else
656 const size_type __offset = __p.base() - _Base::cbegin();
657 _Base::insert(_Base::begin() + __offset, __n, __c);
658 typename _Base::iterator __res = _Base::begin() + __offset;
659#endif
660 this->_M_invalidate_all();
661 return iterator(__res, this);
662 }
663#else
664 void
665 insert(iterator __p, size_type __n, _CharT __c)
666 {
668 _Base::insert(__p.base(), __n, __c);
669 this->_M_invalidate_all();
670 }
671#endif
672
673 template<typename _InputIterator>
674 iterator
675 insert(__const_iterator __p,
676 _InputIterator __first, _InputIterator __last)
677 {
678 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
679 __glibcxx_check_insert_range(__p, __first, __last, __dist);
680
681 typename _Base::iterator __res;
682#if ! _GLIBCXX_INSERT_RETURNS_ITERATOR
683 const size_type __offset = __p.base() - _Base::begin();
684#endif
685 if (__dist.second >= __dp_sign)
686 {
687 _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(__res =)
688 _Base::insert(__p.base(), __gnu_debug::__unsafe(__first),
689 __gnu_debug::__unsafe(__last));
690 }
691 else
692 {
693 _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(__res =)
694 _Base::insert(__p.base(), __first, __last);
695 }
696
697#if ! _GLIBCXX_INSERT_RETURNS_ITERATOR
698 __res = _Base::begin() + __offset;
699#endif
700 this->_M_invalidate_all();
701 return iterator(__res, this);
702 }
703
704#if __cplusplus >= 201103L
705 iterator
706 insert(const_iterator __p, std::initializer_list<_CharT> __l)
707 {
709#if _GLIBCXX_USE_CXX11_ABI
710 const auto __res = _Base::insert(__p.base(), __l);
711#else
712 const size_type __offset = __p.base() - _Base::cbegin();
713 _Base::insert(_Base::begin() + __offset, __l);
714 auto __res = _Base::begin() + __offset;
715#endif
716 this->_M_invalidate_all();
717 return iterator(__res, this);
718 }
719#endif // C++11
720
721 basic_string&
722 erase(size_type __pos = 0, size_type __n = _Base::npos)
723 {
724 _Base::erase(__pos, __n);
725 this->_M_invalidate_all();
726 return *this;
727 }
728
729 iterator
730 erase(__const_iterator __position)
731 {
732 __glibcxx_check_erase(__position);
733 typename _Base::iterator __res = _Base::erase(__position.base());
734 this->_M_invalidate_all();
735 return iterator(__res, this);
736 }
737
738 iterator
739 erase(__const_iterator __first, __const_iterator __last)
740 {
741 // _GLIBCXX_RESOLVE_LIB_DEFECTS
742 // 151. can't currently clear() empty container
743 __glibcxx_check_erase_range(__first, __last);
744 typename _Base::iterator __res = _Base::erase(__first.base(),
745 __last.base());
746 this->_M_invalidate_all();
747 return iterator(__res, this);
748 }
749
750#if __cplusplus >= 201103L
751 void
752 pop_back() // noexcept
753 {
754 __glibcxx_check_nonempty();
756 this->_M_invalidate_all();
757 }
758#endif // C++11
759
760 basic_string&
761 replace(size_type __pos1, size_type __n1, const basic_string& __str)
762 {
763 _Base::replace(__pos1, __n1, __str);
764 this->_M_invalidate_all();
765 return *this;
766 }
767
768 basic_string&
769 replace(size_type __pos1, size_type __n1, const basic_string& __str,
770 size_type __pos2, size_type __n2)
771 {
772 _Base::replace(__pos1, __n1, __str, __pos2, __n2);
773 this->_M_invalidate_all();
774 return *this;
775 }
776
777 basic_string&
778 replace(size_type __pos, size_type __n1, const _CharT* __s,
779 size_type __n2)
780 {
781 __glibcxx_check_string_len(__s, __n2);
782 _Base::replace(__pos, __n1, __s, __n2);
783 this->_M_invalidate_all();
784 return *this;
785 }
786
787 basic_string&
788 replace(size_type __pos, size_type __n1, const _CharT* __s)
789 {
790 __glibcxx_check_string(__s);
791 _Base::replace(__pos, __n1, __s);
792 this->_M_invalidate_all();
793 return *this;
794 }
795
796 basic_string&
797 replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
798 {
799 _Base::replace(__pos, __n1, __n2, __c);
800 this->_M_invalidate_all();
801 return *this;
802 }
803
804 basic_string&
805 replace(__const_iterator __i1, __const_iterator __i2,
806 const basic_string& __str)
807 {
808 __glibcxx_check_erase_range(__i1, __i2);
809 _Base::replace(__i1.base(), __i2.base(), __str);
810 this->_M_invalidate_all();
811 return *this;
812 }
813
814 basic_string&
815 replace(__const_iterator __i1, __const_iterator __i2,
816 const _CharT* __s, size_type __n)
817 {
818 __glibcxx_check_erase_range(__i1, __i2);
819 __glibcxx_check_string_len(__s, __n);
820 _Base::replace(__i1.base(), __i2.base(), __s, __n);
821 this->_M_invalidate_all();
822 return *this;
823 }
824
825 basic_string&
826 replace(__const_iterator __i1, __const_iterator __i2,
827 const _CharT* __s)
828 {
829 __glibcxx_check_erase_range(__i1, __i2);
830 __glibcxx_check_string(__s);
831 _Base::replace(__i1.base(), __i2.base(), __s);
832 this->_M_invalidate_all();
833 return *this;
834 }
835
836 basic_string&
837 replace(__const_iterator __i1, __const_iterator __i2,
838 size_type __n, _CharT __c)
839 {
840 __glibcxx_check_erase_range(__i1, __i2);
841 _Base::replace(__i1.base(), __i2.base(), __n, __c);
842 this->_M_invalidate_all();
843 return *this;
844 }
845
846 template<typename _InputIterator>
847 basic_string&
848 replace(__const_iterator __i1, __const_iterator __i2,
849 _InputIterator __j1, _InputIterator __j2)
850 {
851 __glibcxx_check_erase_range(__i1, __i2);
852
853 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
854 __glibcxx_check_valid_range2(__j1, __j2, __dist);
855
856 if (__dist.second >= __dp_sign)
857 _Base::replace(__i1.base(), __i2.base(),
858 __gnu_debug::__unsafe(__j1),
859 __gnu_debug::__unsafe(__j2));
860 else
861 _Base::replace(__i1.base(), __i2.base(), __j1, __j2);
862
863 this->_M_invalidate_all();
864 return *this;
865 }
866
867#if __cplusplus >= 201103L
868 basic_string&
869 replace(__const_iterator __i1, __const_iterator __i2,
871 {
872 __glibcxx_check_erase_range(__i1, __i2);
873 _Base::replace(__i1.base(), __i2.base(), __l);
874 this->_M_invalidate_all();
875 return *this;
876 }
877#endif // C++11
878
879 size_type
880 copy(_CharT* __s, size_type __n, size_type __pos = 0) const
881 {
882 __glibcxx_check_string_len(__s, __n);
883 return _Base::copy(__s, __n, __pos);
884 }
885
886 void
887 swap(basic_string& __x)
888 _GLIBCXX_NOEXCEPT_IF(std::__is_nothrow_swappable<_Base>::value)
889 {
890 _Safe::_M_swap(__x);
891 _Base::swap(__x);
892 }
893
894 // 21.3.6 string operations:
895 const _CharT*
896 c_str() const _GLIBCXX_NOEXCEPT
897 {
898 const _CharT* __res = _Base::c_str();
899 this->_M_invalidate_all();
900 return __res;
901 }
902
903 const _CharT*
904 data() const _GLIBCXX_NOEXCEPT
905 {
906 const _CharT* __res = _Base::data();
907 this->_M_invalidate_all();
908 return __res;
909 }
910
912
913 using _Base::find;
914
915 _GLIBCXX20_CONSTEXPR
916 size_type
917 find(const _CharT* __s, size_type __pos, size_type __n) const
918 _GLIBCXX_NOEXCEPT
919 {
920 __glibcxx_check_string(__s);
921 return _Base::find(__s, __pos, __n);
922 }
923
924 _GLIBCXX20_CONSTEXPR
925 size_type
926 find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
927 {
928 __glibcxx_check_string(__s);
929 return _Base::find(__s, __pos);
930 }
931
932 using _Base::rfind;
933
934 _GLIBCXX20_CONSTEXPR
935 size_type
936 rfind(const _CharT* __s, size_type __pos, size_type __n) const
937 {
938 __glibcxx_check_string_len(__s, __n);
939 return _Base::rfind(__s, __pos, __n);
940 }
941
942 _GLIBCXX20_CONSTEXPR
943 size_type
944 rfind(const _CharT* __s, size_type __pos = _Base::npos) const
945 {
946 __glibcxx_check_string(__s);
947 return _Base::rfind(__s, __pos);
948 }
949
951
952 _GLIBCXX20_CONSTEXPR
953 size_type
954 find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
955 _GLIBCXX_NOEXCEPT
956 {
957 __glibcxx_check_string(__s);
958 return _Base::find_first_of(__s, __pos, __n);
959 }
960
961 _GLIBCXX20_CONSTEXPR
962 size_type
963 find_first_of(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
964 {
965 __glibcxx_check_string(__s);
966 return _Base::find_first_of(__s, __pos);
967 }
968
970
971 _GLIBCXX20_CONSTEXPR
972 size_type
973 find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
974 _GLIBCXX_NOEXCEPT
975 {
976 __glibcxx_check_string(__s);
977 return _Base::find_last_of(__s, __pos, __n);
978 }
979
980 _GLIBCXX20_CONSTEXPR
981 size_type
982 find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
983 _GLIBCXX_NOEXCEPT
984 {
985 __glibcxx_check_string(__s);
986 return _Base::find_last_of(__s, __pos);
987 }
988
990
991 _GLIBCXX20_CONSTEXPR
992 size_type
993 find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
994 _GLIBCXX_NOEXCEPT
995 {
996 __glibcxx_check_string_len(__s, __n);
997 return _Base::find_first_not_of(__s, __pos, __n);
998 }
999
1000 _GLIBCXX20_CONSTEXPR
1001 size_type
1002 find_first_not_of(const _CharT* __s, size_type __pos = 0) const
1003 _GLIBCXX_NOEXCEPT
1004 {
1005 __glibcxx_check_string(__s);
1006 return _Base::find_first_not_of(__s, __pos);
1007 }
1008
1010
1011 _GLIBCXX20_CONSTEXPR
1012 size_type
1013 find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
1014 _GLIBCXX_NOEXCEPT
1015 {
1016 __glibcxx_check_string(__s);
1017 return _Base::find_last_not_of(__s, __pos, __n);
1018 }
1019
1020 _GLIBCXX20_CONSTEXPR
1021 size_type
1022 find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
1023 _GLIBCXX_NOEXCEPT
1024 {
1025 __glibcxx_check_string(__s);
1026 return _Base::find_last_not_of(__s, __pos);
1027 }
1028
1029 basic_string
1030 substr(size_type __pos = 0, size_type __n = _Base::npos) const
1031 { return basic_string(_Base::substr(__pos, __n)); }
1032
1033 using _Base::compare;
1034
1035 _GLIBCXX20_CONSTEXPR
1036 int
1037 compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT
1038 {
1039 __glibcxx_check_string(__s);
1040 return _Base::compare(__s);
1041 }
1042
1043 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1044 // 5. string::compare specification questionable
1045 _GLIBCXX20_CONSTEXPR
1046 int
1047 compare(size_type __pos1, size_type __n1, const _CharT* __s) const
1048 {
1049 __glibcxx_check_string(__s);
1050 return _Base::compare(__pos1, __n1, __s);
1051 }
1052
1053 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1054 // 5. string::compare specification questionable
1055 _GLIBCXX20_CONSTEXPR
1056 int
1057 compare(size_type __pos1, size_type __n1,const _CharT* __s,
1058 size_type __n2) const
1059 {
1060 __glibcxx_check_string_len(__s, __n2);
1061 return _Base::compare(__pos1, __n1, __s, __n2);
1062 }
1063
1064 _Base&
1065 _M_base() _GLIBCXX_NOEXCEPT { return *this; }
1066
1067 const _Base&
1068 _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
1069
1071 };
1072
1073 template<typename _CharT, typename _Traits, typename _Allocator>
1075 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1077 { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
1078
1079 template<typename _CharT, typename _Traits, typename _Allocator>
1080 inline basic_string<_CharT,_Traits,_Allocator>
1081 operator+(const _CharT* __lhs,
1082 const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1083 {
1084 __glibcxx_check_string(__lhs);
1085 return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
1086 }
1087
1088 template<typename _CharT, typename _Traits, typename _Allocator>
1090 operator+(_CharT __lhs,
1092 { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; }
1093
1094 template<typename _CharT, typename _Traits, typename _Allocator>
1096 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1097 const _CharT* __rhs)
1098 {
1099 __glibcxx_check_string(__rhs);
1100 return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
1101 }
1102
1103 template<typename _CharT, typename _Traits, typename _Allocator>
1105 operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1106 _CharT __rhs)
1107 { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
1108
1109 template<typename _CharT, typename _Traits, typename _Allocator>
1110 inline bool
1111 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1113 { return __lhs._M_base() == __rhs._M_base(); }
1114
1115 template<typename _CharT, typename _Traits, typename _Allocator>
1116 inline bool
1117 operator==(const _CharT* __lhs,
1119 {
1120 __glibcxx_check_string(__lhs);
1121 return __lhs == __rhs._M_base();
1122 }
1123
1124 template<typename _CharT, typename _Traits, typename _Allocator>
1125 inline bool
1126 operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1127 const _CharT* __rhs)
1128 {
1129 __glibcxx_check_string(__rhs);
1130 return __lhs._M_base() == __rhs;
1131 }
1132
1133 template<typename _CharT, typename _Traits, typename _Allocator>
1134 inline bool
1135 operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1137 { return __lhs._M_base() != __rhs._M_base(); }
1138
1139 template<typename _CharT, typename _Traits, typename _Allocator>
1140 inline bool
1141 operator!=(const _CharT* __lhs,
1143 {
1144 __glibcxx_check_string(__lhs);
1145 return __lhs != __rhs._M_base();
1146 }
1147
1148 template<typename _CharT, typename _Traits, typename _Allocator>
1149 inline bool
1150 operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1151 const _CharT* __rhs)
1152 {
1153 __glibcxx_check_string(__rhs);
1154 return __lhs._M_base() != __rhs;
1155 }
1156
1157 template<typename _CharT, typename _Traits, typename _Allocator>
1158 inline bool
1159 operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1161 { return __lhs._M_base() < __rhs._M_base(); }
1162
1163 template<typename _CharT, typename _Traits, typename _Allocator>
1164 inline bool
1165 operator<(const _CharT* __lhs,
1167 {
1168 __glibcxx_check_string(__lhs);
1169 return __lhs < __rhs._M_base();
1170 }
1171
1172 template<typename _CharT, typename _Traits, typename _Allocator>
1173 inline bool
1174 operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1175 const _CharT* __rhs)
1176 {
1177 __glibcxx_check_string(__rhs);
1178 return __lhs._M_base() < __rhs;
1179 }
1180
1181 template<typename _CharT, typename _Traits, typename _Allocator>
1182 inline bool
1183 operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1185 { return __lhs._M_base() <= __rhs._M_base(); }
1186
1187 template<typename _CharT, typename _Traits, typename _Allocator>
1188 inline bool
1189 operator<=(const _CharT* __lhs,
1191 {
1192 __glibcxx_check_string(__lhs);
1193 return __lhs <= __rhs._M_base();
1194 }
1195
1196 template<typename _CharT, typename _Traits, typename _Allocator>
1197 inline bool
1198 operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1199 const _CharT* __rhs)
1200 {
1201 __glibcxx_check_string(__rhs);
1202 return __lhs._M_base() <= __rhs;
1203 }
1204
1205 template<typename _CharT, typename _Traits, typename _Allocator>
1206 inline bool
1207 operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1209 { return __lhs._M_base() >= __rhs._M_base(); }
1210
1211 template<typename _CharT, typename _Traits, typename _Allocator>
1212 inline bool
1213 operator>=(const _CharT* __lhs,
1215 {
1216 __glibcxx_check_string(__lhs);
1217 return __lhs >= __rhs._M_base();
1218 }
1219
1220 template<typename _CharT, typename _Traits, typename _Allocator>
1221 inline bool
1222 operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1223 const _CharT* __rhs)
1224 {
1225 __glibcxx_check_string(__rhs);
1226 return __lhs._M_base() >= __rhs;
1227 }
1228
1229 template<typename _CharT, typename _Traits, typename _Allocator>
1230 inline bool
1231 operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1233 { return __lhs._M_base() > __rhs._M_base(); }
1234
1235 template<typename _CharT, typename _Traits, typename _Allocator>
1236 inline bool
1237 operator>(const _CharT* __lhs,
1239 {
1240 __glibcxx_check_string(__lhs);
1241 return __lhs > __rhs._M_base();
1242 }
1243
1244 template<typename _CharT, typename _Traits, typename _Allocator>
1245 inline bool
1246 operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1247 const _CharT* __rhs)
1248 {
1249 __glibcxx_check_string(__rhs);
1250 return __lhs._M_base() > __rhs;
1251 }
1252
1253 // 21.3.7.8:
1254 template<typename _CharT, typename _Traits, typename _Allocator>
1255 inline void
1258 { __lhs.swap(__rhs); }
1259
1260 template<typename _CharT, typename _Traits, typename _Allocator>
1261 std::basic_ostream<_CharT, _Traits>&
1262 operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1264 { return __os << __str._M_base(); }
1265
1266 template<typename _CharT, typename _Traits, typename _Allocator>
1267 std::basic_istream<_CharT,_Traits>&
1268 operator>>(std::basic_istream<_CharT,_Traits>& __is,
1270 {
1271 std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
1272 __str._M_invalidate_all();
1273 return __res;
1274 }
1275
1276 template<typename _CharT, typename _Traits, typename _Allocator>
1277 std::basic_istream<_CharT,_Traits>&
1278 getline(std::basic_istream<_CharT,_Traits>& __is,
1279 basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
1280 {
1281 std::basic_istream<_CharT,_Traits>& __res = getline(__is,
1282 __str._M_base(),
1283 __delim);
1284 __str._M_invalidate_all();
1285 return __res;
1286 }
1287
1288 template<typename _CharT, typename _Traits, typename _Allocator>
1289 std::basic_istream<_CharT,_Traits>&
1290 getline(std::basic_istream<_CharT,_Traits>& __is,
1292 {
1293 std::basic_istream<_CharT,_Traits>& __res = getline(__is,
1294 __str._M_base());
1295 __str._M_invalidate_all();
1296 return __res;
1297 }
1298
1299 typedef basic_string<char> string;
1300
1301 typedef basic_string<wchar_t> wstring;
1302
1303#ifdef _GLIBCXX_USE_CHAR8_T
1304 /// A string of @c char8_t
1305 typedef basic_string<char8_t> u8string;
1306#endif
1307
1308#if __cplusplus >= 201103L
1309 /// A string of @c char16_t
1311
1312 /// A string of @c char32_t
1314#endif
1315
1316 template<typename _CharT, typename _Traits, typename _Allocator>
1317 struct _Insert_range_from_self_is_safe<
1318 __gnu_debug::basic_string<_CharT, _Traits, _Allocator> >
1319 { enum { __value = 1 }; };
1320
1321} // namespace __gnu_debug
1322
1323#if __cplusplus >= 201103L
1324namespace std _GLIBCXX_VISIBILITY(default)
1325{
1326_GLIBCXX_BEGIN_NAMESPACE_VERSION
1327
1328 /// std::hash specialization for __gnu_debug::basic_string.
1329 template<typename _CharT>
1331 : public hash<std::basic_string<_CharT>>
1332 { };
1333
1334 template<typename _CharT>
1336 : __is_fast_hash<hash<std::basic_string<_CharT>>>
1337 { };
1338
1339#ifdef __glibcxx_erase_if // C++ >= 20 && HOSTED
1340 template<typename _CharT, typename _Traits, typename _Alloc,
1341 typename _Predicate>
1342 constexpr typename __gnu_debug::basic_string<_CharT,
1343 _Traits, _Alloc>::size_type
1345 _Predicate __pred)
1346 {
1347 return __detail::__erase_if(__cont, __cont._M_base(), std::move(__pred));
1348 }
1349
1350 template<typename _CharT, typename _Traits, typename _Alloc,
1351 typename _Up _GLIBCXX26_DEF_VAL_T(_CharT)>
1352 constexpr typename __gnu_debug::basic_string<_CharT,
1353 _Traits, _Alloc>::size_type
1354 erase(__gnu_debug::basic_string<_CharT, _Traits, _Alloc>& __cont,
1355 const _Up& __value)
1356 { return std::erase_if(__cont, __gnu_cxx::__ops::__equal_to(__value)); }
1357#endif // __glibcxx_erase_if
1358
1359_GLIBCXX_END_NAMESPACE_VERSION
1360}
1361#endif /* C++11 */
1362
1363#undef _GLIBCXX_INSERT_RETURNS_ITERATOR
1364#undef _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY
1365
1366#endif
#define __glibcxx_check_insert(_Position)
Definition macros.h:143
#define __glibcxx_check_erase_range(_First, _Last)
Definition macros.h:245
#define __glibcxx_check_erase(_Position)
Definition macros.h:209
#define __glibcxx_check_insert_range(_Position, _First, _Last, _Dist)
Definition macros.h:177
auto declval() noexcept -> decltype(__declval< _Tp >(0))
Definition type_traits:2714
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition move.h:138
ISO C++ entities toplevel namespace is std.
GNU debug classes for public use.
basic_string< char32_t > u32string
A string of char32_t.
const _CharT * __check_string(const _CharT *__s, _Integer __n, const char *__file, unsigned int __line, const char *__function)
Definition debug/string:84
constexpr _Iterator __base(_Iterator __it)
basic_string< char16_t > u16string
A string of char16_t.
initializer_list
Primary class template hash.
is_nothrow_constructible
Definition type_traits:1316
Managing sequences of characters and character-like objects.
constexpr const _CharT * c_str() const noexcept
Return const pointer to null-terminated contents.
constexpr basic_string() noexcept(/*conditional */)
Default constructor creates an empty string.
constexpr size_type size() const noexcept
constexpr void clear() noexcept
constexpr size_type find_last_not_of(const basic_string &__str, size_type __pos=npos) const noexcept
constexpr void reserve(size_type __res_arg)
constexpr size_type find(const _CharT *__s, size_type __pos, size_type __n) const noexcept
constexpr const _CharT * data() const noexcept
Return const pointer to contents.
constexpr void shrink_to_fit() noexcept
A non-binding request to reduce capacity() to size().
constexpr basic_string substr(size_type __pos=0, size_type __n=npos) const
constexpr basic_string & assign(const basic_string &__str)
constexpr size_type length() const noexcept
constexpr const_reverse_iterator crbegin() const noexcept
constexpr size_type copy(_CharT *__s, size_type __n, size_type __pos=0) const
constexpr const_iterator cbegin() const noexcept
constexpr size_type find_first_of(const basic_string &__str, size_type __pos=0) const noexcept
constexpr const_reference at(size_type __n) const
constexpr reverse_iterator rend() noexcept
constexpr void resize(size_type __n, _CharT __c)
constexpr ~basic_string()
Destroy the string instance.
constexpr size_type rfind(const basic_string &__str, size_type __pos=npos) const noexcept
constexpr basic_string & append(const basic_string &__str)
constexpr basic_string & operator=(const basic_string &__str)
constexpr size_type find_last_of(const basic_string &__str, size_type __pos=npos) const noexcept
constexpr iterator end() noexcept
constexpr iterator begin() noexcept
constexpr reverse_iterator rbegin() noexcept
constexpr size_type find_first_not_of(const basic_string &__str, size_type __pos=0) const noexcept
constexpr iterator insert(const_iterator __p, size_type __n, _CharT __c)
constexpr size_type capacity() const noexcept
constexpr basic_string & erase(size_type __pos=0, size_type __n=npos)
constexpr allocator_type get_allocator() const noexcept
constexpr basic_string & replace(size_type __pos, size_type __n, const basic_string &__str)
constexpr const_reverse_iterator crend() const noexcept
constexpr int compare(const basic_string &__str) const
constexpr size_type max_size() const noexcept
constexpr void swap(basic_string &__s) noexcept
constexpr const_reference operator[](size_type __pos) const noexcept
constexpr void pop_back() noexcept
Remove the last character.
constexpr basic_string & operator+=(const basic_string &__str)
constexpr const_iterator cend() const noexcept
Safe iterator wrapper.
constexpr _Iterator & base() noexcept
Return the underlying iterator.
Base class for constructing a safe sequence type that tracks iterators that reference it.
constexpr void _M_invalidate_all() const
Definition safe_base.h:314
Safe class dealing with some allocator dependent operations.
Class std::basic_string with safety/checking/debug instrumentation.
Definition debug/string:136
constexpr size_type capacity() const noexcept
constexpr size_type size() const noexcept
Returns the number of characters in the string, not including any null-termination.
constexpr void reserve()