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