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