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