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