OSDN Git Service

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