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