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