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>
36 #include <debug/safe_container.h>
37 #include <debug/safe_iterator.h>
38 
39 #define _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_Cond,_File,_Line,_Func) \
40  if (! (_Cond)) \
41  __gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func) \
42  ._M_message(#_Cond)._M_error()
43 
44 #if _GLIBCXX_USE_CXX11_ABI && __cplusplus >= 201103
45 # define _GLIBCXX_INSERT_RETURNS_ITERATOR 1
46 # define _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(expr) expr
47 #else
48 # define _GLIBCXX_INSERT_RETURNS_ITERATOR 0
49 # define _GLIBCXX_INSERT_RETURNS_ITERATOR_ONLY(expr)
50 #endif
51 
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 
77 namespace __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> >
129  class basic_string
130  : public __gnu_debug::_Safe_container<
131  basic_string<_CharT, _Traits, _Allocator>,
132  _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>,
133  public std::basic_string<_CharT, _Traits, _Allocator>
134  {
135  typedef std::basic_string<_CharT, _Traits, _Allocator> _Base;
136  typedef __gnu_debug::_Safe_container<
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.
144  typedef __gnu_debug::_Safe_iterator<
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 
159  typedef __gnu_debug::_Safe_iterator<
160  typename _Base::iterator, basic_string> iterator;
161  typedef __gnu_debug::_Safe_iterator<
162  typename _Base::const_iterator, basic_string> const_iterator;
163 
164  typedef std::reverse_iterator<iterator> reverse_iterator;
165  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
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 
187  basic_string(std::initializer_list<_CharT> __l,
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(
197  std::is_nothrow_constructible<_Base, _Base, const _Allocator&>::value )
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
210  basic_string(const _Base& __base)
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())
235  : _Base(__gnu_debug::__base(
236  __glibcxx_check_valid_constructor_range(__begin, __end)),
237  __gnu_debug::__base(__end), __a) { }
238 
239 #if __cplusplus >= 201103L
240  basic_string&
241  operator=(const basic_string&) = default;
242 
243  basic_string&
244  operator=(basic_string&&) = default;
245 #endif
246 
247  basic_string&
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 
256  basic_string&
257  operator=(_CharT __c)
258  {
259  _Base::operator=(__c);
260  this->_M_invalidate_all();
261  return *this;
262  }
263 
264 #if __cplusplus >= 201103L
265  basic_string&
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:
275  iterator
276  begin() // _GLIBCXX_NOEXCEPT
277  { return iterator(_Base::begin(), this); }
278 
279  const_iterator
280  begin() const _GLIBCXX_NOEXCEPT
281  { return const_iterator(_Base::begin(), this); }
282 
283  iterator
284  end() // _GLIBCXX_NOEXCEPT
285  { return iterator(_Base::end(), this); }
286 
287  const_iterator
288  end() const _GLIBCXX_NOEXCEPT
289  { return const_iterator(_Base::end(), this); }
290 
291  reverse_iterator
292  rbegin() // _GLIBCXX_NOEXCEPT
293  { return reverse_iterator(end()); }
294 
295  const_reverse_iterator
296  rbegin() const _GLIBCXX_NOEXCEPT
297  { return const_reverse_iterator(end()); }
298 
299  reverse_iterator
300  rend() // _GLIBCXX_NOEXCEPT
301  { return reverse_iterator(begin()); }
302 
303  const_reverse_iterator
304  rend() const _GLIBCXX_NOEXCEPT
305  { return const_reverse_iterator(begin()); }
306 
307 #if __cplusplus >= 201103L
308  const_iterator
309  cbegin() const noexcept
310  { return const_iterator(_Base::begin(), this); }
311 
312  const_iterator
313  cend() const noexcept
314  { return const_iterator(_Base::end(), this); }
315 
316  const_reverse_iterator
317  crbegin() const noexcept
318  { return const_reverse_iterator(end()); }
319 
320  const_reverse_iterator
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:
406  basic_string&
407  operator+=(const basic_string& __str)
408  {
409  _Base::operator+=(__str);
410  this->_M_invalidate_all();
411  return *this;
412  }
413 
414  basic_string&
415  operator+=(const _CharT* __s)
416  {
417  __glibcxx_check_string(__s);
418  _Base::operator+=(__s);
419  this->_M_invalidate_all();
420  return *this;
421  }
422 
423  basic_string&
424  operator+=(_CharT __c)
425  {
426  _Base::operator+=(__c);
427  this->_M_invalidate_all();
428  return *this;
429  }
430 
431 #if __cplusplus >= 201103L
432  basic_string&
433  operator+=(std::initializer_list<_CharT> __l)
434  {
435  _Base::operator+=(__l);
436  this->_M_invalidate_all();
437  return *this;
438  }
439 #endif // C++11
440 
441  basic_string&
442  append(const basic_string& __str)
443  {
444  _Base::append(__str);
445  this->_M_invalidate_all();
446  return *this;
447  }
448 
449  basic_string&
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 
457  basic_string&
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 
466  basic_string&
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 
475  basic_string&
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>
484  basic_string&
485  append(_InputIterator __first, _InputIterator __last)
486  {
487  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
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 
509  basic_string&
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
518  basic_string&
519  assign(basic_string&& __x)
520  noexcept(noexcept(std::declval<_Base&>().assign(std::move(__x))))
521  {
522  _Base::assign(std::move(__x));
523  this->_M_invalidate_all();
524  return *this;
525  }
526 #endif // C++11
527 
528  basic_string&
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 
536  basic_string&
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 
545  basic_string&
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 
554  basic_string&
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>
563  basic_string&
564  assign(_InputIterator __first, _InputIterator __last)
565  {
566  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
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
580  basic_string&
581  assign(std::initializer_list<_CharT> __l)
582  {
583  _Base::assign(__l);
584  this->_M_invalidate_all();
585  return *this;
586  }
587 #endif // C++11
588 
589  basic_string&
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 
597  basic_string&
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 
606  basic_string&
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 
615  basic_string&
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 
624  basic_string&
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 
632  iterator
633  insert(__const_iterator __p, _CharT __c)
634  {
635  __glibcxx_check_insert(__p);
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
642  iterator
643  insert(const_iterator __p, size_type __n, _CharT __c)
644  {
645  __glibcxx_check_insert(__p);
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  {
660  __glibcxx_check_insert(__p);
661  _Base::insert(__p.base(), __n, __c);
662  this->_M_invalidate_all();
663  }
664 #endif
665 
666  template<typename _InputIterator>
667  iterator
668  insert(__const_iterator __p,
669  _InputIterator __first, _InputIterator __last)
670  {
671  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
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
698  iterator
699  insert(const_iterator __p, std::initializer_list<_CharT> __l)
700  {
701  __glibcxx_check_insert(__p);
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 
714  basic_string&
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 
722  iterator
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 
731  iterator
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();
748  _Base::pop_back();
749  this->_M_invalidate_all();
750  }
751 #endif // C++11
752 
753  basic_string&
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 
761  basic_string&
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 
770  basic_string&
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 
780  basic_string&
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 
789  basic_string&
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 
797  basic_string&
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 
807  basic_string&
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 
818  basic_string&
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 
829  basic_string&
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>
840  basic_string&
841  replace(__const_iterator __i1, __const_iterator __i2,
842  _InputIterator __j1, _InputIterator __j2)
843  {
844  __glibcxx_check_erase_range(__i1, __i2);
845 
846  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
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
861  basic_string&
862  replace(__const_iterator __i1, __const_iterator __i2,
863  std::initializer_list<_CharT> __l)
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 
904  using _Base::get_allocator;
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 
943  using _Base::find_first_of;
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 
962  using _Base::find_last_of;
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 
982  using _Base::find_first_not_of;
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 
1002  using _Base::find_last_not_of;
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 
1022  basic_string
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>
1067  inline basic_string<_CharT,_Traits,_Allocator>
1068  operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1069  const basic_string<_CharT,_Traits,_Allocator>& __rhs)
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>
1254  std::basic_ostream<_CharT, _Traits>&
1255  operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1256  const basic_string<_CharT, _Traits, _Allocator>& __str)
1257  { return __os << __str._M_base(); }
1258 
1259  template<typename _CharT, typename _Traits, typename _Allocator>
1260  std::basic_istream<_CharT,_Traits>&
1261  operator>>(std::basic_istream<_CharT,_Traits>& __is,
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>
1270  std::basic_istream<_CharT,_Traits>&
1271  getline(std::basic_istream<_CharT,_Traits>& __is,
1272  basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
1273  {
1274  std::basic_istream<_CharT,_Traits>& __res = getline(__is,
1275  __str._M_base(),
1276  __delim);
1277  __str._M_invalidate_all();
1278  return __res;
1279  }
1280 
1281  template<typename _CharT, typename _Traits, typename _Allocator>
1282  std::basic_istream<_CharT,_Traits>&
1283  getline(std::basic_istream<_CharT,_Traits>& __is,
1284  basic_string<_CharT,_Traits,_Allocator>& __str)
1285  {
1286  std::basic_istream<_CharT,_Traits>& __res = getline(__is,
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
1303  typedef basic_string<char16_t> u16string;
1304 
1305  /// A string of @c char32_t
1306  typedef basic_string<char32_t> u32string;
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
1317 namespace std _GLIBCXX_VISIBILITY(default)
1318 {
1319 _GLIBCXX_BEGIN_NAMESPACE_VERSION
1320 
1321  /// std::hash specialization for __gnu_debug::basic_string.
1322  template<typename _CharT>
1323  struct hash<__gnu_debug::basic_string<_CharT>>
1324  : public hash<std::basic_string<_CharT>>
1325  { };
1326 
1327  template<typename _CharT>
1328  struct __is_fast_hash<hash<__gnu_debug::basic_string<_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