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