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