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