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