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       _Base::insert(__p, __l);
00518       this->_M_invalidate_all();
00519     }
00520 #endif // __GXX_EXPERIMENTAL_CXX0X__
00521 
00522     basic_string&
00523     erase(size_type __pos = 0, size_type __n = _Base::npos)
00524     {
00525       _Base::erase(__pos, __n);
00526       this->_M_invalidate_all();
00527       return *this;
00528     }
00529 
00530     iterator
00531     erase(iterator __position)
00532     {
00533       __glibcxx_check_erase(__position);
00534       typename _Base::iterator __res = _Base::erase(__position.base());
00535       this->_M_invalidate_all();
00536       return iterator(__res, this);
00537     }
00538 
00539     iterator
00540     erase(iterator __first, iterator __last)
00541     {
00542       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00543       // 151. can't currently clear() empty container
00544       __glibcxx_check_erase_range(__first, __last);
00545       typename _Base::iterator __res = _Base::erase(__first.base(),
00546                                __last.base());
00547       this->_M_invalidate_all();
00548       return iterator(__res, this);
00549     }
00550 
00551     basic_string&
00552     replace(size_type __pos1, size_type __n1, const basic_string& __str)
00553     {
00554       _Base::replace(__pos1, __n1, __str);
00555       this->_M_invalidate_all();
00556       return *this;
00557     }
00558 
00559     basic_string&
00560     replace(size_type __pos1, size_type __n1, const basic_string& __str,
00561         size_type __pos2, size_type __n2)
00562     {
00563       _Base::replace(__pos1, __n1, __str, __pos2, __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         size_type __n2)
00571     {
00572       __glibcxx_check_string_len(__s, __n2);
00573       _Base::replace(__pos, __n1, __s, __n2);
00574       this->_M_invalidate_all();
00575       return *this;
00576     }
00577 
00578     basic_string&
00579     replace(size_type __pos, size_type __n1, const _CharT* __s)
00580     {
00581       __glibcxx_check_string(__s);
00582       _Base::replace(__pos, __n1, __s);
00583       this->_M_invalidate_all();
00584       return *this;
00585     }
00586 
00587     basic_string&
00588     replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
00589     {
00590       _Base::replace(__pos, __n1, __n2, __c);
00591       this->_M_invalidate_all();
00592       return *this;
00593     }
00594 
00595     basic_string&
00596     replace(iterator __i1, iterator __i2, const basic_string& __str)
00597     {
00598       __glibcxx_check_erase_range(__i1, __i2);
00599       _Base::replace(__i1.base(), __i2.base(), __str);
00600       this->_M_invalidate_all();
00601       return *this;
00602     }
00603 
00604     basic_string&
00605     replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
00606     {
00607       __glibcxx_check_erase_range(__i1, __i2);
00608       __glibcxx_check_string_len(__s, __n);
00609       _Base::replace(__i1.base(), __i2.base(), __s, __n);
00610       this->_M_invalidate_all();
00611       return *this;
00612     }
00613 
00614     basic_string&
00615     replace(iterator __i1, iterator __i2, const _CharT* __s)
00616     {
00617       __glibcxx_check_erase_range(__i1, __i2);
00618       __glibcxx_check_string(__s);
00619       _Base::replace(__i1.base(), __i2.base(), __s);
00620       this->_M_invalidate_all();
00621       return *this;
00622     }
00623 
00624     basic_string&
00625     replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
00626     {
00627       __glibcxx_check_erase_range(__i1, __i2);
00628       _Base::replace(__i1.base(), __i2.base(), __n, __c);
00629       this->_M_invalidate_all();
00630       return *this;
00631     }
00632 
00633     template<typename _InputIterator>
00634       basic_string&
00635       replace(iterator __i1, iterator __i2,
00636           _InputIterator __j1, _InputIterator __j2)
00637       {
00638     __glibcxx_check_erase_range(__i1, __i2);
00639     __glibcxx_check_valid_range(__j1, __j2);
00640     _Base::replace(__i1.base(), __i2.base(), __j1, __j2);
00641     this->_M_invalidate_all();
00642     return *this;
00643       }
00644 
00645 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00646       basic_string& replace(iterator __i1, iterator __i2,
00647                 std::initializer_list<_CharT> __l)
00648       {
00649     __glibcxx_check_erase_range(__i1, __i2);
00650     _Base::replace(__i1.base(), __i2.base(), __l);
00651     this->_M_invalidate_all();
00652     return *this;
00653       }
00654 #endif // __GXX_EXPERIMENTAL_CXX0X__
00655 
00656     size_type
00657     copy(_CharT* __s, size_type __n, size_type __pos = 0) const
00658     {
00659       __glibcxx_check_string_len(__s, __n);
00660       return _Base::copy(__s, __n, __pos);
00661     }
00662 
00663     void
00664     swap(basic_string<_CharT,_Traits,_Allocator>& __x)
00665     {
00666       _Base::swap(__x);
00667       this->_M_swap(__x);
00668       this->_M_invalidate_all();
00669       __x._M_invalidate_all();
00670     }
00671 
00672     // 21.3.6 string operations:
00673     const _CharT*
00674     c_str() const
00675     {
00676       const _CharT* __res = _Base::c_str();
00677       this->_M_invalidate_all();
00678       return __res;
00679     }
00680 
00681     const _CharT*
00682     data() const
00683     {
00684       const _CharT* __res = _Base::data();
00685       this->_M_invalidate_all();
00686       return __res;
00687     }
00688 
00689     using _Base::get_allocator;
00690 
00691     size_type
00692     find(const basic_string& __str, size_type __pos = 0) const
00693     { return _Base::find(__str, __pos); }
00694 
00695     size_type
00696     find(const _CharT* __s, size_type __pos, size_type __n) const
00697     {
00698       __glibcxx_check_string(__s);
00699       return _Base::find(__s, __pos, __n);
00700     }
00701 
00702     size_type
00703     find(const _CharT* __s, size_type __pos = 0) const
00704     {
00705       __glibcxx_check_string(__s);
00706       return _Base::find(__s, __pos);
00707     }
00708 
00709     size_type
00710     find(_CharT __c, size_type __pos = 0) const
00711     { return _Base::find(__c, __pos); }
00712 
00713     size_type
00714     rfind(const basic_string& __str, size_type __pos = _Base::npos) const
00715     { return _Base::rfind(__str, __pos); }
00716 
00717     size_type
00718     rfind(const _CharT* __s, size_type __pos, size_type __n) const
00719     {
00720       __glibcxx_check_string_len(__s, __n);
00721       return _Base::rfind(__s, __pos, __n);
00722     }
00723 
00724     size_type
00725     rfind(const _CharT* __s, size_type __pos = _Base::npos) const
00726     {
00727       __glibcxx_check_string(__s);
00728       return _Base::rfind(__s, __pos);
00729     }
00730 
00731     size_type
00732     rfind(_CharT __c, size_type __pos = _Base::npos) const
00733     { return _Base::rfind(__c, __pos); }
00734 
00735     size_type
00736     find_first_of(const basic_string& __str, size_type __pos = 0) const
00737     { return _Base::find_first_of(__str, __pos); }
00738 
00739     size_type
00740     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
00741     {
00742       __glibcxx_check_string(__s);
00743       return _Base::find_first_of(__s, __pos, __n);
00744     }
00745 
00746     size_type
00747     find_first_of(const _CharT* __s, size_type __pos = 0) const
00748     {
00749       __glibcxx_check_string(__s);
00750       return _Base::find_first_of(__s, __pos);
00751     }
00752 
00753     size_type
00754     find_first_of(_CharT __c, size_type __pos = 0) const
00755     { return _Base::find_first_of(__c, __pos); }
00756 
00757     size_type
00758     find_last_of(const basic_string& __str, 
00759          size_type __pos = _Base::npos) const
00760     { return _Base::find_last_of(__str, __pos); }
00761 
00762     size_type
00763     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
00764     {
00765       __glibcxx_check_string(__s);
00766       return _Base::find_last_of(__s, __pos, __n);
00767     }
00768 
00769     size_type
00770     find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
00771     {
00772       __glibcxx_check_string(__s);
00773       return _Base::find_last_of(__s, __pos);
00774     }
00775 
00776     size_type
00777     find_last_of(_CharT __c, size_type __pos = _Base::npos) const
00778     { return _Base::find_last_of(__c, __pos); }
00779 
00780     size_type
00781     find_first_not_of(const basic_string& __str, size_type __pos = 0) const
00782     { return _Base::find_first_not_of(__str, __pos); }
00783 
00784     size_type
00785     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00786     {
00787       __glibcxx_check_string_len(__s, __n);
00788       return _Base::find_first_not_of(__s, __pos, __n);
00789     }
00790 
00791     size_type
00792     find_first_not_of(const _CharT* __s, size_type __pos = 0) const
00793     {
00794       __glibcxx_check_string(__s);
00795       return _Base::find_first_not_of(__s, __pos);
00796     }
00797 
00798     size_type
00799     find_first_not_of(_CharT __c, size_type __pos = 0) const
00800     { return _Base::find_first_not_of(__c, __pos); }
00801 
00802     size_type
00803     find_last_not_of(const basic_string& __str,
00804                   size_type __pos = _Base::npos) const
00805     { return _Base::find_last_not_of(__str, __pos); }
00806 
00807     size_type
00808     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00809     {
00810       __glibcxx_check_string(__s);
00811       return _Base::find_last_not_of(__s, __pos, __n);
00812     }
00813 
00814     size_type
00815     find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
00816     {
00817       __glibcxx_check_string(__s);
00818       return _Base::find_last_not_of(__s, __pos);
00819     }
00820 
00821     size_type
00822     find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const
00823     { return _Base::find_last_not_of(__c, __pos); }
00824 
00825     basic_string
00826     substr(size_type __pos = 0, size_type __n = _Base::npos) const
00827     { return basic_string(_Base::substr(__pos, __n)); }
00828 
00829     int
00830     compare(const basic_string& __str) const
00831     { return _Base::compare(__str); }
00832 
00833     int
00834     compare(size_type __pos1, size_type __n1,
00835           const basic_string& __str) const
00836     { return _Base::compare(__pos1, __n1, __str); }
00837 
00838     int
00839     compare(size_type __pos1, size_type __n1, const basic_string& __str,
00840           size_type __pos2, size_type __n2) const
00841     { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); }
00842 
00843     int
00844     compare(const _CharT* __s) const
00845     {
00846       __glibcxx_check_string(__s);
00847       return _Base::compare(__s);
00848     }
00849 
00850     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
00851     //  5. string::compare specification questionable
00852     int
00853     compare(size_type __pos1, size_type __n1, const _CharT* __s) const
00854     {
00855       __glibcxx_check_string(__s);
00856       return _Base::compare(__pos1, __n1, __s);
00857     }
00858 
00859     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
00860     //  5. string::compare specification questionable
00861     int
00862     compare(size_type __pos1, size_type __n1,const _CharT* __s,
00863           size_type __n2) const
00864     {
00865       __glibcxx_check_string_len(__s, __n2);
00866       return _Base::compare(__pos1, __n1, __s, __n2);
00867     }
00868 
00869     _Base&
00870     _M_base() { return *this; }
00871 
00872     const _Base&
00873     _M_base() const { return *this; }
00874 
00875     using _Safe_base::_M_invalidate_all;
00876   };
00877 
00878   template<typename _CharT, typename _Traits, typename _Allocator>
00879     inline basic_string<_CharT,_Traits,_Allocator>
00880     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00881           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00882     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
00883 
00884   template<typename _CharT, typename _Traits, typename _Allocator>
00885     inline basic_string<_CharT,_Traits,_Allocator>
00886     operator+(const _CharT* __lhs,
00887           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00888     {
00889       __glibcxx_check_string(__lhs);
00890       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
00891     }
00892 
00893   template<typename _CharT, typename _Traits, typename _Allocator>
00894     inline basic_string<_CharT,_Traits,_Allocator>
00895     operator+(_CharT __lhs,
00896           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00897     { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; }
00898 
00899   template<typename _CharT, typename _Traits, typename _Allocator>
00900     inline basic_string<_CharT,_Traits,_Allocator>
00901     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00902           const _CharT* __rhs)
00903     {
00904       __glibcxx_check_string(__rhs);
00905       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
00906     }
00907 
00908   template<typename _CharT, typename _Traits, typename _Allocator>
00909     inline basic_string<_CharT,_Traits,_Allocator>
00910     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00911           _CharT __rhs)
00912     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
00913 
00914   template<typename _CharT, typename _Traits, typename _Allocator>
00915     inline bool
00916     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00917            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00918     { return __lhs._M_base() == __rhs._M_base(); }
00919 
00920   template<typename _CharT, typename _Traits, typename _Allocator>
00921     inline bool
00922     operator==(const _CharT* __lhs,
00923            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00924     {
00925       __glibcxx_check_string(__lhs);
00926       return __lhs == __rhs._M_base();
00927     }
00928 
00929   template<typename _CharT, typename _Traits, typename _Allocator>
00930     inline bool
00931     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00932            const _CharT* __rhs)
00933     {
00934       __glibcxx_check_string(__rhs);
00935       return __lhs._M_base() == __rhs;
00936     }
00937 
00938   template<typename _CharT, typename _Traits, typename _Allocator>
00939     inline bool
00940     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00941            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00942     { return __lhs._M_base() != __rhs._M_base(); }
00943 
00944   template<typename _CharT, typename _Traits, typename _Allocator>
00945     inline bool
00946     operator!=(const _CharT* __lhs,
00947            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00948     {
00949       __glibcxx_check_string(__lhs);
00950       return __lhs != __rhs._M_base();
00951     }
00952 
00953   template<typename _CharT, typename _Traits, typename _Allocator>
00954     inline bool
00955     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00956            const _CharT* __rhs)
00957     {
00958       __glibcxx_check_string(__rhs);
00959       return __lhs._M_base() != __rhs;
00960     }
00961 
00962   template<typename _CharT, typename _Traits, typename _Allocator>
00963     inline bool
00964     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00965           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00966     { return __lhs._M_base() < __rhs._M_base(); }
00967 
00968   template<typename _CharT, typename _Traits, typename _Allocator>
00969     inline bool
00970     operator<(const _CharT* __lhs,
00971           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00972     {
00973       __glibcxx_check_string(__lhs);
00974       return __lhs < __rhs._M_base();
00975     }
00976 
00977   template<typename _CharT, typename _Traits, typename _Allocator>
00978     inline bool
00979     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00980           const _CharT* __rhs)
00981     {
00982       __glibcxx_check_string(__rhs);
00983       return __lhs._M_base() < __rhs;
00984     }
00985 
00986   template<typename _CharT, typename _Traits, typename _Allocator>
00987     inline bool
00988     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00989            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00990     { return __lhs._M_base() <= __rhs._M_base(); }
00991 
00992   template<typename _CharT, typename _Traits, typename _Allocator>
00993     inline bool
00994     operator<=(const _CharT* __lhs,
00995            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00996     {
00997       __glibcxx_check_string(__lhs);
00998       return __lhs <= __rhs._M_base();
00999     }
01000 
01001   template<typename _CharT, typename _Traits, typename _Allocator>
01002     inline bool
01003     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01004            const _CharT* __rhs)
01005     {
01006       __glibcxx_check_string(__rhs);
01007       return __lhs._M_base() <= __rhs;
01008     }
01009 
01010   template<typename _CharT, typename _Traits, typename _Allocator>
01011     inline bool
01012     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01013            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01014     { return __lhs._M_base() >= __rhs._M_base(); }
01015 
01016   template<typename _CharT, typename _Traits, typename _Allocator>
01017     inline bool
01018     operator>=(const _CharT* __lhs,
01019            const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01020     {
01021       __glibcxx_check_string(__lhs);
01022       return __lhs >= __rhs._M_base();
01023     }
01024 
01025   template<typename _CharT, typename _Traits, typename _Allocator>
01026     inline bool
01027     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01028            const _CharT* __rhs)
01029     {
01030       __glibcxx_check_string(__rhs);
01031       return __lhs._M_base() >= __rhs;
01032     }
01033 
01034   template<typename _CharT, typename _Traits, typename _Allocator>
01035     inline bool
01036     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01037           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01038     { return __lhs._M_base() > __rhs._M_base(); }
01039 
01040   template<typename _CharT, typename _Traits, typename _Allocator>
01041     inline bool
01042     operator>(const _CharT* __lhs,
01043           const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01044     {
01045       __glibcxx_check_string(__lhs);
01046       return __lhs > __rhs._M_base();
01047     }
01048 
01049   template<typename _CharT, typename _Traits, typename _Allocator>
01050     inline bool
01051     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01052           const _CharT* __rhs)
01053     {
01054       __glibcxx_check_string(__rhs);
01055       return __lhs._M_base() > __rhs;
01056     }
01057 
01058   // 21.3.7.8:
01059   template<typename _CharT, typename _Traits, typename _Allocator>
01060     inline void
01061     swap(basic_string<_CharT,_Traits,_Allocator>& __lhs,
01062      basic_string<_CharT,_Traits,_Allocator>& __rhs)
01063     { __lhs.swap(__rhs); }
01064 
01065   template<typename _CharT, typename _Traits, typename _Allocator>
01066     std::basic_ostream<_CharT, _Traits>&
01067     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01068            const basic_string<_CharT, _Traits, _Allocator>& __str)
01069     { return __os << __str._M_base(); }
01070 
01071   template<typename _CharT, typename _Traits, typename _Allocator>
01072     std::basic_istream<_CharT,_Traits>&
01073     operator>>(std::basic_istream<_CharT,_Traits>& __is,
01074            basic_string<_CharT,_Traits,_Allocator>& __str)
01075     {
01076       std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
01077       __str._M_invalidate_all();
01078       return __res;
01079     }
01080 
01081   template<typename _CharT, typename _Traits, typename _Allocator>
01082     std::basic_istream<_CharT,_Traits>&
01083     getline(std::basic_istream<_CharT,_Traits>& __is,
01084         basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
01085     {
01086       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
01087                               __str._M_base(),
01088                             __delim);
01089       __str._M_invalidate_all();
01090       return __res;
01091     }
01092 
01093   template<typename _CharT, typename _Traits, typename _Allocator>
01094     std::basic_istream<_CharT,_Traits>&
01095     getline(std::basic_istream<_CharT,_Traits>& __is,
01096         basic_string<_CharT,_Traits,_Allocator>& __str)
01097     {
01098       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
01099                               __str._M_base());
01100       __str._M_invalidate_all();
01101       return __res;
01102     }
01103 
01104   typedef basic_string<char>    string;
01105 
01106 #ifdef _GLIBCXX_USE_WCHAR_T
01107   typedef basic_string<wchar_t> wstring;
01108 #endif
01109 
01110 } // namespace __gnu_debug
01111 
01112 #endif