Home | History | Annotate | Line # | Download | only in debug
string revision 1.1.1.7
      1 // Debugging string implementation -*- C++ -*-
      2 
      3 // Copyright (C) 2003-2017 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file debug/string
     26  *  This file is a GNU debug extension to the Standard C++ Library.
     27  */
     28 
     29 #ifndef _GLIBCXX_DEBUG_STRING
     30 #define _GLIBCXX_DEBUG_STRING 1
     31 
     32 #pragma GCC system_header
     33 
     34 #include <string>
     35 #include <debug/safe_sequence.h>
     36 #include <debug/safe_container.h>
     37 #include <debug/safe_iterator.h>
     38 
     39 namespace __gnu_debug
     40 {
     41 /// Class std::basic_string with safety/checking/debug instrumentation.
     42 template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
     43 	 typename _Allocator = std::allocator<_CharT> >
     44   class basic_string
     45   : public __gnu_debug::_Safe_container<
     46       basic_string<_CharT, _Traits, _Allocator>,
     47       _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>,
     48     public std::basic_string<_CharT, _Traits, _Allocator>
     49   {
     50     typedef std::basic_string<_CharT, _Traits, _Allocator>	_Base;
     51     typedef __gnu_debug::_Safe_container<
     52       basic_string, _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>
     53       _Safe;
     54 
     55   public:
     56     // types:
     57     typedef _Traits					traits_type;
     58     typedef typename _Traits::char_type			value_type;
     59     typedef _Allocator					allocator_type;
     60     typedef typename _Base::size_type			size_type;
     61     typedef typename _Base::difference_type		difference_type;
     62     typedef typename _Base::reference			reference;
     63     typedef typename _Base::const_reference		const_reference;
     64     typedef typename _Base::pointer			pointer;
     65     typedef typename _Base::const_pointer		const_pointer;
     66 
     67     typedef __gnu_debug::_Safe_iterator<
     68       typename _Base::iterator, basic_string>		iterator;
     69     typedef __gnu_debug::_Safe_iterator<
     70       typename _Base::const_iterator, basic_string>	const_iterator;
     71 
     72     typedef std::reverse_iterator<iterator>		reverse_iterator;
     73     typedef std::reverse_iterator<const_iterator>	const_reverse_iterator;
     74 
     75     using _Base::npos;
     76 
     77     basic_string()
     78     _GLIBCXX_NOEXCEPT_IF(std::is_nothrow_default_constructible<_Base>::value)
     79     : _Base() { }
     80 
     81     // 21.3.1 construct/copy/destroy:
     82     explicit
     83     basic_string(const _Allocator& __a) _GLIBCXX_NOEXCEPT
     84     : _Base(__a) { }
     85 
     86 #if __cplusplus < 201103L
     87     basic_string(const basic_string& __str)
     88     : _Base(__str) { }
     89 
     90     ~basic_string() { }
     91 #else
     92     basic_string(const basic_string&) = default;
     93     basic_string(basic_string&&) = default;
     94 
     95     basic_string(std::initializer_list<_CharT> __l,
     96 		 const _Allocator& __a = _Allocator())
     97     : _Base(__l, __a)
     98     { }
     99 
    100 #if _GLIBCXX_USE_CXX11_ABI
    101     basic_string(const basic_string& __s, const _Allocator& __a)
    102     : _Base(__s, __a) { }
    103 
    104     basic_string(basic_string&& __s, const _Allocator& __a)
    105     : _Base(std::move(__s), __a) { }
    106 #endif
    107 
    108     ~basic_string() = default;
    109 
    110     // Provides conversion from a normal-mode string to a debug-mode string
    111     basic_string(_Base&& __base) noexcept
    112     : _Base(std::move(__base)) { }
    113 #endif // C++11
    114 
    115     // Provides conversion from a normal-mode string to a debug-mode string
    116     basic_string(const _Base& __base)
    117     : _Base(__base) { }
    118 
    119     // _GLIBCXX_RESOLVE_LIB_DEFECTS
    120     // 42. string ctors specify wrong default allocator
    121     basic_string(const basic_string& __str, size_type __pos,
    122 		 size_type __n = _Base::npos,
    123 		 const _Allocator& __a = _Allocator())
    124     : _Base(__str, __pos, __n, __a) { }
    125 
    126     basic_string(const _CharT* __s, size_type __n,
    127 		   const _Allocator& __a = _Allocator())
    128     : _Base(__gnu_debug::__check_string(__s, __n), __n, __a) { }
    129 
    130     basic_string(const _CharT* __s, const _Allocator& __a = _Allocator())
    131     : _Base(__gnu_debug::__check_string(__s), __a)
    132     { this->assign(__s); }
    133 
    134     basic_string(size_type __n, _CharT __c,
    135 		   const _Allocator& __a = _Allocator())
    136     : _Base(__n, __c, __a) { }
    137 
    138     template<typename _InputIterator>
    139       basic_string(_InputIterator __begin, _InputIterator __end,
    140 		   const _Allocator& __a = _Allocator())
    141       : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__begin,
    142 								   __end)),
    143 	      __gnu_debug::__base(__end), __a) { }
    144 
    145 #if __cplusplus < 201103L
    146     basic_string&
    147     operator=(const basic_string& __str)
    148     {
    149       this->_M_safe() = __str;
    150       _M_base() = __str;
    151       return *this;
    152     }
    153 #else
    154     basic_string&
    155     operator=(const basic_string&) = default;
    156 
    157     basic_string&
    158     operator=(basic_string&&) = default;
    159 #endif
    160 
    161     basic_string&
    162     operator=(const _CharT* __s)
    163     {
    164       __glibcxx_check_string(__s);
    165       _M_base() = __s;
    166       this->_M_invalidate_all();
    167       return *this;
    168     }
    169 
    170     basic_string&
    171     operator=(_CharT __c)
    172     {
    173       _M_base() = __c;
    174       this->_M_invalidate_all();
    175       return *this;
    176     }
    177 
    178 #if __cplusplus >= 201103L
    179     basic_string&
    180     operator=(std::initializer_list<_CharT> __l)
    181     {
    182       _M_base() = __l;
    183       this->_M_invalidate_all();
    184       return *this;
    185     }
    186 #endif // C++11
    187 
    188     // 21.3.2 iterators:
    189     iterator
    190     begin() // _GLIBCXX_NOEXCEPT
    191     { return iterator(_Base::begin(), this); }
    192 
    193     const_iterator
    194     begin() const _GLIBCXX_NOEXCEPT
    195     { return const_iterator(_Base::begin(), this); }
    196 
    197     iterator
    198     end() // _GLIBCXX_NOEXCEPT
    199     { return iterator(_Base::end(), this); }
    200 
    201     const_iterator
    202     end() const _GLIBCXX_NOEXCEPT
    203     { return const_iterator(_Base::end(), this); }
    204 
    205     reverse_iterator
    206     rbegin() // _GLIBCXX_NOEXCEPT
    207     { return reverse_iterator(end()); }
    208 
    209     const_reverse_iterator
    210     rbegin() const _GLIBCXX_NOEXCEPT
    211     { return const_reverse_iterator(end()); }
    212 
    213     reverse_iterator
    214     rend() // _GLIBCXX_NOEXCEPT
    215     { return reverse_iterator(begin()); }
    216 
    217     const_reverse_iterator
    218     rend() const _GLIBCXX_NOEXCEPT
    219     { return const_reverse_iterator(begin()); }
    220 
    221 #if __cplusplus >= 201103L
    222     const_iterator
    223     cbegin() const noexcept
    224     { return const_iterator(_Base::begin(), this); }
    225 
    226     const_iterator
    227     cend() const noexcept
    228     { return const_iterator(_Base::end(), this); }
    229 
    230     const_reverse_iterator
    231     crbegin() const noexcept
    232     { return const_reverse_iterator(end()); }
    233 
    234     const_reverse_iterator
    235     crend() const noexcept
    236     { return const_reverse_iterator(begin()); }
    237 #endif
    238 
    239     // 21.3.3 capacity:
    240     using _Base::size;
    241     using _Base::length;
    242     using _Base::max_size;
    243 
    244     void
    245     resize(size_type __n, _CharT __c)
    246     {
    247       _Base::resize(__n, __c);
    248       this->_M_invalidate_all();
    249     }
    250 
    251     void
    252     resize(size_type __n)
    253     { this->resize(__n, _CharT()); }
    254 
    255 #if __cplusplus >= 201103L
    256     void
    257     shrink_to_fit() noexcept
    258     {
    259       if (capacity() > size())
    260 	{
    261 	  __try
    262 	    {
    263 	      reserve(0);
    264 	      this->_M_invalidate_all();
    265 	    }
    266 	  __catch(...)
    267 	    { }
    268 	}
    269     }
    270 #endif
    271 
    272     using _Base::capacity;
    273     using _Base::reserve;
    274 
    275     void
    276     clear() // _GLIBCXX_NOEXCEPT
    277     {
    278       _Base::clear();
    279       this->_M_invalidate_all();
    280     }
    281 
    282     using _Base::empty;
    283 
    284     // 21.3.4 element access:
    285     const_reference
    286     operator[](size_type __pos) const _GLIBCXX_NOEXCEPT
    287     {
    288       _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
    289 			    _M_message(__gnu_debug::__msg_subscript_oob)
    290 			    ._M_sequence(*this, "this")
    291 			    ._M_integer(__pos, "__pos")
    292 			    ._M_integer(this->size(), "size"));
    293       return _M_base()[__pos];
    294     }
    295 
    296     reference
    297     operator[](size_type __pos) // _GLIBCXX_NOEXCEPT
    298     {
    299 #if __cplusplus < 201103L && defined(_GLIBCXX_DEBUG_PEDANTIC)
    300       __glibcxx_check_subscript(__pos);
    301 #else
    302       // as an extension v3 allows s[s.size()] when s is non-const.
    303       _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
    304 			    _M_message(__gnu_debug::__msg_subscript_oob)
    305 			    ._M_sequence(*this, "this")
    306 			    ._M_integer(__pos, "__pos")
    307 			    ._M_integer(this->size(), "size"));
    308 #endif
    309       return _M_base()[__pos];
    310     }
    311 
    312     using _Base::at;
    313 
    314 #if __cplusplus >= 201103L
    315     using _Base::front;
    316     using _Base::back;
    317 #endif
    318 
    319     // 21.3.5 modifiers:
    320     basic_string&
    321     operator+=(const basic_string& __str)
    322     {
    323       _M_base() += __str;
    324       this->_M_invalidate_all();
    325       return *this;
    326     }
    327 
    328     basic_string&
    329     operator+=(const _CharT* __s)
    330     {
    331       __glibcxx_check_string(__s);
    332       _M_base() += __s;
    333       this->_M_invalidate_all();
    334       return *this;
    335     }
    336 
    337     basic_string&
    338     operator+=(_CharT __c)
    339     {
    340       _M_base() += __c;
    341       this->_M_invalidate_all();
    342       return *this;
    343     }
    344 
    345 #if __cplusplus >= 201103L
    346     basic_string&
    347     operator+=(std::initializer_list<_CharT> __l)
    348     {
    349       _M_base() += __l;
    350       this->_M_invalidate_all();
    351       return *this;
    352     }
    353 #endif // C++11
    354 
    355     basic_string&
    356     append(const basic_string& __str)
    357     {
    358       _Base::append(__str);
    359       this->_M_invalidate_all();
    360       return *this;
    361     }
    362 
    363     basic_string&
    364     append(const basic_string& __str, size_type __pos, size_type __n)
    365     {
    366       _Base::append(__str, __pos, __n);
    367       this->_M_invalidate_all();
    368       return *this;
    369     }
    370 
    371     basic_string&
    372     append(const _CharT* __s, size_type __n)
    373     {
    374       __glibcxx_check_string_len(__s, __n);
    375       _Base::append(__s, __n);
    376       this->_M_invalidate_all();
    377       return *this;
    378     }
    379 
    380     basic_string&
    381     append(const _CharT* __s)
    382     {
    383       __glibcxx_check_string(__s);
    384       _Base::append(__s);
    385       this->_M_invalidate_all();
    386       return *this;
    387     }
    388 
    389     basic_string&
    390     append(size_type __n, _CharT __c)
    391     {
    392       _Base::append(__n, __c);
    393       this->_M_invalidate_all();
    394       return *this;
    395     }
    396 
    397     template<typename _InputIterator>
    398       basic_string&
    399       append(_InputIterator __first, _InputIterator __last)
    400       {
    401 	typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
    402 	__glibcxx_check_valid_range2(__first, __last, __dist);
    403 
    404 	if (__dist.second >= __dp_sign)
    405 	  _Base::append(__gnu_debug::__unsafe(__first),
    406 			__gnu_debug::__unsafe(__last));
    407 	else
    408 	  _Base::append(__first, __last);
    409 
    410 	this->_M_invalidate_all();
    411 	return *this;
    412       }
    413 
    414     // _GLIBCXX_RESOLVE_LIB_DEFECTS
    415     // 7. string clause minor problems
    416     void
    417     push_back(_CharT __c)
    418     {
    419       _Base::push_back(__c);
    420       this->_M_invalidate_all();
    421     }
    422 
    423     basic_string&
    424     assign(const basic_string& __x)
    425     {
    426       _Base::assign(__x);
    427       this->_M_invalidate_all();
    428       return *this;
    429     }
    430 
    431 #if __cplusplus >= 201103L
    432     basic_string&
    433     assign(basic_string&& __x)
    434     noexcept(noexcept(std::declval<_Base&>().assign(std::move(__x))))
    435     {
    436       _Base::assign(std::move(__x));
    437       this->_M_invalidate_all();
    438       return *this;
    439     }
    440 #endif // C++11
    441 
    442     basic_string&
    443     assign(const basic_string& __str, size_type __pos, size_type __n)
    444     {
    445       _Base::assign(__str, __pos, __n);
    446       this->_M_invalidate_all();
    447       return *this;
    448     }
    449 
    450     basic_string&
    451     assign(const _CharT* __s, size_type __n)
    452     {
    453       __glibcxx_check_string_len(__s, __n);
    454       _Base::assign(__s, __n);
    455       this->_M_invalidate_all();
    456       return *this;
    457     }
    458 
    459     basic_string&
    460     assign(const _CharT* __s)
    461     {
    462       __glibcxx_check_string(__s);
    463       _Base::assign(__s);
    464       this->_M_invalidate_all();
    465       return *this;
    466     }
    467 
    468     basic_string&
    469     assign(size_type __n, _CharT __c)
    470     {
    471       _Base::assign(__n, __c);
    472       this->_M_invalidate_all();
    473       return *this;
    474     }
    475 
    476     template<typename _InputIterator>
    477       basic_string&
    478       assign(_InputIterator __first, _InputIterator __last)
    479       {
    480 	typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
    481 	__glibcxx_check_valid_range2(__first, __last, __dist);
    482 
    483 	if (__dist.second >= __dp_sign)
    484 	  _Base::assign(__gnu_debug::__unsafe(__first),
    485 			__gnu_debug::__unsafe(__last));
    486 	else
    487 	  _Base::assign(__first, __last);
    488 
    489 	this->_M_invalidate_all();
    490 	return *this;
    491       }
    492 
    493 #if __cplusplus >= 201103L
    494     basic_string&
    495     assign(std::initializer_list<_CharT> __l)
    496     {
    497       _Base::assign(__l);
    498       this->_M_invalidate_all();
    499       return *this;
    500     }
    501 #endif // C++11
    502 
    503     basic_string&
    504     insert(size_type __pos1, const basic_string& __str)
    505     {
    506       _Base::insert(__pos1, __str);
    507       this->_M_invalidate_all();
    508       return *this;
    509     }
    510 
    511     basic_string&
    512     insert(size_type __pos1, const basic_string& __str,
    513 	   size_type __pos2, size_type __n)
    514     {
    515       _Base::insert(__pos1, __str, __pos2, __n);
    516       this->_M_invalidate_all();
    517       return *this;
    518     }
    519 
    520     basic_string&
    521     insert(size_type __pos, const _CharT* __s, size_type __n)
    522     {
    523       __glibcxx_check_string(__s);
    524       _Base::insert(__pos, __s, __n);
    525       this->_M_invalidate_all();
    526       return *this;
    527     }
    528 
    529     basic_string&
    530     insert(size_type __pos, const _CharT* __s)
    531     {
    532       __glibcxx_check_string(__s);
    533       _Base::insert(__pos, __s);
    534       this->_M_invalidate_all();
    535       return *this;
    536     }
    537 
    538     basic_string&
    539     insert(size_type __pos, size_type __n, _CharT __c)
    540     {
    541       _Base::insert(__pos, __n, __c);
    542       this->_M_invalidate_all();
    543       return *this;
    544     }
    545 
    546     iterator
    547     insert(iterator __p, _CharT __c)
    548     {
    549       __glibcxx_check_insert(__p);
    550       typename _Base::iterator __res = _Base::insert(__p.base(), __c);
    551       this->_M_invalidate_all();
    552       return iterator(__res, this);
    553     }
    554 
    555     void
    556     insert(iterator __p, size_type __n, _CharT __c)
    557     {
    558       __glibcxx_check_insert(__p);
    559       _Base::insert(__p.base(), __n, __c);
    560       this->_M_invalidate_all();
    561     }
    562 
    563     template<typename _InputIterator>
    564       void
    565       insert(iterator __p, _InputIterator __first, _InputIterator __last)
    566       {
    567 	typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
    568 	__glibcxx_check_insert_range(__p, __first, __last, __dist);
    569 
    570 	if (__dist.second >= __dp_sign)
    571 	  _Base::insert(__p.base(), __gnu_debug::__unsafe(__first),
    572 				    __gnu_debug::__unsafe(__last));
    573 	else
    574 	  _Base::insert(__p.base(), __first, __last);
    575 
    576 	this->_M_invalidate_all();
    577       }
    578 
    579 #if __cplusplus >= 201103L
    580     void
    581     insert(iterator __p, std::initializer_list<_CharT> __l)
    582     {
    583       __glibcxx_check_insert(__p);
    584       _Base::insert(__p.base(), __l);
    585       this->_M_invalidate_all();
    586     }
    587 #endif // C++11
    588 
    589     basic_string&
    590     erase(size_type __pos = 0, size_type __n = _Base::npos)
    591     {
    592       _Base::erase(__pos, __n);
    593       this->_M_invalidate_all();
    594       return *this;
    595     }
    596 
    597     iterator
    598     erase(iterator __position)
    599     {
    600       __glibcxx_check_erase(__position);
    601       typename _Base::iterator __res = _Base::erase(__position.base());
    602       this->_M_invalidate_all();
    603       return iterator(__res, this);
    604     }
    605 
    606     iterator
    607     erase(iterator __first, iterator __last)
    608     {
    609       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    610       // 151. can't currently clear() empty container
    611       __glibcxx_check_erase_range(__first, __last);
    612       typename _Base::iterator __res = _Base::erase(__first.base(),
    613 						    __last.base());
    614       this->_M_invalidate_all();
    615       return iterator(__res, this);
    616     }
    617 
    618 #if __cplusplus >= 201103L
    619     void
    620     pop_back() // noexcept
    621     {
    622       __glibcxx_check_nonempty();
    623       _Base::pop_back();
    624       this->_M_invalidate_all();
    625     }
    626 #endif // C++11
    627 
    628     basic_string&
    629     replace(size_type __pos1, size_type __n1, const basic_string& __str)
    630     {
    631       _Base::replace(__pos1, __n1, __str);
    632       this->_M_invalidate_all();
    633       return *this;
    634     }
    635 
    636     basic_string&
    637     replace(size_type __pos1, size_type __n1, const basic_string& __str,
    638 	    size_type __pos2, size_type __n2)
    639     {
    640       _Base::replace(__pos1, __n1, __str, __pos2, __n2);
    641       this->_M_invalidate_all();
    642       return *this;
    643     }
    644 
    645     basic_string&
    646     replace(size_type __pos, size_type __n1, const _CharT* __s,
    647 	    size_type __n2)
    648     {
    649       __glibcxx_check_string_len(__s, __n2);
    650       _Base::replace(__pos, __n1, __s, __n2);
    651       this->_M_invalidate_all();
    652       return *this;
    653     }
    654 
    655     basic_string&
    656     replace(size_type __pos, size_type __n1, const _CharT* __s)
    657     {
    658       __glibcxx_check_string(__s);
    659       _Base::replace(__pos, __n1, __s);
    660       this->_M_invalidate_all();
    661       return *this;
    662     }
    663 
    664     basic_string&
    665     replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
    666     {
    667       _Base::replace(__pos, __n1, __n2, __c);
    668       this->_M_invalidate_all();
    669       return *this;
    670     }
    671 
    672     basic_string&
    673     replace(iterator __i1, iterator __i2, const basic_string& __str)
    674     {
    675       __glibcxx_check_erase_range(__i1, __i2);
    676       _Base::replace(__i1.base(), __i2.base(), __str);
    677       this->_M_invalidate_all();
    678       return *this;
    679     }
    680 
    681     basic_string&
    682     replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
    683     {
    684       __glibcxx_check_erase_range(__i1, __i2);
    685       __glibcxx_check_string_len(__s, __n);
    686       _Base::replace(__i1.base(), __i2.base(), __s, __n);
    687       this->_M_invalidate_all();
    688       return *this;
    689     }
    690 
    691     basic_string&
    692     replace(iterator __i1, iterator __i2, const _CharT* __s)
    693     {
    694       __glibcxx_check_erase_range(__i1, __i2);
    695       __glibcxx_check_string(__s);
    696       _Base::replace(__i1.base(), __i2.base(), __s);
    697       this->_M_invalidate_all();
    698       return *this;
    699     }
    700 
    701     basic_string&
    702     replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
    703     {
    704       __glibcxx_check_erase_range(__i1, __i2);
    705       _Base::replace(__i1.base(), __i2.base(), __n, __c);
    706       this->_M_invalidate_all();
    707       return *this;
    708     }
    709 
    710     template<typename _InputIterator>
    711       basic_string&
    712       replace(iterator __i1, iterator __i2,
    713 	      _InputIterator __j1, _InputIterator __j2)
    714       {
    715 	__glibcxx_check_erase_range(__i1, __i2);
    716 
    717 	typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
    718 	__glibcxx_check_valid_range2(__j1, __j2, __dist);
    719 
    720 	if (__dist.second >= __dp_sign)
    721 	  _Base::replace(__i1.base(), __i2.base(),
    722 			 __gnu_debug::__unsafe(__j1),
    723 			 __gnu_debug::__unsafe(__j2));
    724 	else
    725 	  _Base::replace(__i1.base(), __i2.base(), __j1, __j2);
    726 
    727 	this->_M_invalidate_all();
    728 	return *this;
    729       }
    730 
    731 #if __cplusplus >= 201103L
    732       basic_string& replace(iterator __i1, iterator __i2,
    733 			    std::initializer_list<_CharT> __l)
    734       {
    735 	__glibcxx_check_erase_range(__i1, __i2);
    736 	_Base::replace(__i1.base(), __i2.base(), __l);
    737 	this->_M_invalidate_all();
    738 	return *this;
    739       }
    740 #endif // C++11
    741 
    742     size_type
    743     copy(_CharT* __s, size_type __n, size_type __pos = 0) const
    744     {
    745       __glibcxx_check_string_len(__s, __n);
    746       return _Base::copy(__s, __n, __pos);
    747     }
    748 
    749     void
    750     swap(basic_string& __x)
    751     _GLIBCXX_NOEXCEPT_IF(std::__is_nothrow_swappable<_Base>::value)
    752     {
    753       _Safe::_M_swap(__x);
    754       _Base::swap(__x);
    755     }
    756 
    757     // 21.3.6 string operations:
    758     const _CharT*
    759     c_str() const _GLIBCXX_NOEXCEPT
    760     {
    761       const _CharT* __res = _Base::c_str();
    762       this->_M_invalidate_all();
    763       return __res;
    764     }
    765 
    766     const _CharT*
    767     data() const _GLIBCXX_NOEXCEPT
    768     {
    769       const _CharT* __res = _Base::data();
    770       this->_M_invalidate_all();
    771       return __res;
    772     }
    773 
    774     using _Base::get_allocator;
    775 
    776     size_type
    777     find(const basic_string& __str, size_type __pos = 0) const
    778       _GLIBCXX_NOEXCEPT
    779     { return _Base::find(__str, __pos); }
    780 
    781     size_type
    782     find(const _CharT* __s, size_type __pos, size_type __n) const
    783     {
    784       __glibcxx_check_string(__s);
    785       return _Base::find(__s, __pos, __n);
    786     }
    787 
    788     size_type
    789     find(const _CharT* __s, size_type __pos = 0) const
    790     {
    791       __glibcxx_check_string(__s);
    792       return _Base::find(__s, __pos);
    793     }
    794 
    795     size_type
    796     find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
    797     { return _Base::find(__c, __pos); }
    798 
    799     size_type
    800     rfind(const basic_string& __str, size_type __pos = _Base::npos) const
    801       _GLIBCXX_NOEXCEPT
    802     { return _Base::rfind(__str, __pos); }
    803 
    804     size_type
    805     rfind(const _CharT* __s, size_type __pos, size_type __n) const
    806     {
    807       __glibcxx_check_string_len(__s, __n);
    808       return _Base::rfind(__s, __pos, __n);
    809     }
    810 
    811     size_type
    812     rfind(const _CharT* __s, size_type __pos = _Base::npos) const
    813     {
    814       __glibcxx_check_string(__s);
    815       return _Base::rfind(__s, __pos);
    816     }
    817 
    818     size_type
    819     rfind(_CharT __c, size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
    820     { return _Base::rfind(__c, __pos); }
    821 
    822     size_type
    823     find_first_of(const basic_string& __str, size_type __pos = 0) const
    824       _GLIBCXX_NOEXCEPT
    825     { return _Base::find_first_of(__str, __pos); }
    826 
    827     size_type
    828     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
    829     {
    830       __glibcxx_check_string(__s);
    831       return _Base::find_first_of(__s, __pos, __n);
    832     }
    833 
    834     size_type
    835     find_first_of(const _CharT* __s, size_type __pos = 0) const
    836     {
    837       __glibcxx_check_string(__s);
    838       return _Base::find_first_of(__s, __pos);
    839     }
    840 
    841     size_type
    842     find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
    843     { return _Base::find_first_of(__c, __pos); }
    844 
    845     size_type
    846     find_last_of(const basic_string& __str,
    847 		 size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
    848     { return _Base::find_last_of(__str, __pos); }
    849 
    850     size_type
    851     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
    852     {
    853       __glibcxx_check_string(__s);
    854       return _Base::find_last_of(__s, __pos, __n);
    855     }
    856 
    857     size_type
    858     find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
    859     {
    860       __glibcxx_check_string(__s);
    861       return _Base::find_last_of(__s, __pos);
    862     }
    863 
    864     size_type
    865     find_last_of(_CharT __c, size_type __pos = _Base::npos) const
    866       _GLIBCXX_NOEXCEPT
    867     { return _Base::find_last_of(__c, __pos); }
    868 
    869     size_type
    870     find_first_not_of(const basic_string& __str, size_type __pos = 0) const
    871       _GLIBCXX_NOEXCEPT
    872     { return _Base::find_first_not_of(__str, __pos); }
    873 
    874     size_type
    875     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
    876     {
    877       __glibcxx_check_string_len(__s, __n);
    878       return _Base::find_first_not_of(__s, __pos, __n);
    879     }
    880 
    881     size_type
    882     find_first_not_of(const _CharT* __s, size_type __pos = 0) const
    883     {
    884       __glibcxx_check_string(__s);
    885       return _Base::find_first_not_of(__s, __pos);
    886     }
    887 
    888     size_type
    889     find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
    890     { return _Base::find_first_not_of(__c, __pos); }
    891 
    892     size_type
    893     find_last_not_of(const basic_string& __str,
    894 				  size_type __pos = _Base::npos) const
    895       _GLIBCXX_NOEXCEPT
    896     { return _Base::find_last_not_of(__str, __pos); }
    897 
    898     size_type
    899     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
    900     {
    901       __glibcxx_check_string(__s);
    902       return _Base::find_last_not_of(__s, __pos, __n);
    903     }
    904 
    905     size_type
    906     find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
    907     {
    908       __glibcxx_check_string(__s);
    909       return _Base::find_last_not_of(__s, __pos);
    910     }
    911 
    912     size_type
    913     find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const
    914       _GLIBCXX_NOEXCEPT
    915     { return _Base::find_last_not_of(__c, __pos); }
    916 
    917     basic_string
    918     substr(size_type __pos = 0, size_type __n = _Base::npos) const
    919     { return basic_string(_Base::substr(__pos, __n)); }
    920 
    921     int
    922     compare(const basic_string& __str) const
    923     { return _Base::compare(__str); }
    924 
    925     int
    926     compare(size_type __pos1, size_type __n1,
    927 		  const basic_string& __str) const
    928     { return _Base::compare(__pos1, __n1, __str); }
    929 
    930     int
    931     compare(size_type __pos1, size_type __n1, const basic_string& __str,
    932 	      size_type __pos2, size_type __n2) const
    933     { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); }
    934 
    935     int
    936     compare(const _CharT* __s) const
    937     {
    938       __glibcxx_check_string(__s);
    939       return _Base::compare(__s);
    940     }
    941 
    942     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
    943     //  5. string::compare specification questionable
    944     int
    945     compare(size_type __pos1, size_type __n1, const _CharT* __s) const
    946     {
    947       __glibcxx_check_string(__s);
    948       return _Base::compare(__pos1, __n1, __s);
    949     }
    950 
    951     //  _GLIBCXX_RESOLVE_LIB_DEFECTS
    952     //  5. string::compare specification questionable
    953     int
    954     compare(size_type __pos1, size_type __n1,const _CharT* __s,
    955 	    size_type __n2) const
    956     {
    957       __glibcxx_check_string_len(__s, __n2);
    958       return _Base::compare(__pos1, __n1, __s, __n2);
    959     }
    960 
    961     _Base&
    962     _M_base() _GLIBCXX_NOEXCEPT		{ return *this; }
    963 
    964     const _Base&
    965     _M_base() const _GLIBCXX_NOEXCEPT	{ return *this; }
    966 
    967     using _Safe::_M_invalidate_all;
    968   };
    969 
    970   template<typename _CharT, typename _Traits, typename _Allocator>
    971     inline basic_string<_CharT,_Traits,_Allocator>
    972     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
    973 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    974     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
    975 
    976   template<typename _CharT, typename _Traits, typename _Allocator>
    977     inline basic_string<_CharT,_Traits,_Allocator>
    978     operator+(const _CharT* __lhs,
    979 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    980     {
    981       __glibcxx_check_string(__lhs);
    982       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
    983     }
    984 
    985   template<typename _CharT, typename _Traits, typename _Allocator>
    986     inline basic_string<_CharT,_Traits,_Allocator>
    987     operator+(_CharT __lhs,
    988 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
    989     { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; }
    990 
    991   template<typename _CharT, typename _Traits, typename _Allocator>
    992     inline basic_string<_CharT,_Traits,_Allocator>
    993     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
    994 	      const _CharT* __rhs)
    995     {
    996       __glibcxx_check_string(__rhs);
    997       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
    998     }
    999 
   1000   template<typename _CharT, typename _Traits, typename _Allocator>
   1001     inline basic_string<_CharT,_Traits,_Allocator>
   1002     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1003 	      _CharT __rhs)
   1004     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
   1005 
   1006   template<typename _CharT, typename _Traits, typename _Allocator>
   1007     inline bool
   1008     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1009 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1010     { return __lhs._M_base() == __rhs._M_base(); }
   1011 
   1012   template<typename _CharT, typename _Traits, typename _Allocator>
   1013     inline bool
   1014     operator==(const _CharT* __lhs,
   1015 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1016     {
   1017       __glibcxx_check_string(__lhs);
   1018       return __lhs == __rhs._M_base();
   1019     }
   1020 
   1021   template<typename _CharT, typename _Traits, typename _Allocator>
   1022     inline bool
   1023     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1024 	       const _CharT* __rhs)
   1025     {
   1026       __glibcxx_check_string(__rhs);
   1027       return __lhs._M_base() == __rhs;
   1028     }
   1029 
   1030   template<typename _CharT, typename _Traits, typename _Allocator>
   1031     inline bool
   1032     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1033 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1034     { return __lhs._M_base() != __rhs._M_base(); }
   1035 
   1036   template<typename _CharT, typename _Traits, typename _Allocator>
   1037     inline bool
   1038     operator!=(const _CharT* __lhs,
   1039 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1040     {
   1041       __glibcxx_check_string(__lhs);
   1042       return __lhs != __rhs._M_base();
   1043     }
   1044 
   1045   template<typename _CharT, typename _Traits, typename _Allocator>
   1046     inline bool
   1047     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1048 	       const _CharT* __rhs)
   1049     {
   1050       __glibcxx_check_string(__rhs);
   1051       return __lhs._M_base() != __rhs;
   1052     }
   1053 
   1054   template<typename _CharT, typename _Traits, typename _Allocator>
   1055     inline bool
   1056     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1057 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1058     { return __lhs._M_base() < __rhs._M_base(); }
   1059 
   1060   template<typename _CharT, typename _Traits, typename _Allocator>
   1061     inline bool
   1062     operator<(const _CharT* __lhs,
   1063 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1064     {
   1065       __glibcxx_check_string(__lhs);
   1066       return __lhs < __rhs._M_base();
   1067     }
   1068 
   1069   template<typename _CharT, typename _Traits, typename _Allocator>
   1070     inline bool
   1071     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1072 	      const _CharT* __rhs)
   1073     {
   1074       __glibcxx_check_string(__rhs);
   1075       return __lhs._M_base() < __rhs;
   1076     }
   1077 
   1078   template<typename _CharT, typename _Traits, typename _Allocator>
   1079     inline bool
   1080     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1081 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1082     { return __lhs._M_base() <= __rhs._M_base(); }
   1083 
   1084   template<typename _CharT, typename _Traits, typename _Allocator>
   1085     inline bool
   1086     operator<=(const _CharT* __lhs,
   1087 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1088     {
   1089       __glibcxx_check_string(__lhs);
   1090       return __lhs <= __rhs._M_base();
   1091     }
   1092 
   1093   template<typename _CharT, typename _Traits, typename _Allocator>
   1094     inline bool
   1095     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1096 	       const _CharT* __rhs)
   1097     {
   1098       __glibcxx_check_string(__rhs);
   1099       return __lhs._M_base() <= __rhs;
   1100     }
   1101 
   1102   template<typename _CharT, typename _Traits, typename _Allocator>
   1103     inline bool
   1104     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1105 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1106     { return __lhs._M_base() >= __rhs._M_base(); }
   1107 
   1108   template<typename _CharT, typename _Traits, typename _Allocator>
   1109     inline bool
   1110     operator>=(const _CharT* __lhs,
   1111 	       const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1112     {
   1113       __glibcxx_check_string(__lhs);
   1114       return __lhs >= __rhs._M_base();
   1115     }
   1116 
   1117   template<typename _CharT, typename _Traits, typename _Allocator>
   1118     inline bool
   1119     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1120 	       const _CharT* __rhs)
   1121     {
   1122       __glibcxx_check_string(__rhs);
   1123       return __lhs._M_base() >= __rhs;
   1124     }
   1125 
   1126   template<typename _CharT, typename _Traits, typename _Allocator>
   1127     inline bool
   1128     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1129 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1130     { return __lhs._M_base() > __rhs._M_base(); }
   1131 
   1132   template<typename _CharT, typename _Traits, typename _Allocator>
   1133     inline bool
   1134     operator>(const _CharT* __lhs,
   1135 	      const basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1136     {
   1137       __glibcxx_check_string(__lhs);
   1138       return __lhs > __rhs._M_base();
   1139     }
   1140 
   1141   template<typename _CharT, typename _Traits, typename _Allocator>
   1142     inline bool
   1143     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1144 	      const _CharT* __rhs)
   1145     {
   1146       __glibcxx_check_string(__rhs);
   1147       return __lhs._M_base() > __rhs;
   1148     }
   1149 
   1150   // 21.3.7.8:
   1151   template<typename _CharT, typename _Traits, typename _Allocator>
   1152     inline void
   1153     swap(basic_string<_CharT,_Traits,_Allocator>& __lhs,
   1154 	 basic_string<_CharT,_Traits,_Allocator>& __rhs)
   1155     { __lhs.swap(__rhs); }
   1156 
   1157   template<typename _CharT, typename _Traits, typename _Allocator>
   1158     std::basic_ostream<_CharT, _Traits>&
   1159     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
   1160 	       const basic_string<_CharT, _Traits, _Allocator>& __str)
   1161     { return __os << __str._M_base(); }
   1162 
   1163   template<typename _CharT, typename _Traits, typename _Allocator>
   1164     std::basic_istream<_CharT,_Traits>&
   1165     operator>>(std::basic_istream<_CharT,_Traits>& __is,
   1166 	       basic_string<_CharT,_Traits,_Allocator>& __str)
   1167     {
   1168       std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
   1169       __str._M_invalidate_all();
   1170       return __res;
   1171     }
   1172 
   1173   template<typename _CharT, typename _Traits, typename _Allocator>
   1174     std::basic_istream<_CharT,_Traits>&
   1175     getline(std::basic_istream<_CharT,_Traits>& __is,
   1176 	    basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
   1177     {
   1178       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
   1179 							  __str._M_base(),
   1180 							__delim);
   1181       __str._M_invalidate_all();
   1182       return __res;
   1183     }
   1184 
   1185   template<typename _CharT, typename _Traits, typename _Allocator>
   1186     std::basic_istream<_CharT,_Traits>&
   1187     getline(std::basic_istream<_CharT,_Traits>& __is,
   1188 	    basic_string<_CharT,_Traits,_Allocator>& __str)
   1189     {
   1190       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
   1191 							  __str._M_base());
   1192       __str._M_invalidate_all();
   1193       return __res;
   1194     }
   1195 
   1196   typedef basic_string<char>    string;
   1197 
   1198 #ifdef _GLIBCXX_USE_WCHAR_T
   1199   typedef basic_string<wchar_t> wstring;
   1200 #endif
   1201 
   1202   template<typename _CharT, typename _Traits, typename _Allocator>
   1203     struct _Insert_range_from_self_is_safe<
   1204       __gnu_debug::basic_string<_CharT, _Traits, _Allocator> >
   1205       { enum { __value = 1 }; };
   1206 
   1207 } // namespace __gnu_debug
   1208 
   1209 #endif
   1210