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