libstdc++
debug/string
Go to the documentation of this file.
00001 // Debugging string implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
00004 // Free Software Foundation, Inc.
00005 //
00006 // This file is part of the GNU ISO C++ Library.  This library is free
00007 // software; you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the
00009 // Free Software Foundation; either version 3, or (at your option)
00010 // any later version.
00011 
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 
00017 // Under Section 7 of GPL version 3, you are granted additional
00018 // permissions described in the GCC Runtime Library Exception, version
00019 // 3.1, as published by the Free Software Foundation.
00020 
00021 // You should have received a copy of the GNU General Public License and
00022 // a copy of the GCC Runtime Library Exception along with this program;
00023 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00024 // <http://www.gnu.org/licenses/>.
00025 
00026 /** @file debug/string
00027  *  This file is a GNU debug extension to the Standard C++ Library.
00028  */
00029 
00030 #ifndef _GLIBCXX_DEBUG_STRING
00031 #define _GLIBCXX_DEBUG_STRING 1
00032 
00033 #include <string>
00034 #include <debug/safe_sequence.h>
00035 #include <debug/safe_iterator.h>
00036 
00037 namespace __gnu_debug
00038 {
00039   /// Class std::basic_string with safety/checking/debug instrumentation.
00040   template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
00041             typename _Allocator = std::allocator<_CharT> >
00042     class basic_string
00043     : public std::basic_string<_CharT, _Traits, _Allocator>,
00044       public __gnu_debug::_Safe_sequence<basic_string<_CharT, _Traits,
00045                               _Allocator> >
00046     {
00047       typedef std::basic_string<_CharT, _Traits, _Allocator> _Base;
00048       typedef __gnu_debug::_Safe_sequence<basic_string>     _Safe_base;
00049 
00050   public:
00051     // types:
00052     typedef _Traits                    traits_type;
00053     typedef typename _Traits::char_type            value_type;
00054     typedef _Allocator                     allocator_type;
00055     typedef typename _Base::size_type                  size_type;
00056     typedef typename _Base::difference_type            difference_type;
00057     typedef typename _Base::reference                  reference;
00058     typedef typename _Base::const_reference            const_reference;
00059     typedef typename _Base::pointer                    pointer;
00060     typedef typename _Base::const_pointer              const_pointer;
00061 
00062     typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, basic_string>
00063                                                        iterator;
00064     typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,
00065                                          basic_string> const_iterator;
00066 
00067     typedef std::reverse_iterator<iterator>            reverse_iterator;
00068     typedef std::reverse_iterator<const_iterator>      const_reverse_iterator;
00069 
00070     using _Base::npos;
00071 
00072     // 21.3.1 construct/copy/destroy:
00073     explicit basic_string(const _Allocator& __a = _Allocator())
00074     : _Base(__a)
00075     { }
00076 
00077     // Provides conversion from a release-mode string to a debug-mode string
00078     basic_string(const _Base& __base) : _Base(__base) { }
00079 
00080     // _GLIBCXX_RESOLVE_LIB_DEFECTS
00081     // 42. string ctors specify wrong default allocator
00082     basic_string(const basic_string& __str)
00083     : _Base(__str, 0, _Base::npos, __str.get_allocator())
00084     { }
00085 
00086     // _GLIBCXX_RESOLVE_LIB_DEFECTS
00087     // 42. string ctors specify wrong default allocator
00088     basic_string(const basic_string& __str, size_type __pos,
00089            size_type __n = _Base::npos,
00090            const _Allocator& __a = _Allocator())
00091     : _Base(__str, __pos, __n, __a)
00092     { }
00093 
00094     basic_string(const _CharT* __s, size_type __n,
00095            const _Allocator& __a = _Allocator())
00096     : _Base(__gnu_debug::__check_string(__s, __n), __n, __a)
00097     { }
00098 
00099     basic_string(const _CharT* __s, const _Allocator& __a = _Allocator())
00100     : _Base(__gnu_debug::__check_string(__s), __a)
00101     { this->assign(__s); }
00102 
00103     basic_string(size_type __n, _CharT __c,
00104            const _Allocator& __a = _Allocator())
00105     : _Base(__n, __c, __a)
00106     { }
00107 
00108     template<typename _InputIterator>
00109       basic_string(_InputIterator __begin, _InputIterator __end,
00110            const _Allocator& __a = _Allocator())
00111       : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__begin,
00112                                    __end)),
00113           __gnu_debug::__base(__end), __a)
00114       { }
00115 
00116 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00117     basic_string(basic_string&& __str) noexcept
00118     : _Base(std::move(__str))
00119     { }
00120 
00121     basic_string(std::initializer_list<_CharT> __l,
00122          const _Allocator& __a = _Allocator())
00123     : _Base(__l, __a)
00124     { }
00125 #endif // __GXX_EXPERIMENTAL_CXX0X__
00126 
00127     ~basic_string() _GLIBCXX_NOEXCEPT { }
00128 
00129     basic_string&
00130     operator=(const basic_string& __str)
00131     {
00132       *static_cast<_Base*>(this) = __str;
00133       this->_M_invalidate_all();
00134       return *this;
00135     }
00136 
00137     basic_string&
00138     operator=(const _CharT* __s)
00139     {
00140       __glibcxx_check_string(__s);
00141       *static_cast<_Base*>(this) = __s;
00142       this->_M_invalidate_all();
00143       return *this;
00144     }
00145 
00146     basic_string&
00147     operator=(_CharT __c)
00148     {
00149       *static_cast<_Base*>(this) = __c;
00150       this->_M_invalidate_all();
00151       return *this;
00152     }
00153 
00154 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00155     basic_string&
00156     operator=(basic_string&& __str)
00157     {
00158       *static_cast<_Base*>(this) = std::move(__str);
00159       this->_M_invalidate_all();
00160       return *this;
00161     }
00162 
00163     basic_string&
00164     operator=(std::initializer_list<_CharT> __l)
00165     {
00166       *static_cast<_Base*>(this) = __l;
00167       this->_M_invalidate_all();
00168       return *this;
00169     }
00170 #endif // __GXX_EXPERIMENTAL_CXX0X__
00171 
00172     // 21.3.2 iterators:
00173     iterator
00174     begin() _GLIBCXX_NOEXCEPT
00175     { return iterator(_Base::begin(), this); }
00176 
00177     const_iterator
00178     begin() const _GLIBCXX_NOEXCEPT
00179     { return const_iterator(_Base::begin(), this); }
00180 
00181     iterator
00182     end() _GLIBCXX_NOEXCEPT
00183     { return iterator(_Base::end(), this); }
00184 
00185     const_iterator
00186     end() const _GLIBCXX_NOEXCEPT
00187     { return const_iterator(_Base::end(), this); }
00188 
00189     reverse_iterator
00190     rbegin() _GLIBCXX_NOEXCEPT
00191     { return reverse_iterator(end()); }
00192 
00193     const_reverse_iterator
00194     rbegin() const _GLIBCXX_NOEXCEPT
00195     { return const_reverse_iterator(end()); }
00196 
00197     reverse_iterator
00198     rend() _GLIBCXX_NOEXCEPT
00199     { return reverse_iterator(begin()); }
00200 
00201     const_reverse_iterator
00202     rend() const _GLIBCXX_NOEXCEPT
00203     { return const_reverse_iterator(begin()); }
00204 
00205 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00206     const_iterator
00207     cbegin() const noexcept
00208     { return const_iterator(_Base::begin(), this); }
00209 
00210     const_iterator
00211     cend() const noexcept
00212     { return const_iterator(_Base::end(), this); }
00213 
00214     const_reverse_iterator
00215     crbegin() const noexcept
00216     { return const_reverse_iterator(end()); }
00217 
00218     const_reverse_iterator
00219     crend() const noexcept
00220     { return const_reverse_iterator(begin()); }
00221 #endif
00222 
00223     // 21.3.3 capacity:
00224     using _Base::size;
00225     using _Base::length;
00226     using _Base::max_size;
00227 
00228     void
00229     resize(size_type __n, _CharT __c)
00230     {
00231       _Base::resize(__n, __c);
00232       this->_M_invalidate_all();
00233     }
00234 
00235     void
00236     resize(size_type __n)
00237     { this->resize(__n, _CharT()); }
00238 
00239 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00240     void
00241     shrink_to_fit()
00242     {
00243       if (capacity() > size())
00244     {
00245       __try
00246         {
00247           reserve(0);
00248           this->_M_invalidate_all();
00249         }
00250       __catch(...)
00251         { }
00252     }
00253     }
00254 #endif
00255 
00256     using _Base::capacity;
00257     using _Base::reserve;
00258 
00259     void
00260     clear() _GLIBCXX_NOEXCEPT
00261     {
00262       _Base::clear();
00263       this->_M_invalidate_all();
00264     }
00265 
00266     using _Base::empty;
00267 
00268     // 21.3.4 element access:
00269     const_reference
00270     operator[](size_type __pos) const
00271     {
00272       _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
00273                 _M_message(__gnu_debug::__msg_subscript_oob)
00274                 ._M_sequence(*this, "this")
00275                 ._M_integer(__pos, "__pos")
00276                 ._M_integer(this->size(), "size"));
00277       return _M_base()[__pos];
00278     }
00279 
00280     reference
00281     operator[](size_type __pos)
00282     {
00283 #ifdef _GLIBCXX_DEBUG_PEDANTIC
00284       __glibcxx_check_subscript(__pos);
00285 #else
00286       // as an extension v3 allows s[s.size()] when s is non-const.
00287       _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
00288                 _M_message(__gnu_debug::__msg_subscript_oob)
00289                 ._M_sequence(*this, "this")
00290                 ._M_integer(__pos, "__pos")
00291                 ._M_integer(this->size(), "size"));
00292 #endif
00293       return _M_base()[__pos];
00294     }
00295 
00296     using _Base::at;
00297 
00298 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00299     using _Base::front;
00300     using _Base::back;
00301 #endif
00302 
00303     // 21.3.5 modifiers:
00304     basic_string&
00305     operator+=(const basic_string& __str)
00306     {
00307       _M_base() += __str;
00308       this->_M_invalidate_all();
00309       return *this;
00310     }
00311 
00312     basic_string&
00313     operator+=(const _CharT* __s)
00314     {
00315       __glibcxx_check_string(__s);
00316       _M_base() += __s;
00317       this->_M_invalidate_all();
00318       return *this;
00319     }
00320 
00321     basic_string&
00322     operator+=(_CharT __c)
00323     {
00324       _M_base() += __c;
00325       this->_M_invalidate_all();
00326       return *this;
00327     }
00328 
00329 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00330     basic_string&
00331     operator+=(std::initializer_list<_CharT> __l)
00332     {
00333       _M_base() += __l;
00334       this->_M_invalidate_all();
00335       return *this;
00336     }
00337 #endif // __GXX_EXPERIMENTAL_CXX0X__
00338 
00339     basic_string&
00340     append(const basic_string& __str)
00341     {
00342       _Base::append(__str);
00343       this->_M_invalidate_all();
00344       return *this;
00345     }
00346 
00347     basic_string&
00348     append(const basic_string& __str, size_type __pos, size_type __n)
00349     {
00350       _Base::append(__str, __pos, __n);
00351       this->_M_invalidate_all();
00352       return *this;
00353     }
00354 
00355     basic_string&
00356     append(const _CharT* __s, size_type __n)
00357     {
00358       __glibcxx_check_string_len(__s, __n);
00359       _Base::append(__s, __n);
00360       this->_M_invalidate_all();
00361       return *this;
00362     }
00363 
00364     basic_string&
00365     append(const _CharT* __s)
00366     {
00367       __glibcxx_check_string(__s);
00368       _Base::append(__s);
00369       this->_M_invalidate_all();
00370       return *this;
00371     }
00372 
00373     basic_string&
00374     append(size_type __n, _CharT __c)
00375     {
00376       _Base::append(__n, __c);
00377       this->_M_invalidate_all();
00378       return *this;
00379     }
00380 
00381     template<typename _InputIterator>
00382       basic_string&
00383       append(_InputIterator __first, _InputIterator __last)
00384       {
00385     __glibcxx_check_valid_range(__first, __last);
00386     _Base::append(__gnu_debug::__base(__first),
00387               __gnu_debug::__base(__last));
00388     this->_M_invalidate_all();
00389     return *this;
00390       }
00391 
00392     // _GLIBCXX_RESOLVE_LIB_DEFECTS
00393     // 7. string clause minor problems
00394     void
00395     push_back(_CharT __c)
00396     {
00397       _Base::push_back(__c);
00398       this->_M_invalidate_all();
00399     }
00400 
00401     basic_string&
00402     assign(const basic_string& __x)
00403     {
00404       _Base::assign(__x);
00405       this->_M_invalidate_all();
00406       return *this;
00407     }
00408 
00409 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00410     basic_string&
00411     assign(basic_string&& __x)
00412     {
00413       _Base::assign(std::move(__x));
00414       this->_M_invalidate_all();
00415       return *this;
00416     }
00417 #endif // __GXX_EXPERIMENTAL_CXX0X__
00418 
00419     basic_string&
00420     assign(const basic_string& __str, size_type __pos, size_type __n)
00421     {
00422       _Base::assign(__str, __pos, __n);
00423       this->_M_invalidate_all();
00424       return *this;
00425     }
00426 
00427     basic_string&
00428     assign(const _CharT* __s, size_type __n)
00429     {
00430       __glibcxx_check_string_len(__s, __n);
00431       _Base::assign(__s, __n);
00432       this->_M_invalidate_all();
00433       return *this;
00434     }
00435 
00436     basic_string&
00437     assign(const _CharT* __s)
00438     {
00439       __glibcxx_check_string(__s);
00440       _Base::assign(__s);
00441       this->_M_invalidate_all();
00442       return *this;
00443     }
00444 
00445     basic_string&
00446     assign(size_type __n, _CharT __c)
00447     {
00448       _Base::assign(__n, __c);
00449       this->_M_invalidate_all();
00450       return *this;
00451     }
00452 
00453     template<typename _InputIterator>
00454       basic_string&
00455       assign(_InputIterator __first, _InputIterator __last)
00456       {
00457     __glibcxx_check_valid_range(__first, __last);
00458     _Base::assign(__gnu_debug::__base(__first),
00459               __gnu_debug::__base(__last));
00460     this->_M_invalidate_all();
00461     return *this;
00462       }
00463 
00464 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00465     basic_string&
00466     assign(std::initializer_list<_CharT> __l)
00467     {
00468       _Base::assign(__l);
00469       this->_M_invalidate_all();
00470       return *this;
00471     }
00472 #endif // __GXX_EXPERIMENTAL_CXX0X__
00473 
00474     basic_string&
00475     insert(size_type __pos1, const basic_string& __str)
00476     {
00477       _Base::insert(__pos1, __str);
00478       this->_M_invalidate_all();
00479       return *this;
00480     }
00481 
00482     basic_string&
00483     insert(size_type __pos1, const basic_string& __str,
00484        size_type __pos2, size_type __n)
00485     {
00486       _Base::insert(__pos1, __str, __pos2, __n);
00487       this->_M_invalidate_all();
00488       return *this;
00489     }
00490 
00491     basic_string&
00492     insert(size_type __pos, const _CharT* __s, size_type __n)
00493     {
00494       __glibcxx_check_string(__s);
00495       _Base::insert(__pos, __s, __n);
00496       this->_M_invalidate_all();
00497       return *this;
00498     }
00499 
00500     basic_string&
00501     insert(size_type __pos, const _CharT* __s)
00502     {
00503       __glibcxx_check_string(__s);
00504       _Base::insert(__pos, __s);
00505       this->_M_invalidate_all();
00506       return *this;
00507     }
00508 
00509     basic_string&
00510     insert(size_type __pos, size_type __n, _CharT __c)
00511     {
00512       _Base::insert(__pos, __n, __c);
00513       this->_M_invalidate_all();
00514       return *this;
00515     }
00516 
00517     iterator
00518     insert(iterator __p, _CharT __c)
00519     {
00520       __glibcxx_check_insert(__p);
00521       typename _Base::iterator __res = _Base::insert(__p.base(), __c);
00522       this->_M_invalidate_all();
00523       return iterator(__res, this);
00524     }
00525 
00526     void
00527     insert(iterator __p, size_type __n, _CharT __c)
00528     {
00529       __glibcxx_check_insert(__p);
00530       _Base::insert(__p.base(), __n, __c);
00531       this->_M_invalidate_all();
00532     }
00533 
00534     template<typename _InputIterator>
00535       void
00536       insert(iterator __p, _InputIterator __first, _InputIterator __last)
00537       {
00538     __glibcxx_check_insert_range(__p, __first, __last);
00539     _Base::insert(__p.base(), __gnu_debug::__base(__first),
00540                   __gnu_debug::__base(__last));
00541     this->_M_invalidate_all();
00542       }
00543 
00544 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00545     void
00546     insert(iterator __p, std::initializer_list<_CharT> __l)
00547     {
00548       __glibcxx_check_insert(__p);
00549       _Base::insert(__p.base(), __l);
00550       this->_M_invalidate_all();
00551     }
00552 #endif // __GXX_EXPERIMENTAL_CXX0X__
00553 
00554     basic_string&
00555     erase(size_type __pos = 0, size_type __n = _Base::npos)
00556     {
00557       _Base::erase(__pos, __n);
00558       this->_M_invalidate_all();
00559       return *this;
00560     }
00561 
00562     iterator
00563     erase(iterator __position)
00564     {
00565       __glibcxx_check_erase(__position);
00566       typename _Base::iterator __res = _Base::erase(__position.base());
00567       this->_M_invalidate_all();
00568       return iterator(__res, this);
00569     }
00570 
00571     iterator
00572     erase(iterator __first, iterator __last)
00573     {
00574       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00575       // 151. can't currently clear() empty container
00576       __glibcxx_check_erase_range(__first, __last);
00577       typename _Base::iterator __res = _Base::erase(__first.base(),
00578                                __last.base());
00579       this->_M_invalidate_all();
00580       return iterator(__res, this);
00581     }
00582 
00583 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00584     void
00585     pop_back()
00586     {
00587       __glibcxx_check_nonempty();
00588       _Base::pop_back();
00589       this->_M_invalidate_all();
00590     }
00591 #endif // __GXX_EXPERIMENTAL_CXX0X__
00592 
00593     basic_string&
00594     replace(size_type __pos1, size_type __n1, const basic_string& __str)
00595     {
00596       _Base::replace(__pos1, __n1, __str);
00597       this->_M_invalidate_all();
00598       return *this;
00599     }
00600 
00601     basic_string&
00602     replace(size_type __pos1, size_type __n1, const basic_string& __str,
00603         size_type __pos2, size_type __n2)
00604     {
00605       _Base::replace(__pos1, __n1, __str, __pos2, __n2);
00606       this->_M_invalidate_all();
00607       return *this;
00608     }
00609 
00610     basic_string&
00611     replace(size_type __pos, size_type __n1, const _CharT* __s,
00612         size_type __n2)
00613     {
00614       __glibcxx_check_string_len(__s, __n2);
00615       _Base::replace(__pos, __n1, __s, __n2);
00616       this->_M_invalidate_all();
00617       return *this;
00618     }
00619 
00620     basic_string&
00621     replace(size_type __pos, size_type __n1, const _CharT* __s)
00622     {
00623       __glibcxx_check_string(__s);
00624       _Base::replace(__pos, __n1, __s);
00625       this->_M_invalidate_all();
00626       return *this;
00627     }
00628 
00629     basic_string&
00630     replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
00631     {
00632       _Base::replace(__pos, __n1, __n2, __c);
00633       this->_M_invalidate_all();
00634       return *this;
00635     }
00636 
00637     basic_string&
00638     replace(iterator __i1, iterator __i2, const basic_string& __str)
00639     {
00640       __glibcxx_check_erase_range(__i1, __i2);
00641       _Base::replace(__i1.base(), __i2.base(), __str);
00642       this->_M_invalidate_all();
00643       return *this;
00644     }
00645 
00646     basic_string&
00647     replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
00648     {
00649       __glibcxx_check_erase_range(__i1, __i2);
00650       __glibcxx_check_string_len(__s, __n);
00651       _Base::replace(__i1.base(), __i2.base(), __s, __n);
00652       this->_M_invalidate_all();
00653       return *this;
00654     }
00655 
00656     basic_string&
00657     replace(iterator __i1, iterator __i2, const _CharT* __s)
00658     {
00659       __glibcxx_check_erase_range(__i1, __i2);
00660       __glibcxx_check_string(__s);
00661       _Base::replace(__i1.base(), __i2.base(), __s);
00662       this->_M_invalidate_all();
00663       return *this;
00664     }
00665 
00666     basic_string&
00667     replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
00668     {
00669       __glibcxx_check_erase_range(__i1, __i2);
00670       _Base::replace(__i1.base(), __i2.base(), __n, __c);
00671       this->_M_invalidate_all();
00672       return *this;
00673     }
00674 
00675     template<typename _InputIterator>
00676       basic_string&
00677       replace(iterator __i1, iterator __i2,
00678           _InputIterator __j1, _InputIterator __j2)
00679       {
00680     __glibcxx_check_erase_range(__i1, __i2);
00681     __glibcxx_check_valid_range(__j1, __j2);
00682     _Base::replace(__i1.base(), __i2.base(), __j1, __j2);
00683     this->_M_invalidate_all();
00684     return *this;
00685       }
00686 
00687 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00688       basic_string& replace(iterator __i1, iterator __i2,
00689                 std::initializer_list<_CharT> __l)
00690       {
00691     __glibcxx_check_erase_range(__i1, __i2);
00692     _Base::replace(__i1.base(), __i2.base(), __l);
00693     this->_M_invalidate_all();
00694     return *this;
00695       }
00696 #endif // __GXX_EXPERIMENTAL_CXX0X__
00697 
00698     size_type
00699     copy(_CharT* __s, size_type __n, size_type __pos = 0) const
00700     {
00701       __glibcxx_check_string_len(__s, __n);
00702       return _Base::copy(__s, __n, __pos);
00703     }
00704 
00705     void
00706     swap(basic_string<_CharT,_Traits,_Allocator>& __x)
00707     {
00708       _Base::swap(__x);
00709       this->_M_swap(__x);
00710       this->_M_invalidate_all();
00711       __x._M_invalidate_all();
00712     }
00713 
00714     // 21.3.6 string operations:
00715     const _CharT*
00716     c_str() const _GLIBCXX_NOEXCEPT
00717     {
00718       const _CharT* __res = _Base::c_str();
00719       this->_M_invalidate_all();
00720       return __res;
00721     }
00722 
00723     const _CharT*
00724     data() const _GLIBCXX_NOEXCEPT
00725     {
00726       const _CharT* __res = _Base::data();
00727       this->_M_invalidate_all();
00728       return __res;
00729     }
00730 
00731     using _Base::get_allocator;
00732 
00733     size_type
00734     find(const basic_string& __str, size_type __pos = 0) const
00735       _GLIBCXX_NOEXCEPT
00736     { return _Base::find(__str, __pos); }
00737 
00738     size_type
00739     find(const _CharT* __s, size_type __pos, size_type __n) const
00740     {
00741       __glibcxx_check_string(__s);
00742       return _Base::find(__s, __pos, __n);
00743     }
00744 
00745     size_type
00746     find(const _CharT* __s, size_type __pos = 0) const
00747     {
00748       __glibcxx_check_string(__s);
00749       return _Base::find(__s, __pos);
00750     }
00751 
00752     size_type
00753     find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
00754     { return _Base::find(__c, __pos); }
00755 
00756     size_type
00757     rfind(const basic_string& __str, size_type __pos = _Base::npos) const
00758       _GLIBCXX_NOEXCEPT
00759     { return _Base::rfind(__str, __pos); }
00760 
00761     size_type
00762     rfind(const _CharT* __s, size_type __pos, size_type __n) const
00763     {
00764       __glibcxx_check_string_len(__s, __n);
00765       return _Base::rfind(__s, __pos, __n);
00766     }
00767 
00768     size_type
00769     rfind(const _CharT* __s, size_type __pos = _Base::npos) const
00770     {
00771       __glibcxx_check_string(__s);
00772       return _Base::rfind(__s, __pos);
00773     }
00774 
00775     size_type
00776     rfind(_CharT __c, size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
00777     { return _Base::rfind(__c, __pos); }
00778 
00779     size_type
00780     find_first_of(const basic_string& __str, size_type __pos = 0) const
00781       _GLIBCXX_NOEXCEPT
00782     { return _Base::find_first_of(__str, __pos); }
00783 
00784     size_type
00785     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
00786     {
00787       __glibcxx_check_string(__s);
00788       return _Base::find_first_of(__s, __pos, __n);
00789     }
00790 
00791     size_type
00792     find_first_of(const _CharT* __s, size_type __pos = 0) const
00793     {
00794       __glibcxx_check_string(__s);
00795       return _Base::find_first_of(__s, __pos);
00796     }
00797 
00798     size_type
00799     find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
00800     { return _Base::find_first_of(__c, __pos); }
00801 
00802     size_type
00803     find_last_of(const basic_string& __str, 
00804          size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
00805     { return _Base::find_last_of(__str, __pos); }
00806 
00807     size_type
00808     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
00809     {
00810       __glibcxx_check_string(__s);
00811       return _Base::find_last_of(__s, __pos, __n);
00812     }
00813 
00814     size_type
00815     find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
00816     {
00817       __glibcxx_check_string(__s);
00818       return _Base::find_last_of(__s, __pos);
00819     }
00820 
00821     size_type
00822     find_last_of(_CharT __c, size_type __pos = _Base::npos) const
00823       _GLIBCXX_NOEXCEPT
00824     { return _Base::find_last_of(__c, __pos); }
00825 
00826     size_type
00827     find_first_not_of(const basic_string& __str, size_type __pos = 0) const
00828       _GLIBCXX_NOEXCEPT
00829     { return _Base::find_first_not_of(__str, __pos); }
00830 
00831     size_type
00832     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00833     {
00834       __glibcxx_check_string_len(__s, __n);
00835       return _Base::find_first_not_of(__s, __pos, __n);
00836     }
00837 
00838     size_type
00839     find_first_not_of(const _CharT* __s, size_type __pos = 0) const
00840     {
00841       __glibcxx_check_string(__s);
00842       return _Base::find_first_not_of(__s, __pos);
00843     }
00844 
00845     size_type
00846     find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
00847     { return _Base::find_first_not_of(__c, __pos); }
00848 
00849     size_type
00850     find_last_not_of(const basic_string& __str,
00851                   size_type __pos = _Base::npos) const
00852       _GLIBCXX_NOEXCEPT
00853     { return _Base::find_last_not_of(__str, __pos); }
00854 
00855     size_type
00856     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00857     {
00858       __glibcxx_check_string(__s);
00859       return _Base::find_last_not_of(__s, __pos, __n);
00860     }
00861 
00862     size_type
00863     find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
00864     {
00865       __glibcxx_check_string(__s);
00866       return _Base::find_last_not_of(__s, __pos);
00867     }
00868 
00869     size_type
00870     find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const
00871       _GLIBCXX_NOEXCEPT
00872     { return _Base::find_last_not_of(__c, __pos); }
00873 
00874     basic_string
00875     substr(size_type __pos = 0, size_type __n = _Base::npos) const
00876     { return basic_string(_Base::substr(__pos, __n)); }
00877 
00878     int
00879     compare(const basic_string& __str) const
00880     { return _Base::compare(__str); }
00881 
00882     int
00883     compare(size_type __pos1, size_type __n1,
00884           const basic_string& __str) const
00885     { return _Base::compare(__pos1, __n1, __str); }
00886 
00887     int
00888     compare(size_type __pos1, size_type __n1, const basic_string& __str,
00889           size_type __pos2, size_type __n2) const
00890     { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); }
00891 
00892     int
00893     compare(const _CharT* __s) const
00894     {
00895       __glibcxx_check_string(__s);
00896       return _Base::compare(__s);
00897     }
00898 
00899     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
00900     //  5. string::compare specification questionable
00901     int
00902     compare(size_type __pos1, size_type __n1, const _CharT* __s) const
00903     {
00904       __glibcxx_check_string(__s);
00905       return _Base::compare(__pos1, __n1, __s);
00906     }
00907 
00908     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
00909     //  5. string::compare specification questionable
00910     int
00911     compare(size_type __pos1, size_type __n1,const _CharT* __s,
00912           size_type __n2) const
00913     {
00914       __glibcxx_check_string_len(__s, __n2);
00915       return _Base::compare(__pos1, __n1, __s, __n2);
00916     }
00917 
00918     _Base&
00919     _M_base() _GLIBCXX_NOEXCEPT       { return *this; }
00920 
00921     const _Base&
00922     _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
00923 
00924     using _Safe_base::_M_invalidate_all;
00925   };
00926 
00927   template<typename _CharT, typename _Traits, typename _Allocator>
00928     inline basic_string<_CharT,_Traits,_Allocator>
00929     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00930           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00931     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
00932 
00933   template<typename _CharT, typename _Traits, typename _Allocator>
00934     inline basic_string<_CharT,_Traits,_Allocator>
00935     operator+(const _CharT* __lhs,
00936           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00937     {
00938       __glibcxx_check_string(__lhs);
00939       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
00940     }
00941 
00942   template<typename _CharT, typename _Traits, typename _Allocator>
00943     inline basic_string<_CharT,_Traits,_Allocator>
00944     operator+(_CharT __lhs,
00945           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00946     { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; }
00947 
00948   template<typename _CharT, typename _Traits, typename _Allocator>
00949     inline basic_string<_CharT,_Traits,_Allocator>
00950     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00951           const _CharT* __rhs)
00952     {
00953       __glibcxx_check_string(__rhs);
00954       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
00955     }
00956 
00957   template<typename _CharT, typename _Traits, typename _Allocator>
00958     inline basic_string<_CharT,_Traits,_Allocator>
00959     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00960           _CharT __rhs)
00961     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
00962 
00963   template<typename _CharT, typename _Traits, typename _Allocator>
00964     inline bool
00965     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00966            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00967     { return __lhs._M_base() == __rhs._M_base(); }
00968 
00969   template<typename _CharT, typename _Traits, typename _Allocator>
00970     inline bool
00971     operator==(const _CharT* __lhs,
00972            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00973     {
00974       __glibcxx_check_string(__lhs);
00975       return __lhs == __rhs._M_base();
00976     }
00977 
00978   template<typename _CharT, typename _Traits, typename _Allocator>
00979     inline bool
00980     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00981            const _CharT* __rhs)
00982     {
00983       __glibcxx_check_string(__rhs);
00984       return __lhs._M_base() == __rhs;
00985     }
00986 
00987   template<typename _CharT, typename _Traits, typename _Allocator>
00988     inline bool
00989     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00990            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00991     { return __lhs._M_base() != __rhs._M_base(); }
00992 
00993   template<typename _CharT, typename _Traits, typename _Allocator>
00994     inline bool
00995     operator!=(const _CharT* __lhs,
00996            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00997     {
00998       __glibcxx_check_string(__lhs);
00999       return __lhs != __rhs._M_base();
01000     }
01001 
01002   template<typename _CharT, typename _Traits, typename _Allocator>
01003     inline bool
01004     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01005            const _CharT* __rhs)
01006     {
01007       __glibcxx_check_string(__rhs);
01008       return __lhs._M_base() != __rhs;
01009     }
01010 
01011   template<typename _CharT, typename _Traits, typename _Allocator>
01012     inline bool
01013     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01014           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01015     { return __lhs._M_base() < __rhs._M_base(); }
01016 
01017   template<typename _CharT, typename _Traits, typename _Allocator>
01018     inline bool
01019     operator<(const _CharT* __lhs,
01020           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01021     {
01022       __glibcxx_check_string(__lhs);
01023       return __lhs < __rhs._M_base();
01024     }
01025 
01026   template<typename _CharT, typename _Traits, typename _Allocator>
01027     inline bool
01028     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01029           const _CharT* __rhs)
01030     {
01031       __glibcxx_check_string(__rhs);
01032       return __lhs._M_base() < __rhs;
01033     }
01034 
01035   template<typename _CharT, typename _Traits, typename _Allocator>
01036     inline bool
01037     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01038            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01039     { return __lhs._M_base() <= __rhs._M_base(); }
01040 
01041   template<typename _CharT, typename _Traits, typename _Allocator>
01042     inline bool
01043     operator<=(const _CharT* __lhs,
01044            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01045     {
01046       __glibcxx_check_string(__lhs);
01047       return __lhs <= __rhs._M_base();
01048     }
01049 
01050   template<typename _CharT, typename _Traits, typename _Allocator>
01051     inline bool
01052     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01053            const _CharT* __rhs)
01054     {
01055       __glibcxx_check_string(__rhs);
01056       return __lhs._M_base() <= __rhs;
01057     }
01058 
01059   template<typename _CharT, typename _Traits, typename _Allocator>
01060     inline bool
01061     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01062            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01063     { return __lhs._M_base() >= __rhs._M_base(); }
01064 
01065   template<typename _CharT, typename _Traits, typename _Allocator>
01066     inline bool
01067     operator>=(const _CharT* __lhs,
01068            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01069     {
01070       __glibcxx_check_string(__lhs);
01071       return __lhs >= __rhs._M_base();
01072     }
01073 
01074   template<typename _CharT, typename _Traits, typename _Allocator>
01075     inline bool
01076     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01077            const _CharT* __rhs)
01078     {
01079       __glibcxx_check_string(__rhs);
01080       return __lhs._M_base() >= __rhs;
01081     }
01082 
01083   template<typename _CharT, typename _Traits, typename _Allocator>
01084     inline bool
01085     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01086           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01087     { return __lhs._M_base() > __rhs._M_base(); }
01088 
01089   template<typename _CharT, typename _Traits, typename _Allocator>
01090     inline bool
01091     operator>(const _CharT* __lhs,
01092           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01093     {
01094       __glibcxx_check_string(__lhs);
01095       return __lhs > __rhs._M_base();
01096     }
01097 
01098   template<typename _CharT, typename _Traits, typename _Allocator>
01099     inline bool
01100     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01101           const _CharT* __rhs)
01102     {
01103       __glibcxx_check_string(__rhs);
01104       return __lhs._M_base() > __rhs;
01105     }
01106 
01107   // 21.3.7.8:
01108   template<typename _CharT, typename _Traits, typename _Allocator>
01109     inline void
01110     swap(basic_string<_CharT,_Traits,_Allocator>& __lhs,
01111      basic_string<_CharT,_Traits,_Allocator>& __rhs)
01112     { __lhs.swap(__rhs); }
01113 
01114   template<typename _CharT, typename _Traits, typename _Allocator>
01115     std::basic_ostream<_CharT, _Traits>&
01116     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01117            const basic_string<_CharT, _Traits, _Allocator>& __str)
01118     { return __os << __str._M_base(); }
01119 
01120   template<typename _CharT, typename _Traits, typename _Allocator>
01121     std::basic_istream<_CharT,_Traits>&
01122     operator>>(std::basic_istream<_CharT,_Traits>& __is,
01123            basic_string<_CharT,_Traits,_Allocator>& __str)
01124     {
01125       std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
01126       __str._M_invalidate_all();
01127       return __res;
01128     }
01129 
01130   template<typename _CharT, typename _Traits, typename _Allocator>
01131     std::basic_istream<_CharT,_Traits>&
01132     getline(std::basic_istream<_CharT,_Traits>& __is,
01133         basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
01134     {
01135       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
01136                               __str._M_base(),
01137                             __delim);
01138       __str._M_invalidate_all();
01139       return __res;
01140     }
01141 
01142   template<typename _CharT, typename _Traits, typename _Allocator>
01143     std::basic_istream<_CharT,_Traits>&
01144     getline(std::basic_istream<_CharT,_Traits>& __is,
01145         basic_string<_CharT,_Traits,_Allocator>& __str)
01146     {
01147       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
01148                               __str._M_base());
01149       __str._M_invalidate_all();
01150       return __res;
01151     }
01152 
01153   typedef basic_string<char>    string;
01154 
01155 #ifdef _GLIBCXX_USE_WCHAR_T
01156   typedef basic_string<wchar_t> wstring;
01157 #endif
01158 
01159 } // namespace __gnu_debug
01160 
01161 #endif