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