OSDN Git Service

2006-02-21 Benjamin Kosnik <bkoz@redhat.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / debug / string
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 #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
38 namespace __gnu_debug
39 {
40   template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
41             typename _Allocator = std::allocator<_CharT> >
42     class basic_string
43     : public std::basic_string<_CharT, _Traits, _Allocator>,
44       public __gnu_debug::_Safe_sequence<basic_string<_CharT, _Traits,
45                                                       _Allocator> >
46     {
47       typedef std::basic_string<_CharT, _Traits, _Allocator> _Base;
48       typedef __gnu_debug::_Safe_sequence<basic_string>     _Safe_base;
49
50   public:
51     // types:
52     typedef _Traits                                    traits_type;
53     typedef typename _Traits::char_type                value_type;
54     typedef _Allocator                                 allocator_type;
55     typedef typename _Base::size_type                  size_type;
56     typedef typename _Base::difference_type            difference_type;
57     typedef typename _Base::reference                  reference;
58     typedef typename _Base::const_reference            const_reference;
59     typedef typename _Base::pointer                    pointer;
60     typedef typename _Base::const_pointer              const_pointer;
61
62     typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, basic_string>
63                                                        iterator;
64     typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
65                                          basic_string> const_iterator;
66
67     typedef std::reverse_iterator<iterator>            reverse_iterator;
68     typedef std::reverse_iterator<const_iterator>      const_reverse_iterator;
69
70     using _Base::npos;
71
72     // 21.3.1 construct/copy/destroy:
73     explicit basic_string(const _Allocator& __a = _Allocator())
74     : _Base(__a)
75     { }
76
77     // Provides conversion from a release-mode string to a debug-mode string
78     basic_string(const _Base& __base) : _Base(__base), _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, 
666                  size_type __pos = _Base::npos) const
667     { return _Base::find_last_of(__str, __pos); }
668
669     size_type
670     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
671     {
672       __glibcxx_check_string(__s);
673       return _Base::find_last_of(__s, __pos, __n);
674     }
675
676     size_type
677     find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
678     {
679       __glibcxx_check_string(__s);
680       return _Base::find_last_of(__s, __pos);
681     }
682
683     size_type
684     find_last_of(_CharT __c, size_type __pos = _Base::npos) const
685     { return _Base::find_last_of(__c, __pos); }
686
687     size_type
688     find_first_not_of(const basic_string& __str, size_type __pos = 0) const
689     { return _Base::find_first_not_of(__str, __pos); }
690
691     size_type
692     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
693     {
694       __glibcxx_check_string_len(__s, __n);
695       return _Base::find_first_not_of(__s, __pos, __n);
696     }
697
698     size_type
699     find_first_not_of(const _CharT* __s, size_type __pos = 0) const
700     {
701       __glibcxx_check_string(__s);
702       return _Base::find_first_not_of(__s, __pos);
703     }
704
705     size_type
706     find_first_not_of(_CharT __c, size_type __pos = 0) const
707     { return _Base::find_first_not_of(__c, __pos); }
708
709     size_type
710     find_last_not_of(const basic_string& __str,
711                                   size_type __pos = _Base::npos) const
712     { return _Base::find_last_not_of(__str, __pos); }
713
714     size_type
715     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
716     {
717       __glibcxx_check_string(__s);
718       return _Base::find_last_not_of(__s, __pos, __n);
719     }
720
721     size_type
722     find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
723     {
724       __glibcxx_check_string(__s);
725       return _Base::find_last_not_of(__s, __pos);
726     }
727
728     size_type
729     find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const
730     { return _Base::find_last_not_of(__c, __pos); }
731
732     basic_string
733     substr(size_type __pos = 0, size_type __n = _Base::npos) const
734     { return basic_string(_Base::substr(__pos, __n)); }
735
736     int
737     compare(const basic_string& __str) const
738     { return _Base::compare(__str); }
739
740     int
741     compare(size_type __pos1, size_type __n1,
742                   const basic_string& __str) const
743     { return _Base::compare(__pos1, __n1, __str); }
744
745     int
746     compare(size_type __pos1, size_type __n1, const basic_string& __str,
747               size_type __pos2, size_type __n2) const
748     { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); }
749
750     int
751     compare(const _CharT* __s) const
752     {
753       __glibcxx_check_string(__s);
754       return _Base::compare(__s);
755     }
756
757     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
758     //  5. string::compare specification questionable
759     int
760     compare(size_type __pos1, size_type __n1, const _CharT* __s) const
761     {
762       __glibcxx_check_string(__s);
763       return _Base::compare(__pos1, __n1, __s);
764     }
765
766     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
767     //  5. string::compare specification questionable
768     int
769     compare(size_type __pos1, size_type __n1,const _CharT* __s,
770               size_type __n2) const
771     {
772       __glibcxx_check_string_len(__s, __n2);
773       return _Base::compare(__pos1, __n1, __s, __n2);
774     }
775
776     _Base&
777     _M_base() { return *this; }
778
779     const _Base&
780     _M_base() const { return *this; }
781
782     using _Safe_base::_M_invalidate_all;
783   };
784
785   template<typename _CharT, typename _Traits, typename _Allocator>
786     inline basic_string<_CharT,_Traits,_Allocator>
787     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
788               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
789     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
790
791   template<typename _CharT, typename _Traits, typename _Allocator>
792     inline basic_string<_CharT,_Traits,_Allocator>
793     operator+(const _CharT* __lhs,
794               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
795     {
796       __glibcxx_check_string(__lhs);
797       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
798     }
799
800   template<typename _CharT, typename _Traits, typename _Allocator>
801     inline basic_string<_CharT,_Traits,_Allocator>
802     operator+(_CharT __lhs,
803               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
804     { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; }
805
806   template<typename _CharT, typename _Traits, typename _Allocator>
807     inline basic_string<_CharT,_Traits,_Allocator>
808     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
809               const _CharT* __rhs)
810     {
811       __glibcxx_check_string(__rhs);
812       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
813     }
814
815   template<typename _CharT, typename _Traits, typename _Allocator>
816     inline basic_string<_CharT,_Traits,_Allocator>
817     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
818               _CharT __rhs)
819     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
820
821   template<typename _CharT, typename _Traits, typename _Allocator>
822     inline bool
823     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
824                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
825     { return __lhs._M_base() == __rhs._M_base(); }
826
827   template<typename _CharT, typename _Traits, typename _Allocator>
828     inline bool
829     operator==(const _CharT* __lhs,
830                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
831     {
832       __glibcxx_check_string(__lhs);
833       return __lhs == __rhs._M_base();
834     }
835
836   template<typename _CharT, typename _Traits, typename _Allocator>
837     inline bool
838     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
839                const _CharT* __rhs)
840     {
841       __glibcxx_check_string(__rhs);
842       return __lhs._M_base() == __rhs;
843     }
844
845   template<typename _CharT, typename _Traits, typename _Allocator>
846     inline bool
847     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
848                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
849     { return __lhs._M_base() != __rhs._M_base(); }
850
851   template<typename _CharT, typename _Traits, typename _Allocator>
852     inline bool
853     operator!=(const _CharT* __lhs,
854                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
855     {
856       __glibcxx_check_string(__lhs);
857       return __lhs != __rhs._M_base();
858     }
859
860   template<typename _CharT, typename _Traits, typename _Allocator>
861     inline bool
862     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
863                const _CharT* __rhs)
864     {
865       __glibcxx_check_string(__rhs);
866       return __lhs._M_base() != __rhs;
867     }
868
869   template<typename _CharT, typename _Traits, typename _Allocator>
870     inline bool
871     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
872               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
873     { return __lhs._M_base() < __rhs._M_base(); }
874
875   template<typename _CharT, typename _Traits, typename _Allocator>
876     inline bool
877     operator<(const _CharT* __lhs,
878               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
879     {
880       __glibcxx_check_string(__lhs);
881       return __lhs < __rhs._M_base();
882     }
883
884   template<typename _CharT, typename _Traits, typename _Allocator>
885     inline bool
886     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
887               const _CharT* __rhs)
888     {
889       __glibcxx_check_string(__rhs);
890       return __lhs._M_base() < __rhs;
891     }
892
893   template<typename _CharT, typename _Traits, typename _Allocator>
894     inline bool
895     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
896                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
897     { return __lhs._M_base() <= __rhs._M_base(); }
898
899   template<typename _CharT, typename _Traits, typename _Allocator>
900     inline bool
901     operator<=(const _CharT* __lhs,
902                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
903     {
904       __glibcxx_check_string(__lhs);
905       return __lhs <= __rhs._M_base();
906     }
907
908   template<typename _CharT, typename _Traits, typename _Allocator>
909     inline bool
910     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
911                const _CharT* __rhs)
912     {
913       __glibcxx_check_string(__rhs);
914       return __lhs._M_base() <= __rhs;
915     }
916
917   template<typename _CharT, typename _Traits, typename _Allocator>
918     inline bool
919     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
920                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
921     { return __lhs._M_base() >= __rhs._M_base(); }
922
923   template<typename _CharT, typename _Traits, typename _Allocator>
924     inline bool
925     operator>=(const _CharT* __lhs,
926                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
927     {
928       __glibcxx_check_string(__lhs);
929       return __lhs >= __rhs._M_base();
930     }
931
932   template<typename _CharT, typename _Traits, typename _Allocator>
933     inline bool
934     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
935                const _CharT* __rhs)
936     {
937       __glibcxx_check_string(__rhs);
938       return __lhs._M_base() >= __rhs;
939     }
940
941   template<typename _CharT, typename _Traits, typename _Allocator>
942     inline bool
943     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
944               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
945     { return __lhs._M_base() > __rhs._M_base(); }
946
947   template<typename _CharT, typename _Traits, typename _Allocator>
948     inline bool
949     operator>(const _CharT* __lhs,
950               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
951     {
952       __glibcxx_check_string(__lhs);
953       return __lhs > __rhs._M_base();
954     }
955
956   template<typename _CharT, typename _Traits, typename _Allocator>
957     inline bool
958     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
959               const _CharT* __rhs)
960     {
961       __glibcxx_check_string(__rhs);
962       return __lhs._M_base() > __rhs;
963     }
964
965   // 21.3.7.8:
966   template<typename _CharT, typename _Traits, typename _Allocator>
967     inline void
968     swap(basic_string<_CharT,_Traits,_Allocator>& __lhs,
969          basic_string<_CharT,_Traits,_Allocator>& __rhs)
970     { __lhs.swap(__rhs); }
971
972   template<typename _CharT, typename _Traits, typename _Allocator>
973     std::basic_ostream<_CharT, _Traits>&
974     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
975                const basic_string<_CharT, _Traits, _Allocator>& __str)
976     { return __os << __str._M_base(); }
977
978   template<typename _CharT, typename _Traits, typename _Allocator>
979     std::basic_istream<_CharT,_Traits>&
980     operator>>(std::basic_istream<_CharT,_Traits>& __is,
981                basic_string<_CharT,_Traits,_Allocator>& __str)
982     {
983       std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
984       __str._M_invalidate_all();
985       return __res;
986     }
987
988   template<typename _CharT, typename _Traits, typename _Allocator>
989     std::basic_istream<_CharT,_Traits>&
990     getline(std::basic_istream<_CharT,_Traits>& __is,
991             basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
992     {
993       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
994                                                           __str._M_base(),
995                                                         __delim);
996       __str._M_invalidate_all();
997       return __res;
998     }
999
1000   template<typename _CharT, typename _Traits, typename _Allocator>
1001     std::basic_istream<_CharT,_Traits>&
1002     getline(std::basic_istream<_CharT,_Traits>& __is,
1003             basic_string<_CharT,_Traits,_Allocator>& __str)
1004     {
1005       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
1006                                                           __str._M_base());
1007       __str._M_invalidate_all();
1008       return __res;
1009     }
1010
1011   typedef basic_string<char>    string;
1012
1013 #ifdef _GLIBCXX_USE_WCHAR_T
1014   typedef basic_string<wchar_t> wstring;
1015 #endif
1016
1017 } // namespace __gnu_debug
1018
1019 #endif