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