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