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