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