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