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