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