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