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