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