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