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