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