]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/libstdc++/include/debug/string
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / libstdc++ / 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 /** @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
42 namespace __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