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
52namespace __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
1316namespace 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
1339