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
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), _Safe_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()), _Safe_base()
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::__check_valid_range(__begin, __end), __end, __a)
00112       { }
00113 
00114 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00115     basic_string(basic_string&& __str)
00116     : _Base(std::forward<_Base>(__str))
00117     { }
00118 
00119     basic_string(std::initializer_list<_CharT> __l,
00120          const _Allocator& __a = _Allocator())
00121     : _Base(__l, __a)
00122     { }
00123 #endif // __GXX_EXPERIMENTAL_CXX0X__
00124 
00125     ~basic_string() { }
00126 
00127     basic_string&
00128     operator=(const basic_string& __str)
00129     {
00130       *static_cast<_Base*>(this) = __str;
00131       this->_M_invalidate_all();
00132       return *this;
00133     }
00134 
00135     basic_string&
00136     operator=(const _CharT* __s)
00137     {
00138       __glibcxx_check_string(__s);
00139       *static_cast<_Base*>(this) = __s;
00140       this->_M_invalidate_all();
00141       return *this;
00142     }
00143 
00144     basic_string&
00145     operator=(_CharT __c)
00146     {
00147       *static_cast<_Base*>(this) = __c;
00148       this->_M_invalidate_all();
00149       return *this;
00150     }
00151 
00152 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00153     basic_string&
00154     operator=(basic_string&& __str)
00155     {
00156       *static_cast<_Base*>(this) = std::forward<_Base>(__str);
00157       this->_M_invalidate_all();
00158       return *this;
00159     }
00160 
00161     basic_string&
00162     operator=(std::initializer_list<_CharT> __l)
00163     {
00164       *static_cast<_Base*>(this) = __l;
00165       this->_M_invalidate_all();
00166       return *this;
00167     }
00168 #endif // __GXX_EXPERIMENTAL_CXX0X__
00169 
00170     // 21.3.2 iterators:
00171     iterator
00172     begin()
00173     { return iterator(_Base::begin(), this); }
00174 
00175     const_iterator
00176     begin() const
00177     { return const_iterator(_Base::begin(), this); }
00178 
00179     iterator
00180     end()
00181     { return iterator(_Base::end(), this); }
00182 
00183     const_iterator
00184     end() const
00185     { return const_iterator(_Base::end(), this); }
00186 
00187     reverse_iterator
00188     rbegin()
00189     { return reverse_iterator(end()); }
00190 
00191     const_reverse_iterator
00192     rbegin() const
00193     { return const_reverse_iterator(end()); }
00194 
00195     reverse_iterator
00196     rend()
00197     { return reverse_iterator(begin()); }
00198 
00199     const_reverse_iterator
00200     rend() const
00201     { return const_reverse_iterator(begin()); }
00202 
00203     // 21.3.3 capacity:
00204     using _Base::size;
00205     using _Base::length;
00206     using _Base::max_size;
00207 
00208     void
00209     resize(size_type __n, _CharT __c)
00210     {
00211       _Base::resize(__n, __c);
00212       this->_M_invalidate_all();
00213     }
00214 
00215     void
00216     resize(size_type __n)
00217     { this->resize(__n, _CharT()); }
00218 
00219 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00220     using _Base::shrink_to_fit;
00221 #endif
00222 
00223     using _Base::capacity;
00224     using _Base::reserve;
00225 
00226     void
00227     clear()
00228     {
00229       _Base::clear();
00230       this->_M_invalidate_all();
00231     }
00232 
00233     using _Base::empty;
00234 
00235     // 21.3.4 element access:
00236     const_reference
00237     operator[](size_type __pos) const
00238     {
00239       _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
00240                 _M_message(__gnu_debug::__msg_subscript_oob)
00241                 ._M_sequence(*this, "this")
00242                 ._M_integer(__pos, "__pos")
00243                 ._M_integer(this->size(), "size"));
00244       return _M_base()[__pos];
00245     }
00246 
00247     reference
00248     operator[](size_type __pos)
00249     {
00250 #ifdef _GLIBCXX_DEBUG_PEDANTIC
00251       __glibcxx_check_subscript(__pos);
00252 #else
00253       // as an extension v3 allows s[s.size()] when s is non-const.
00254       _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
00255                 _M_message(__gnu_debug::__msg_subscript_oob)
00256                 ._M_sequence(*this, "this")
00257                 ._M_integer(__pos, "__pos")
00258                 ._M_integer(this->size(), "size"));
00259 #endif
00260       return _M_base()[__pos];
00261     }
00262 
00263     using _Base::at;
00264 
00265     // 21.3.5 modifiers:
00266     basic_string&
00267     operator+=(const basic_string& __str)
00268     {
00269       _M_base() += __str;
00270       this->_M_invalidate_all();
00271       return *this;
00272     }
00273 
00274     basic_string&
00275     operator+=(const _CharT* __s)
00276     {
00277       __glibcxx_check_string(__s);
00278       _M_base() += __s;
00279       this->_M_invalidate_all();
00280       return *this;
00281     }
00282 
00283     basic_string&
00284     operator+=(_CharT __c)
00285     {
00286       _M_base() += __c;
00287       this->_M_invalidate_all();
00288       return *this;
00289     }
00290 
00291 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00292     basic_string&
00293     operator+=(std::initializer_list<_CharT> __l)
00294     {
00295       _M_base() += __l;
00296       this->_M_invalidate_all();
00297       return *this;
00298     }
00299 #endif // __GXX_EXPERIMENTAL_CXX0X__
00300 
00301     basic_string&
00302     append(const basic_string& __str)
00303     {
00304       _Base::append(__str);
00305       this->_M_invalidate_all();
00306       return *this;
00307     }
00308 
00309     basic_string&
00310     append(const basic_string& __str, size_type __pos, size_type __n)
00311     {
00312       _Base::append(__str, __pos, __n);
00313       this->_M_invalidate_all();
00314       return *this;
00315     }
00316 
00317     basic_string&
00318     append(const _CharT* __s, size_type __n)
00319     {
00320       __glibcxx_check_string_len(__s, __n);
00321       _Base::append(__s, __n);
00322       this->_M_invalidate_all();
00323       return *this;
00324     }
00325 
00326     basic_string&
00327     append(const _CharT* __s)
00328     {
00329       __glibcxx_check_string(__s);
00330       _Base::append(__s);
00331       this->_M_invalidate_all();
00332       return *this;
00333     }
00334 
00335     basic_string&
00336     append(size_type __n, _CharT __c)
00337     {
00338       _Base::append(__n, __c);
00339       this->_M_invalidate_all();
00340       return *this;
00341     }
00342 
00343     template<typename _InputIterator>
00344       basic_string&
00345       append(_InputIterator __first, _InputIterator __last)
00346       {
00347     __glibcxx_check_valid_range(__first, __last);
00348     _Base::append(__first, __last);
00349     this->_M_invalidate_all();
00350     return *this;
00351       }
00352 
00353     // _GLIBCXX_RESOLVE_LIB_DEFECTS
00354     // 7. string clause minor problems
00355     void
00356     push_back(_CharT __c)
00357     {
00358       _Base::push_back(__c);
00359       this->_M_invalidate_all();
00360     }
00361 
00362     basic_string&
00363     assign(const basic_string& __x)
00364     {
00365       _Base::assign(__x);
00366       this->_M_invalidate_all();
00367       return *this;
00368     }
00369 
00370 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00371     basic_string&
00372     assign(basic_string&& __x)
00373     {
00374       _Base::assign(std::forward<_Base>(__x));
00375       this->_M_invalidate_all();
00376       return *this;
00377     }
00378 #endif // __GXX_EXPERIMENTAL_CXX0X__
00379 
00380     basic_string&
00381     assign(const basic_string& __str, size_type __pos, size_type __n)
00382     {
00383       _Base::assign(__str, __pos, __n);
00384       this->_M_invalidate_all();
00385       return *this;
00386     }
00387 
00388     basic_string&
00389     assign(const _CharT* __s, size_type __n)
00390     {
00391       __glibcxx_check_string_len(__s, __n);
00392       _Base::assign(__s, __n);
00393       this->_M_invalidate_all();
00394       return *this;
00395     }
00396 
00397     basic_string&
00398     assign(const _CharT* __s)
00399     {
00400       __glibcxx_check_string(__s);
00401       _Base::assign(__s);
00402       this->_M_invalidate_all();
00403       return *this;
00404     }
00405 
00406     basic_string&
00407     assign(size_type __n, _CharT __c)
00408     {
00409       _Base::assign(__n, __c);
00410       this->_M_invalidate_all();
00411       return *this;
00412     }
00413 
00414     template<typename _InputIterator>
00415       basic_string&
00416       assign(_InputIterator __first, _InputIterator __last)
00417       {
00418     __glibcxx_check_valid_range(__first, __last);
00419     _Base::assign(__first, __last);
00420     this->_M_invalidate_all();
00421     return *this;
00422       }
00423 
00424 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00425     basic_string&
00426     assign(std::initializer_list<_CharT> __l)
00427     {
00428       _Base::assign(__l);
00429       this->_M_invalidate_all();
00430       return *this;
00431     }
00432 #endif // __GXX_EXPERIMENTAL_CXX0X__
00433 
00434     basic_string&
00435     insert(size_type __pos1, const basic_string& __str)
00436     {
00437       _Base::insert(__pos1, __str);
00438       this->_M_invalidate_all();
00439       return *this;
00440     }
00441 
00442     basic_string&
00443     insert(size_type __pos1, const basic_string& __str,
00444        size_type __pos2, size_type __n)
00445     {
00446       _Base::insert(__pos1, __str, __pos2, __n);
00447       this->_M_invalidate_all();
00448       return *this;
00449     }
00450 
00451     basic_string&
00452     insert(size_type __pos, const _CharT* __s, size_type __n)
00453     {
00454       __glibcxx_check_string(__s);
00455       _Base::insert(__pos, __s, __n);
00456       this->_M_invalidate_all();
00457       return *this;
00458     }
00459 
00460     basic_string&
00461     insert(size_type __pos, const _CharT* __s)
00462     {
00463       __glibcxx_check_string(__s);
00464       _Base::insert(__pos, __s);
00465       this->_M_invalidate_all();
00466       return *this;
00467     }
00468 
00469     basic_string&
00470     insert(size_type __pos, size_type __n, _CharT __c)
00471     {
00472       _Base::insert(__pos, __n, __c);
00473       this->_M_invalidate_all();
00474       return *this;
00475     }
00476 
00477     iterator
00478     insert(iterator __p, _CharT __c)
00479     {
00480       __glibcxx_check_insert(__p);
00481       typename _Base::iterator __res = _Base::insert(__p.base(), __c);
00482       this->_M_invalidate_all();
00483       return iterator(__res, this);
00484     }
00485 
00486     void
00487     insert(iterator __p, size_type __n, _CharT __c)
00488     {
00489       __glibcxx_check_insert(__p);
00490       _Base::insert(__p.base(), __n, __c);
00491       this->_M_invalidate_all();
00492     }
00493 
00494     template<typename _InputIterator>
00495       void
00496       insert(iterator __p, _InputIterator __first, _InputIterator __last)
00497       {
00498     __glibcxx_check_insert_range(__p, __first, __last);
00499     _Base::insert(__p.base(), __first, __last);
00500     this->_M_invalidate_all();
00501       }
00502 
00503 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00504     void
00505     insert(iterator __p, std::initializer_list<_CharT> __l)
00506     {
00507       _Base::insert(__p, __l);
00508       this->_M_invalidate_all();
00509     }
00510 #endif // __GXX_EXPERIMENTAL_CXX0X__
00511 
00512     basic_string&
00513     erase(size_type __pos = 0, size_type __n = _Base::npos)
00514     {
00515       _Base::erase(__pos, __n);
00516       this->_M_invalidate_all();
00517       return *this;
00518     }
00519 
00520     iterator
00521     erase(iterator __position)
00522     {
00523       __glibcxx_check_erase(__position);
00524       typename _Base::iterator __res = _Base::erase(__position.base());
00525       this->_M_invalidate_all();
00526       return iterator(__res, this);
00527     }
00528 
00529     iterator
00530     erase(iterator __first, iterator __last)
00531     {
00532       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00533       // 151. can't currently clear() empty container
00534       __glibcxx_check_erase_range(__first, __last);
00535       typename _Base::iterator __res = _Base::erase(__first.base(),
00536                                __last.base());
00537       this->_M_invalidate_all();
00538       return iterator(__res, this);
00539     }
00540 
00541     basic_string&
00542     replace(size_type __pos1, size_type __n1, const basic_string& __str)
00543     {
00544       _Base::replace(__pos1, __n1, __str);
00545       this->_M_invalidate_all();
00546       return *this;
00547     }
00548 
00549     basic_string&
00550     replace(size_type __pos1, size_type __n1, const basic_string& __str,
00551         size_type __pos2, size_type __n2)
00552     {
00553       _Base::replace(__pos1, __n1, __str, __pos2, __n2);
00554       this->_M_invalidate_all();
00555       return *this;
00556     }
00557 
00558     basic_string&
00559     replace(size_type __pos, size_type __n1, const _CharT* __s,
00560         size_type __n2)
00561     {
00562       __glibcxx_check_string_len(__s, __n2);
00563       _Base::replace(__pos, __n1, __s, __n2);
00564       this->_M_invalidate_all();
00565       return *this;
00566     }
00567 
00568     basic_string&
00569     replace(size_type __pos, size_type __n1, const _CharT* __s)
00570     {
00571       __glibcxx_check_string(__s);
00572       _Base::replace(__pos, __n1, __s);
00573       this->_M_invalidate_all();
00574       return *this;
00575     }
00576 
00577     basic_string&
00578     replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
00579     {
00580       _Base::replace(__pos, __n1, __n2, __c);
00581       this->_M_invalidate_all();
00582       return *this;
00583     }
00584 
00585     basic_string&
00586     replace(iterator __i1, iterator __i2, const basic_string& __str)
00587     {
00588       __glibcxx_check_erase_range(__i1, __i2);
00589       _Base::replace(__i1.base(), __i2.base(), __str);
00590       this->_M_invalidate_all();
00591       return *this;
00592     }
00593 
00594     basic_string&
00595     replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
00596     {
00597       __glibcxx_check_erase_range(__i1, __i2);
00598       __glibcxx_check_string_len(__s, __n);
00599       _Base::replace(__i1.base(), __i2.base(), __s, __n);
00600       this->_M_invalidate_all();
00601       return *this;
00602     }
00603 
00604     basic_string&
00605     replace(iterator __i1, iterator __i2, const _CharT* __s)
00606     {
00607       __glibcxx_check_erase_range(__i1, __i2);
00608       __glibcxx_check_string(__s);
00609       _Base::replace(__i1.base(), __i2.base(), __s);
00610       this->_M_invalidate_all();
00611       return *this;
00612     }
00613 
00614     basic_string&
00615     replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
00616     {
00617       __glibcxx_check_erase_range(__i1, __i2);
00618       _Base::replace(__i1.base(), __i2.base(), __n, __c);
00619       this->_M_invalidate_all();
00620       return *this;
00621     }
00622 
00623     template<typename _InputIterator>
00624       basic_string&
00625       replace(iterator __i1, iterator __i2,
00626           _InputIterator __j1, _InputIterator __j2)
00627       {
00628     __glibcxx_check_erase_range(__i1, __i2);
00629     __glibcxx_check_valid_range(__j1, __j2);
00630     _Base::replace(__i1.base(), __i2.base(), __j1, __j2);
00631     this->_M_invalidate_all();
00632     return *this;
00633       }
00634 
00635 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00636       basic_string& replace(iterator __i1, iterator __i2,
00637                 std::initializer_list<_CharT> __l)
00638       {
00639     __glibcxx_check_erase_range(__i1, __i2);
00640     _Base::replace(__i1.base(), __i2.base(), __l);
00641     this->_M_invalidate_all();
00642     return *this;
00643       }
00644 #endif // __GXX_EXPERIMENTAL_CXX0X__
00645 
00646     size_type
00647     copy(_CharT* __s, size_type __n, size_type __pos = 0) const
00648     {
00649       __glibcxx_check_string_len(__s, __n);
00650       return _Base::copy(__s, __n, __pos);
00651     }
00652 
00653     void
00654     swap(basic_string<_CharT,_Traits,_Allocator>& __x)
00655     {
00656       _Base::swap(__x);
00657       this->_M_swap(__x);
00658       this->_M_invalidate_all();
00659       __x._M_invalidate_all();
00660     }
00661 
00662     // 21.3.6 string operations:
00663     const _CharT*
00664     c_str() const
00665     {
00666       const _CharT* __res = _Base::c_str();
00667       this->_M_invalidate_all();
00668       return __res;
00669     }
00670 
00671     const _CharT*
00672     data() const
00673     {
00674       const _CharT* __res = _Base::data();
00675       this->_M_invalidate_all();
00676       return __res;
00677     }
00678 
00679     using _Base::get_allocator;
00680 
00681     size_type
00682     find(const basic_string& __str, size_type __pos = 0) const
00683     { return _Base::find(__str, __pos); }
00684 
00685     size_type
00686     find(const _CharT* __s, size_type __pos, size_type __n) const
00687     {
00688       __glibcxx_check_string(__s);
00689       return _Base::find(__s, __pos, __n);
00690     }
00691 
00692     size_type
00693     find(const _CharT* __s, size_type __pos = 0) const
00694     {
00695       __glibcxx_check_string(__s);
00696       return _Base::find(__s, __pos);
00697     }
00698 
00699     size_type
00700     find(_CharT __c, size_type __pos = 0) const
00701     { return _Base::find(__c, __pos); }
00702 
00703     size_type
00704     rfind(const basic_string& __str, size_type __pos = _Base::npos) const
00705     { return _Base::rfind(__str, __pos); }
00706 
00707     size_type
00708     rfind(const _CharT* __s, size_type __pos, size_type __n) const
00709     {
00710       __glibcxx_check_string_len(__s, __n);
00711       return _Base::rfind(__s, __pos, __n);
00712     }
00713 
00714     size_type
00715     rfind(const _CharT* __s, size_type __pos = _Base::npos) const
00716     {
00717       __glibcxx_check_string(__s);
00718       return _Base::rfind(__s, __pos);
00719     }
00720 
00721     size_type
00722     rfind(_CharT __c, size_type __pos = _Base::npos) const
00723     { return _Base::rfind(__c, __pos); }
00724 
00725     size_type
00726     find_first_of(const basic_string& __str, size_type __pos = 0) const
00727     { return _Base::find_first_of(__str, __pos); }
00728 
00729     size_type
00730     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
00731     {
00732       __glibcxx_check_string(__s);
00733       return _Base::find_first_of(__s, __pos, __n);
00734     }
00735 
00736     size_type
00737     find_first_of(const _CharT* __s, size_type __pos = 0) const
00738     {
00739       __glibcxx_check_string(__s);
00740       return _Base::find_first_of(__s, __pos);
00741     }
00742 
00743     size_type
00744     find_first_of(_CharT __c, size_type __pos = 0) const
00745     { return _Base::find_first_of(__c, __pos); }
00746 
00747     size_type
00748     find_last_of(const basic_string& __str, 
00749          size_type __pos = _Base::npos) const
00750     { return _Base::find_last_of(__str, __pos); }
00751 
00752     size_type
00753     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
00754     {
00755       __glibcxx_check_string(__s);
00756       return _Base::find_last_of(__s, __pos, __n);
00757     }
00758 
00759     size_type
00760     find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
00761     {
00762       __glibcxx_check_string(__s);
00763       return _Base::find_last_of(__s, __pos);
00764     }
00765 
00766     size_type
00767     find_last_of(_CharT __c, size_type __pos = _Base::npos) const
00768     { return _Base::find_last_of(__c, __pos); }
00769 
00770     size_type
00771     find_first_not_of(const basic_string& __str, size_type __pos = 0) const
00772     { return _Base::find_first_not_of(__str, __pos); }
00773 
00774     size_type
00775     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00776     {
00777       __glibcxx_check_string_len(__s, __n);
00778       return _Base::find_first_not_of(__s, __pos, __n);
00779     }
00780 
00781     size_type
00782     find_first_not_of(const _CharT* __s, size_type __pos = 0) const
00783     {
00784       __glibcxx_check_string(__s);
00785       return _Base::find_first_not_of(__s, __pos);
00786     }
00787 
00788     size_type
00789     find_first_not_of(_CharT __c, size_type __pos = 0) const
00790     { return _Base::find_first_not_of(__c, __pos); }
00791 
00792     size_type
00793     find_last_not_of(const basic_string& __str,
00794                   size_type __pos = _Base::npos) const
00795     { return _Base::find_last_not_of(__str, __pos); }
00796 
00797     size_type
00798     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00799     {
00800       __glibcxx_check_string(__s);
00801       return _Base::find_last_not_of(__s, __pos, __n);
00802     }
00803 
00804     size_type
00805     find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
00806     {
00807       __glibcxx_check_string(__s);
00808       return _Base::find_last_not_of(__s, __pos);
00809     }
00810 
00811     size_type
00812     find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const
00813     { return _Base::find_last_not_of(__c, __pos); }
00814 
00815     basic_string
00816     substr(size_type __pos = 0, size_type __n = _Base::npos) const
00817     { return basic_string(_Base::substr(__pos, __n)); }
00818 
00819     int
00820     compare(const basic_string& __str) const
00821     { return _Base::compare(__str); }
00822 
00823     int
00824     compare(size_type __pos1, size_type __n1,
00825           const basic_string& __str) const
00826     { return _Base::compare(__pos1, __n1, __str); }
00827 
00828     int
00829     compare(size_type __pos1, size_type __n1, const basic_string& __str,
00830           size_type __pos2, size_type __n2) const
00831     { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); }
00832 
00833     int
00834     compare(const _CharT* __s) const
00835     {
00836       __glibcxx_check_string(__s);
00837       return _Base::compare(__s);
00838     }
00839 
00840     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
00841     //  5. string::compare specification questionable
00842     int
00843     compare(size_type __pos1, size_type __n1, const _CharT* __s) const
00844     {
00845       __glibcxx_check_string(__s);
00846       return _Base::compare(__pos1, __n1, __s);
00847     }
00848 
00849     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
00850     //  5. string::compare specification questionable
00851     int
00852     compare(size_type __pos1, size_type __n1,const _CharT* __s,
00853           size_type __n2) const
00854     {
00855       __glibcxx_check_string_len(__s, __n2);
00856       return _Base::compare(__pos1, __n1, __s, __n2);
00857     }
00858 
00859     _Base&
00860     _M_base() { return *this; }
00861 
00862     const _Base&
00863     _M_base() const { return *this; }
00864 
00865     using _Safe_base::_M_invalidate_all;
00866   };
00867 
00868   template<typename _CharT, typename _Traits, typename _Allocator>
00869     inline basic_string<_CharT,_Traits,_Allocator>
00870     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00871           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00872     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
00873 
00874   template<typename _CharT, typename _Traits, typename _Allocator>
00875     inline basic_string<_CharT,_Traits,_Allocator>
00876     operator+(const _CharT* __lhs,
00877           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00878     {
00879       __glibcxx_check_string(__lhs);
00880       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
00881     }
00882 
00883   template<typename _CharT, typename _Traits, typename _Allocator>
00884     inline basic_string<_CharT,_Traits,_Allocator>
00885     operator+(_CharT __lhs,
00886           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00887     { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; }
00888 
00889   template<typename _CharT, typename _Traits, typename _Allocator>
00890     inline basic_string<_CharT,_Traits,_Allocator>
00891     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00892           const _CharT* __rhs)
00893     {
00894       __glibcxx_check_string(__rhs);
00895       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
00896     }
00897 
00898   template<typename _CharT, typename _Traits, typename _Allocator>
00899     inline basic_string<_CharT,_Traits,_Allocator>
00900     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00901           _CharT __rhs)
00902     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
00903 
00904   template<typename _CharT, typename _Traits, typename _Allocator>
00905     inline bool
00906     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00907            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00908     { return __lhs._M_base() == __rhs._M_base(); }
00909 
00910   template<typename _CharT, typename _Traits, typename _Allocator>
00911     inline bool
00912     operator==(const _CharT* __lhs,
00913            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00914     {
00915       __glibcxx_check_string(__lhs);
00916       return __lhs == __rhs._M_base();
00917     }
00918 
00919   template<typename _CharT, typename _Traits, typename _Allocator>
00920     inline bool
00921     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00922            const _CharT* __rhs)
00923     {
00924       __glibcxx_check_string(__rhs);
00925       return __lhs._M_base() == __rhs;
00926     }
00927 
00928   template<typename _CharT, typename _Traits, typename _Allocator>
00929     inline bool
00930     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00931            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00932     { return __lhs._M_base() != __rhs._M_base(); }
00933 
00934   template<typename _CharT, typename _Traits, typename _Allocator>
00935     inline bool
00936     operator!=(const _CharT* __lhs,
00937            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00938     {
00939       __glibcxx_check_string(__lhs);
00940       return __lhs != __rhs._M_base();
00941     }
00942 
00943   template<typename _CharT, typename _Traits, typename _Allocator>
00944     inline bool
00945     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00946            const _CharT* __rhs)
00947     {
00948       __glibcxx_check_string(__rhs);
00949       return __lhs._M_base() != __rhs;
00950     }
00951 
00952   template<typename _CharT, typename _Traits, typename _Allocator>
00953     inline bool
00954     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00955           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00956     { return __lhs._M_base() < __rhs._M_base(); }
00957 
00958   template<typename _CharT, typename _Traits, typename _Allocator>
00959     inline bool
00960     operator<(const _CharT* __lhs,
00961           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00962     {
00963       __glibcxx_check_string(__lhs);
00964       return __lhs < __rhs._M_base();
00965     }
00966 
00967   template<typename _CharT, typename _Traits, typename _Allocator>
00968     inline bool
00969     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00970           const _CharT* __rhs)
00971     {
00972       __glibcxx_check_string(__rhs);
00973       return __lhs._M_base() < __rhs;
00974     }
00975 
00976   template<typename _CharT, typename _Traits, typename _Allocator>
00977     inline bool
00978     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00979            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00980     { return __lhs._M_base() <= __rhs._M_base(); }
00981 
00982   template<typename _CharT, typename _Traits, typename _Allocator>
00983     inline bool
00984     operator<=(const _CharT* __lhs,
00985            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00986     {
00987       __glibcxx_check_string(__lhs);
00988       return __lhs <= __rhs._M_base();
00989     }
00990 
00991   template<typename _CharT, typename _Traits, typename _Allocator>
00992     inline bool
00993     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00994            const _CharT* __rhs)
00995     {
00996       __glibcxx_check_string(__rhs);
00997       return __lhs._M_base() <= __rhs;
00998     }
00999 
01000   template<typename _CharT, typename _Traits, typename _Allocator>
01001     inline bool
01002     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01003            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01004     { return __lhs._M_base() >= __rhs._M_base(); }
01005 
01006   template<typename _CharT, typename _Traits, typename _Allocator>
01007     inline bool
01008     operator>=(const _CharT* __lhs,
01009            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01010     {
01011       __glibcxx_check_string(__lhs);
01012       return __lhs >= __rhs._M_base();
01013     }
01014 
01015   template<typename _CharT, typename _Traits, typename _Allocator>
01016     inline bool
01017     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01018            const _CharT* __rhs)
01019     {
01020       __glibcxx_check_string(__rhs);
01021       return __lhs._M_base() >= __rhs;
01022     }
01023 
01024   template<typename _CharT, typename _Traits, typename _Allocator>
01025     inline bool
01026     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01027           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01028     { return __lhs._M_base() > __rhs._M_base(); }
01029 
01030   template<typename _CharT, typename _Traits, typename _Allocator>
01031     inline bool
01032     operator>(const _CharT* __lhs,
01033           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01034     {
01035       __glibcxx_check_string(__lhs);
01036       return __lhs > __rhs._M_base();
01037     }
01038 
01039   template<typename _CharT, typename _Traits, typename _Allocator>
01040     inline bool
01041     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01042           const _CharT* __rhs)
01043     {
01044       __glibcxx_check_string(__rhs);
01045       return __lhs._M_base() > __rhs;
01046     }
01047 
01048   // 21.3.7.8:
01049   template<typename _CharT, typename _Traits, typename _Allocator>
01050     inline void
01051     swap(basic_string<_CharT,_Traits,_Allocator>& __lhs,
01052      basic_string<_CharT,_Traits,_Allocator>& __rhs)
01053     { __lhs.swap(__rhs); }
01054 
01055   template<typename _CharT, typename _Traits, typename _Allocator>
01056     std::basic_ostream<_CharT, _Traits>&
01057     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01058            const basic_string<_CharT, _Traits, _Allocator>& __str)
01059     { return __os << __str._M_base(); }
01060 
01061   template<typename _CharT, typename _Traits, typename _Allocator>
01062     std::basic_istream<_CharT,_Traits>&
01063     operator>>(std::basic_istream<_CharT,_Traits>& __is,
01064            basic_string<_CharT,_Traits,_Allocator>& __str)
01065     {
01066       std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
01067       __str._M_invalidate_all();
01068       return __res;
01069     }
01070 
01071   template<typename _CharT, typename _Traits, typename _Allocator>
01072     std::basic_istream<_CharT,_Traits>&
01073     getline(std::basic_istream<_CharT,_Traits>& __is,
01074         basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
01075     {
01076       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
01077                               __str._M_base(),
01078                             __delim);
01079       __str._M_invalidate_all();
01080       return __res;
01081     }
01082 
01083   template<typename _CharT, typename _Traits, typename _Allocator>
01084     std::basic_istream<_CharT,_Traits>&
01085     getline(std::basic_istream<_CharT,_Traits>& __is,
01086         basic_string<_CharT,_Traits,_Allocator>& __str)
01087     {
01088       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
01089                               __str._M_base());
01090       __str._M_invalidate_all();
01091       return __res;
01092     }
01093 
01094   typedef basic_string<char>    string;
01095 
01096 #ifdef _GLIBCXX_USE_WCHAR_T
01097   typedef basic_string<wchar_t> wstring;
01098 #endif
01099 
01100 } // namespace __gnu_debug
01101 
01102 #endif