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