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
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._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())
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& __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
252      const_iterator
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
260      const_iterator
261      end() const _GLIBCXX_NOEXCEPT
262      { return const_iterator(_Base::end(), this); }
263
264      reverse_iterator
265      rbegin() // _GLIBCXX_NOEXCEPT
266      { return reverse_iterator(end()); }
267
268      const_reverse_iterator
269      rbegin() const _GLIBCXX_NOEXCEPT
270      { return const_reverse_iterator(end()); }
271
272      reverse_iterator
273      rend() // _GLIBCXX_NOEXCEPT
274      { return reverse_iterator(begin()); }
275
276      const_reverse_iterator
277      rend() const _GLIBCXX_NOEXCEPT
278      { return const_reverse_iterator(begin()); }
279
280#if __cplusplus >= 201103L
281      const_iterator
282      cbegin() const noexcept
283      { return const_iterator(_Base::begin(), this); }
284
285      const_iterator
286      cend() const noexcept
287      { return const_iterator(_Base::end(), this); }
288
289      const_reverse_iterator
290      crbegin() const noexcept
291      { return const_reverse_iterator(end()); }
292
293      const_reverse_iterator
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	{
460	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
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	{
539	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
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&
554      assign(std::initializer_list<_CharT> __l)
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      {
608	__glibcxx_check_insert(__p);
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      {
618	__glibcxx_check_insert(__p);
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      {
633	__glibcxx_check_insert(__p);
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	{
644	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
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
672      insert(const_iterator __p, std::initializer_list<_CharT> __l)
673      {
674	__glibcxx_check_insert(__p);
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
819	  typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
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,
836	      std::initializer_list<_CharT> __l)
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>
1074    inline basic_string<_CharT,_Traits,_Allocator>
1075    operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1076	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
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>
1261    std::basic_ostream<_CharT, _Traits>&
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>
1267    std::basic_istream<_CharT,_Traits>&
1268    operator>>(std::basic_istream<_CharT,_Traits>& __is,
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>
1277    std::basic_istream<_CharT,_Traits>&
1278    getline(std::basic_istream<_CharT,_Traits>& __is,
1279	    basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
1280    {
1281      std::basic_istream<_CharT,_Traits>& __res = getline(__is,
1282							  __str._M_base(),
1283							__delim);
1284      __str._M_invalidate_all();
1285      return __res;
1286    }
1287
1288  template<typename _CharT, typename _Traits, typename _Allocator>
1289    std::basic_istream<_CharT,_Traits>&
1290    getline(std::basic_istream<_CharT,_Traits>& __is,
1291	    basic_string<_CharT,_Traits,_Allocator>& __str)
1292    {
1293      std::basic_istream<_CharT,_Traits>& __res = getline(__is,
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
1312  typedef basic_string<char16_t> u16string;
1313
1314  /// A string of @c char32_t
1315  typedef basic_string<char32_t> u32string;
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
1326namespace 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
1349