libstdc++
string
Go to the documentation of this file.
00001 // Debugging string implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2003-2017 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 #pragma GCC system_header
00033 
00034 #include <string>
00035 #include <debug/safe_sequence.h>
00036 #include <debug/safe_container.h>
00037 #include <debug/safe_iterator.h>
00038 
00039 namespace __gnu_debug
00040 {
00041 /// Class std::basic_string with safety/checking/debug instrumentation.
00042 template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
00043          typename _Allocator = std::allocator<_CharT> >
00044   class basic_string
00045   : public __gnu_debug::_Safe_container<
00046       basic_string<_CharT, _Traits, _Allocator>,
00047       _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>,
00048     public std::basic_string<_CharT, _Traits, _Allocator>
00049   {
00050     typedef std::basic_string<_CharT, _Traits, _Allocator>      _Base;
00051     typedef __gnu_debug::_Safe_container<
00052       basic_string, _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>
00053       _Safe;
00054 
00055   public:
00056     // types:
00057     typedef _Traits                                     traits_type;
00058     typedef typename _Traits::char_type                 value_type;
00059     typedef _Allocator                                  allocator_type;
00060     typedef typename _Base::size_type                   size_type;
00061     typedef typename _Base::difference_type             difference_type;
00062     typedef typename _Base::reference                   reference;
00063     typedef typename _Base::const_reference             const_reference;
00064     typedef typename _Base::pointer                     pointer;
00065     typedef typename _Base::const_pointer               const_pointer;
00066 
00067     typedef __gnu_debug::_Safe_iterator<
00068       typename _Base::iterator, basic_string>           iterator;
00069     typedef __gnu_debug::_Safe_iterator<
00070       typename _Base::const_iterator, basic_string>     const_iterator;
00071 
00072     typedef std::reverse_iterator<iterator>             reverse_iterator;
00073     typedef std::reverse_iterator<const_iterator>       const_reverse_iterator;
00074 
00075     using _Base::npos;
00076 
00077     basic_string()
00078     _GLIBCXX_NOEXCEPT_IF(std::is_nothrow_default_constructible<_Base>::value)
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         typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
00402         __glibcxx_check_valid_range2(__first, __last, __dist);
00403 
00404         if (__dist.second >= __dp_sign)
00405           _Base::append(__gnu_debug::__unsafe(__first),
00406                         __gnu_debug::__unsafe(__last));
00407         else
00408           _Base::append(__first, __last);
00409 
00410         this->_M_invalidate_all();
00411         return *this;
00412       }
00413 
00414     // _GLIBCXX_RESOLVE_LIB_DEFECTS
00415     // 7. string clause minor problems
00416     void
00417     push_back(_CharT __c)
00418     {
00419       _Base::push_back(__c);
00420       this->_M_invalidate_all();
00421     }
00422 
00423     basic_string&
00424     assign(const basic_string& __x)
00425     {
00426       _Base::assign(__x);
00427       this->_M_invalidate_all();
00428       return *this;
00429     }
00430 
00431 #if __cplusplus >= 201103L
00432     basic_string&
00433     assign(basic_string&& __x)
00434     noexcept(noexcept(std::declval<_Base&>().assign(std::move(__x))))
00435     {
00436       _Base::assign(std::move(__x));
00437       this->_M_invalidate_all();
00438       return *this;
00439     }
00440 #endif // C++11
00441 
00442     basic_string&
00443     assign(const basic_string& __str, size_type __pos, size_type __n)
00444     {
00445       _Base::assign(__str, __pos, __n);
00446       this->_M_invalidate_all();
00447       return *this;
00448     }
00449 
00450     basic_string&
00451     assign(const _CharT* __s, size_type __n)
00452     {
00453       __glibcxx_check_string_len(__s, __n);
00454       _Base::assign(__s, __n);
00455       this->_M_invalidate_all();
00456       return *this;
00457     }
00458 
00459     basic_string&
00460     assign(const _CharT* __s)
00461     {
00462       __glibcxx_check_string(__s);
00463       _Base::assign(__s);
00464       this->_M_invalidate_all();
00465       return *this;
00466     }
00467 
00468     basic_string&
00469     assign(size_type __n, _CharT __c)
00470     {
00471       _Base::assign(__n, __c);
00472       this->_M_invalidate_all();
00473       return *this;
00474     }
00475 
00476     template<typename _InputIterator>
00477       basic_string&
00478       assign(_InputIterator __first, _InputIterator __last)
00479       {
00480         typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
00481         __glibcxx_check_valid_range2(__first, __last, __dist);
00482 
00483         if (__dist.second >= __dp_sign)
00484           _Base::assign(__gnu_debug::__unsafe(__first),
00485                         __gnu_debug::__unsafe(__last));
00486         else
00487           _Base::assign(__first, __last);
00488 
00489         this->_M_invalidate_all();
00490         return *this;
00491       }
00492 
00493 #if __cplusplus >= 201103L
00494     basic_string&
00495     assign(std::initializer_list<_CharT> __l)
00496     {
00497       _Base::assign(__l);
00498       this->_M_invalidate_all();
00499       return *this;
00500     }
00501 #endif // C++11
00502 
00503     basic_string&
00504     insert(size_type __pos1, const basic_string& __str)
00505     {
00506       _Base::insert(__pos1, __str);
00507       this->_M_invalidate_all();
00508       return *this;
00509     }
00510 
00511     basic_string&
00512     insert(size_type __pos1, const basic_string& __str,
00513            size_type __pos2, size_type __n)
00514     {
00515       _Base::insert(__pos1, __str, __pos2, __n);
00516       this->_M_invalidate_all();
00517       return *this;
00518     }
00519 
00520     basic_string&
00521     insert(size_type __pos, const _CharT* __s, size_type __n)
00522     {
00523       __glibcxx_check_string(__s);
00524       _Base::insert(__pos, __s, __n);
00525       this->_M_invalidate_all();
00526       return *this;
00527     }
00528 
00529     basic_string&
00530     insert(size_type __pos, const _CharT* __s)
00531     {
00532       __glibcxx_check_string(__s);
00533       _Base::insert(__pos, __s);
00534       this->_M_invalidate_all();
00535       return *this;
00536     }
00537 
00538     basic_string&
00539     insert(size_type __pos, size_type __n, _CharT __c)
00540     {
00541       _Base::insert(__pos, __n, __c);
00542       this->_M_invalidate_all();
00543       return *this;
00544     }
00545 
00546     iterator
00547     insert(iterator __p, _CharT __c)
00548     {
00549       __glibcxx_check_insert(__p);
00550       typename _Base::iterator __res = _Base::insert(__p.base(), __c);
00551       this->_M_invalidate_all();
00552       return iterator(__res, this);
00553     }
00554 
00555     void
00556     insert(iterator __p, size_type __n, _CharT __c)
00557     {
00558       __glibcxx_check_insert(__p);
00559       _Base::insert(__p.base(), __n, __c);
00560       this->_M_invalidate_all();
00561     }
00562 
00563     template<typename _InputIterator>
00564       void
00565       insert(iterator __p, _InputIterator __first, _InputIterator __last)
00566       {
00567         typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
00568         __glibcxx_check_insert_range2(__p, __first, __last, __dist);
00569 
00570         if (__dist.second >= __dp_sign)
00571           _Base::insert(__p.base(), __gnu_debug::__unsafe(__first),
00572                                     __gnu_debug::__unsafe(__last));
00573         else
00574           _Base::insert(__p.base(), __first, __last);
00575 
00576         this->_M_invalidate_all();
00577       }
00578 
00579 #if __cplusplus >= 201103L
00580     void
00581     insert(iterator __p, std::initializer_list<_CharT> __l)
00582     {
00583       __glibcxx_check_insert(__p);
00584       _Base::insert(__p.base(), __l);
00585       this->_M_invalidate_all();
00586     }
00587 #endif // C++11
00588 
00589     basic_string&
00590     erase(size_type __pos = 0, size_type __n = _Base::npos)
00591     {
00592       _Base::erase(__pos, __n);
00593       this->_M_invalidate_all();
00594       return *this;
00595     }
00596 
00597     iterator
00598     erase(iterator __position)
00599     {
00600       __glibcxx_check_erase(__position);
00601       typename _Base::iterator __res = _Base::erase(__position.base());
00602       this->_M_invalidate_all();
00603       return iterator(__res, this);
00604     }
00605 
00606     iterator
00607     erase(iterator __first, iterator __last)
00608     {
00609       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00610       // 151. can't currently clear() empty container
00611       __glibcxx_check_erase_range(__first, __last);
00612       typename _Base::iterator __res = _Base::erase(__first.base(),
00613                                                     __last.base());
00614       this->_M_invalidate_all();
00615       return iterator(__res, this);
00616     }
00617 
00618 #if __cplusplus >= 201103L
00619     void
00620     pop_back() // noexcept
00621     {
00622       __glibcxx_check_nonempty();
00623       _Base::pop_back();
00624       this->_M_invalidate_all();
00625     }
00626 #endif // C++11
00627 
00628     basic_string&
00629     replace(size_type __pos1, size_type __n1, const basic_string& __str)
00630     {
00631       _Base::replace(__pos1, __n1, __str);
00632       this->_M_invalidate_all();
00633       return *this;
00634     }
00635 
00636     basic_string&
00637     replace(size_type __pos1, size_type __n1, const basic_string& __str,
00638             size_type __pos2, size_type __n2)
00639     {
00640       _Base::replace(__pos1, __n1, __str, __pos2, __n2);
00641       this->_M_invalidate_all();
00642       return *this;
00643     }
00644 
00645     basic_string&
00646     replace(size_type __pos, size_type __n1, const _CharT* __s,
00647             size_type __n2)
00648     {
00649       __glibcxx_check_string_len(__s, __n2);
00650       _Base::replace(__pos, __n1, __s, __n2);
00651       this->_M_invalidate_all();
00652       return *this;
00653     }
00654 
00655     basic_string&
00656     replace(size_type __pos, size_type __n1, const _CharT* __s)
00657     {
00658       __glibcxx_check_string(__s);
00659       _Base::replace(__pos, __n1, __s);
00660       this->_M_invalidate_all();
00661       return *this;
00662     }
00663 
00664     basic_string&
00665     replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
00666     {
00667       _Base::replace(__pos, __n1, __n2, __c);
00668       this->_M_invalidate_all();
00669       return *this;
00670     }
00671 
00672     basic_string&
00673     replace(iterator __i1, iterator __i2, const basic_string& __str)
00674     {
00675       __glibcxx_check_erase_range(__i1, __i2);
00676       _Base::replace(__i1.base(), __i2.base(), __str);
00677       this->_M_invalidate_all();
00678       return *this;
00679     }
00680 
00681     basic_string&
00682     replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
00683     {
00684       __glibcxx_check_erase_range(__i1, __i2);
00685       __glibcxx_check_string_len(__s, __n);
00686       _Base::replace(__i1.base(), __i2.base(), __s, __n);
00687       this->_M_invalidate_all();
00688       return *this;
00689     }
00690 
00691     basic_string&
00692     replace(iterator __i1, iterator __i2, const _CharT* __s)
00693     {
00694       __glibcxx_check_erase_range(__i1, __i2);
00695       __glibcxx_check_string(__s);
00696       _Base::replace(__i1.base(), __i2.base(), __s);
00697       this->_M_invalidate_all();
00698       return *this;
00699     }
00700 
00701     basic_string&
00702     replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
00703     {
00704       __glibcxx_check_erase_range(__i1, __i2);
00705       _Base::replace(__i1.base(), __i2.base(), __n, __c);
00706       this->_M_invalidate_all();
00707       return *this;
00708     }
00709 
00710     template<typename _InputIterator>
00711       basic_string&
00712       replace(iterator __i1, iterator __i2,
00713               _InputIterator __j1, _InputIterator __j2)
00714       {
00715         __glibcxx_check_erase_range(__i1, __i2);
00716 
00717         typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
00718         __glibcxx_check_valid_range2(__j1, __j2, __dist);
00719 
00720         if (__dist.second >= __dp_sign)
00721           _Base::replace(__i1.base(), __i2.base(),
00722                          __gnu_debug::__unsafe(__j1),
00723                          __gnu_debug::__unsafe(__j2));
00724         else
00725           _Base::replace(__i1.base(), __i2.base(), __j1, __j2);
00726 
00727         this->_M_invalidate_all();
00728         return *this;
00729       }
00730 
00731 #if __cplusplus >= 201103L
00732       basic_string& replace(iterator __i1, iterator __i2,
00733                             std::initializer_list<_CharT> __l)
00734       {
00735         __glibcxx_check_erase_range(__i1, __i2);
00736         _Base::replace(__i1.base(), __i2.base(), __l);
00737         this->_M_invalidate_all();
00738         return *this;
00739       }
00740 #endif // C++11
00741 
00742     size_type
00743     copy(_CharT* __s, size_type __n, size_type __pos = 0) const
00744     {
00745       __glibcxx_check_string_len(__s, __n);
00746       return _Base::copy(__s, __n, __pos);
00747     }
00748 
00749     void
00750     swap(basic_string& __x)
00751     _GLIBCXX_NOEXCEPT_IF(std::__is_nothrow_swappable<_Base>::value)
00752     {
00753       _Safe::_M_swap(__x);
00754       _Base::swap(__x);
00755     }
00756 
00757     // 21.3.6 string operations:
00758     const _CharT*
00759     c_str() const _GLIBCXX_NOEXCEPT
00760     {
00761       const _CharT* __res = _Base::c_str();
00762       this->_M_invalidate_all();
00763       return __res;
00764     }
00765 
00766     const _CharT*
00767     data() const _GLIBCXX_NOEXCEPT
00768     {
00769       const _CharT* __res = _Base::data();
00770       this->_M_invalidate_all();
00771       return __res;
00772     }
00773 
00774     using _Base::get_allocator;
00775 
00776     size_type
00777     find(const basic_string& __str, size_type __pos = 0) const
00778       _GLIBCXX_NOEXCEPT
00779     { return _Base::find(__str, __pos); }
00780 
00781     size_type
00782     find(const _CharT* __s, size_type __pos, size_type __n) const
00783     {
00784       __glibcxx_check_string(__s);
00785       return _Base::find(__s, __pos, __n);
00786     }
00787 
00788     size_type
00789     find(const _CharT* __s, size_type __pos = 0) const
00790     {
00791       __glibcxx_check_string(__s);
00792       return _Base::find(__s, __pos);
00793     }
00794 
00795     size_type
00796     find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
00797     { return _Base::find(__c, __pos); }
00798 
00799     size_type
00800     rfind(const basic_string& __str, size_type __pos = _Base::npos) const
00801       _GLIBCXX_NOEXCEPT
00802     { return _Base::rfind(__str, __pos); }
00803 
00804     size_type
00805     rfind(const _CharT* __s, size_type __pos, size_type __n) const
00806     {
00807       __glibcxx_check_string_len(__s, __n);
00808       return _Base::rfind(__s, __pos, __n);
00809     }
00810 
00811     size_type
00812     rfind(const _CharT* __s, size_type __pos = _Base::npos) const
00813     {
00814       __glibcxx_check_string(__s);
00815       return _Base::rfind(__s, __pos);
00816     }
00817 
00818     size_type
00819     rfind(_CharT __c, size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
00820     { return _Base::rfind(__c, __pos); }
00821 
00822     size_type
00823     find_first_of(const basic_string& __str, size_type __pos = 0) const
00824       _GLIBCXX_NOEXCEPT
00825     { return _Base::find_first_of(__str, __pos); }
00826 
00827     size_type
00828     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
00829     {
00830       __glibcxx_check_string(__s);
00831       return _Base::find_first_of(__s, __pos, __n);
00832     }
00833 
00834     size_type
00835     find_first_of(const _CharT* __s, size_type __pos = 0) const
00836     {
00837       __glibcxx_check_string(__s);
00838       return _Base::find_first_of(__s, __pos);
00839     }
00840 
00841     size_type
00842     find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
00843     { return _Base::find_first_of(__c, __pos); }
00844 
00845     size_type
00846     find_last_of(const basic_string& __str,
00847                  size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
00848     { return _Base::find_last_of(__str, __pos); }
00849 
00850     size_type
00851     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
00852     {
00853       __glibcxx_check_string(__s);
00854       return _Base::find_last_of(__s, __pos, __n);
00855     }
00856 
00857     size_type
00858     find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
00859     {
00860       __glibcxx_check_string(__s);
00861       return _Base::find_last_of(__s, __pos);
00862     }
00863 
00864     size_type
00865     find_last_of(_CharT __c, size_type __pos = _Base::npos) const
00866       _GLIBCXX_NOEXCEPT
00867     { return _Base::find_last_of(__c, __pos); }
00868 
00869     size_type
00870     find_first_not_of(const basic_string& __str, size_type __pos = 0) const
00871       _GLIBCXX_NOEXCEPT
00872     { return _Base::find_first_not_of(__str, __pos); }
00873 
00874     size_type
00875     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00876     {
00877       __glibcxx_check_string_len(__s, __n);
00878       return _Base::find_first_not_of(__s, __pos, __n);
00879     }
00880 
00881     size_type
00882     find_first_not_of(const _CharT* __s, size_type __pos = 0) const
00883     {
00884       __glibcxx_check_string(__s);
00885       return _Base::find_first_not_of(__s, __pos);
00886     }
00887 
00888     size_type
00889     find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
00890     { return _Base::find_first_not_of(__c, __pos); }
00891 
00892     size_type
00893     find_last_not_of(const basic_string& __str,
00894                                   size_type __pos = _Base::npos) const
00895       _GLIBCXX_NOEXCEPT
00896     { return _Base::find_last_not_of(__str, __pos); }
00897 
00898     size_type
00899     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
00900     {
00901       __glibcxx_check_string(__s);
00902       return _Base::find_last_not_of(__s, __pos, __n);
00903     }
00904 
00905     size_type
00906     find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
00907     {
00908       __glibcxx_check_string(__s);
00909       return _Base::find_last_not_of(__s, __pos);
00910     }
00911 
00912     size_type
00913     find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const
00914       _GLIBCXX_NOEXCEPT
00915     { return _Base::find_last_not_of(__c, __pos); }
00916 
00917     basic_string
00918     substr(size_type __pos = 0, size_type __n = _Base::npos) const
00919     { return basic_string(_Base::substr(__pos, __n)); }
00920 
00921     int
00922     compare(const basic_string& __str) const
00923     { return _Base::compare(__str); }
00924 
00925     int
00926     compare(size_type __pos1, size_type __n1,
00927                   const basic_string& __str) const
00928     { return _Base::compare(__pos1, __n1, __str); }
00929 
00930     int
00931     compare(size_type __pos1, size_type __n1, const basic_string& __str,
00932               size_type __pos2, size_type __n2) const
00933     { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); }
00934 
00935     int
00936     compare(const _CharT* __s) const
00937     {
00938       __glibcxx_check_string(__s);
00939       return _Base::compare(__s);
00940     }
00941 
00942     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
00943     //  5. string::compare specification questionable
00944     int
00945     compare(size_type __pos1, size_type __n1, const _CharT* __s) const
00946     {
00947       __glibcxx_check_string(__s);
00948       return _Base::compare(__pos1, __n1, __s);
00949     }
00950 
00951     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
00952     //  5. string::compare specification questionable
00953     int
00954     compare(size_type __pos1, size_type __n1,const _CharT* __s,
00955             size_type __n2) const
00956     {
00957       __glibcxx_check_string_len(__s, __n2);
00958       return _Base::compare(__pos1, __n1, __s, __n2);
00959     }
00960 
00961     _Base&
00962     _M_base() _GLIBCXX_NOEXCEPT         { return *this; }
00963 
00964     const _Base&
00965     _M_base() const _GLIBCXX_NOEXCEPT   { return *this; }
00966 
00967     using _Safe::_M_invalidate_all;
00968   };
00969 
00970   template<typename _CharT, typename _Traits, typename _Allocator>
00971     inline basic_string<_CharT,_Traits,_Allocator>
00972     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00973               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00974     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
00975 
00976   template<typename _CharT, typename _Traits, typename _Allocator>
00977     inline basic_string<_CharT,_Traits,_Allocator>
00978     operator+(const _CharT* __lhs,
00979               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00980     {
00981       __glibcxx_check_string(__lhs);
00982       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
00983     }
00984 
00985   template<typename _CharT, typename _Traits, typename _Allocator>
00986     inline basic_string<_CharT,_Traits,_Allocator>
00987     operator+(_CharT __lhs,
00988               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
00989     { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; }
00990 
00991   template<typename _CharT, typename _Traits, typename _Allocator>
00992     inline basic_string<_CharT,_Traits,_Allocator>
00993     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
00994               const _CharT* __rhs)
00995     {
00996       __glibcxx_check_string(__rhs);
00997       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
00998     }
00999 
01000   template<typename _CharT, typename _Traits, typename _Allocator>
01001     inline basic_string<_CharT,_Traits,_Allocator>
01002     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01003               _CharT __rhs)
01004     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
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   template<typename _CharT, typename _Traits, typename _Allocator>
01103     inline bool
01104     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01105                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01106     { return __lhs._M_base() >= __rhs._M_base(); }
01107 
01108   template<typename _CharT, typename _Traits, typename _Allocator>
01109     inline bool
01110     operator>=(const _CharT* __lhs,
01111                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01112     {
01113       __glibcxx_check_string(__lhs);
01114       return __lhs >= __rhs._M_base();
01115     }
01116 
01117   template<typename _CharT, typename _Traits, typename _Allocator>
01118     inline bool
01119     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01120                const _CharT* __rhs)
01121     {
01122       __glibcxx_check_string(__rhs);
01123       return __lhs._M_base() >= __rhs;
01124     }
01125 
01126   template<typename _CharT, typename _Traits, typename _Allocator>
01127     inline bool
01128     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01129               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01130     { return __lhs._M_base() > __rhs._M_base(); }
01131 
01132   template<typename _CharT, typename _Traits, typename _Allocator>
01133     inline bool
01134     operator>(const _CharT* __lhs,
01135               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
01136     {
01137       __glibcxx_check_string(__lhs);
01138       return __lhs > __rhs._M_base();
01139     }
01140 
01141   template<typename _CharT, typename _Traits, typename _Allocator>
01142     inline bool
01143     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
01144               const _CharT* __rhs)
01145     {
01146       __glibcxx_check_string(__rhs);
01147       return __lhs._M_base() > __rhs;
01148     }
01149 
01150   // 21.3.7.8:
01151   template<typename _CharT, typename _Traits, typename _Allocator>
01152     inline void
01153     swap(basic_string<_CharT,_Traits,_Allocator>& __lhs,
01154          basic_string<_CharT,_Traits,_Allocator>& __rhs)
01155     { __lhs.swap(__rhs); }
01156 
01157   template<typename _CharT, typename _Traits, typename _Allocator>
01158     std::basic_ostream<_CharT, _Traits>&
01159     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
01160                const basic_string<_CharT, _Traits, _Allocator>& __str)
01161     { return __os << __str._M_base(); }
01162 
01163   template<typename _CharT, typename _Traits, typename _Allocator>
01164     std::basic_istream<_CharT,_Traits>&
01165     operator>>(std::basic_istream<_CharT,_Traits>& __is,
01166                basic_string<_CharT,_Traits,_Allocator>& __str)
01167     {
01168       std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
01169       __str._M_invalidate_all();
01170       return __res;
01171     }
01172 
01173   template<typename _CharT, typename _Traits, typename _Allocator>
01174     std::basic_istream<_CharT,_Traits>&
01175     getline(std::basic_istream<_CharT,_Traits>& __is,
01176             basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
01177     {
01178       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
01179                                                           __str._M_base(),
01180                                                         __delim);
01181       __str._M_invalidate_all();
01182       return __res;
01183     }
01184 
01185   template<typename _CharT, typename _Traits, typename _Allocator>
01186     std::basic_istream<_CharT,_Traits>&
01187     getline(std::basic_istream<_CharT,_Traits>& __is,
01188             basic_string<_CharT,_Traits,_Allocator>& __str)
01189     {
01190       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
01191                                                           __str._M_base());
01192       __str._M_invalidate_all();
01193       return __res;
01194     }
01195 
01196   typedef basic_string<char>    string;
01197 
01198 #ifdef _GLIBCXX_USE_WCHAR_T
01199   typedef basic_string<wchar_t> wstring;
01200 #endif
01201 
01202   template<typename _CharT, typename _Traits, typename _Allocator>
01203     struct _Insert_range_from_self_is_safe<
01204       __gnu_debug::basic_string<_CharT, _Traits, _Allocator> >
01205       { enum { __value = 1 }; };
01206 
01207 } // namespace __gnu_debug
01208 
01209 #endif