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