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