xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/basic_string.tcc (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg // Components for manipulating sequences of characters -*- C++ -*-
21debfc3dSmrg 
3*8feb0f0bSmrg // Copyright (C) 1997-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library.  This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg 
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg 
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg 
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg 
251debfc3dSmrg /** @file bits/basic_string.tcc
261debfc3dSmrg  *  This is an internal header file, included by other library headers.
271debfc3dSmrg  *  Do not attempt to use it directly. @headername{string}
281debfc3dSmrg  */
291debfc3dSmrg 
301debfc3dSmrg //
311debfc3dSmrg // ISO C++ 14882: 21  Strings library
321debfc3dSmrg //
331debfc3dSmrg 
341debfc3dSmrg // Written by Jason Merrill based upon the specification by Takanori Adachi
351debfc3dSmrg // in ANSI X3J16/94-0013R2.  Rewritten by Nathan Myers to ISO-14882.
361debfc3dSmrg // Non-reference-counted implementation written by Paolo Carlini and
371debfc3dSmrg // updated by Jonathan Wakely for ISO-14882-2011.
381debfc3dSmrg 
391debfc3dSmrg #ifndef _BASIC_STRING_TCC
401debfc3dSmrg #define _BASIC_STRING_TCC 1
411debfc3dSmrg 
421debfc3dSmrg #pragma GCC system_header
431debfc3dSmrg 
441debfc3dSmrg #include <bits/cxxabi_forced.h>
451debfc3dSmrg 
461debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
471debfc3dSmrg {
481debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
491debfc3dSmrg 
501debfc3dSmrg #if _GLIBCXX_USE_CXX11_ABI
511debfc3dSmrg 
521debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
531debfc3dSmrg     const typename basic_string<_CharT, _Traits, _Alloc>::size_type
541debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::npos;
551debfc3dSmrg 
561debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
571debfc3dSmrg     void
581debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
swap(basic_string & __s)591debfc3dSmrg     swap(basic_string& __s) _GLIBCXX_NOEXCEPT
601debfc3dSmrg     {
611debfc3dSmrg       if (this == &__s)
621debfc3dSmrg 	return;
631debfc3dSmrg 
641debfc3dSmrg       _Alloc_traits::_S_on_swap(_M_get_allocator(), __s._M_get_allocator());
651debfc3dSmrg 
661debfc3dSmrg       if (_M_is_local())
671debfc3dSmrg 	if (__s._M_is_local())
681debfc3dSmrg 	  {
691debfc3dSmrg 	    if (length() && __s.length())
701debfc3dSmrg 	      {
711debfc3dSmrg 		_CharT __tmp_data[_S_local_capacity + 1];
721debfc3dSmrg 		traits_type::copy(__tmp_data, __s._M_local_buf,
731debfc3dSmrg 				  _S_local_capacity + 1);
741debfc3dSmrg 		traits_type::copy(__s._M_local_buf, _M_local_buf,
751debfc3dSmrg 				  _S_local_capacity + 1);
761debfc3dSmrg 		traits_type::copy(_M_local_buf, __tmp_data,
771debfc3dSmrg 				  _S_local_capacity + 1);
781debfc3dSmrg 	      }
791debfc3dSmrg 	    else if (__s.length())
801debfc3dSmrg 	      {
811debfc3dSmrg 		traits_type::copy(_M_local_buf, __s._M_local_buf,
821debfc3dSmrg 				  _S_local_capacity + 1);
831debfc3dSmrg 		_M_length(__s.length());
841debfc3dSmrg 		__s._M_set_length(0);
851debfc3dSmrg 		return;
861debfc3dSmrg 	      }
871debfc3dSmrg 	    else if (length())
881debfc3dSmrg 	      {
891debfc3dSmrg 		traits_type::copy(__s._M_local_buf, _M_local_buf,
901debfc3dSmrg 				  _S_local_capacity + 1);
911debfc3dSmrg 		__s._M_length(length());
921debfc3dSmrg 		_M_set_length(0);
931debfc3dSmrg 		return;
941debfc3dSmrg 	      }
951debfc3dSmrg 	  }
961debfc3dSmrg 	else
971debfc3dSmrg 	  {
981debfc3dSmrg 	    const size_type __tmp_capacity = __s._M_allocated_capacity;
991debfc3dSmrg 	    traits_type::copy(__s._M_local_buf, _M_local_buf,
1001debfc3dSmrg 			      _S_local_capacity + 1);
1011debfc3dSmrg 	    _M_data(__s._M_data());
1021debfc3dSmrg 	    __s._M_data(__s._M_local_buf);
1031debfc3dSmrg 	    _M_capacity(__tmp_capacity);
1041debfc3dSmrg 	  }
1051debfc3dSmrg       else
1061debfc3dSmrg 	{
1071debfc3dSmrg 	  const size_type __tmp_capacity = _M_allocated_capacity;
1081debfc3dSmrg 	  if (__s._M_is_local())
1091debfc3dSmrg 	    {
1101debfc3dSmrg 	      traits_type::copy(_M_local_buf, __s._M_local_buf,
1111debfc3dSmrg 				_S_local_capacity + 1);
1121debfc3dSmrg 	      __s._M_data(_M_data());
1131debfc3dSmrg 	      _M_data(_M_local_buf);
1141debfc3dSmrg 	    }
1151debfc3dSmrg 	  else
1161debfc3dSmrg 	    {
1171debfc3dSmrg 	      pointer __tmp_ptr = _M_data();
1181debfc3dSmrg 	      _M_data(__s._M_data());
1191debfc3dSmrg 	      __s._M_data(__tmp_ptr);
1201debfc3dSmrg 	      _M_capacity(__s._M_allocated_capacity);
1211debfc3dSmrg 	    }
1221debfc3dSmrg 	  __s._M_capacity(__tmp_capacity);
1231debfc3dSmrg 	}
1241debfc3dSmrg 
1251debfc3dSmrg       const size_type __tmp_length = length();
1261debfc3dSmrg       _M_length(__s.length());
1271debfc3dSmrg       __s._M_length(__tmp_length);
1281debfc3dSmrg     }
1291debfc3dSmrg 
1301debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
1311debfc3dSmrg     typename basic_string<_CharT, _Traits, _Alloc>::pointer
1321debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
_M_create(size_type & __capacity,size_type __old_capacity)1331debfc3dSmrg     _M_create(size_type& __capacity, size_type __old_capacity)
1341debfc3dSmrg     {
1351debfc3dSmrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
1361debfc3dSmrg       // 83.  String::npos vs. string::max_size()
1371debfc3dSmrg       if (__capacity > max_size())
1381debfc3dSmrg 	std::__throw_length_error(__N("basic_string::_M_create"));
1391debfc3dSmrg 
1401debfc3dSmrg       // The below implements an exponential growth policy, necessary to
1411debfc3dSmrg       // meet amortized linear time requirements of the library: see
1421debfc3dSmrg       // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
1431debfc3dSmrg       if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
1441debfc3dSmrg 	{
1451debfc3dSmrg 	  __capacity = 2 * __old_capacity;
1461debfc3dSmrg 	  // Never allocate a string bigger than max_size.
1471debfc3dSmrg 	  if (__capacity > max_size())
1481debfc3dSmrg 	    __capacity = max_size();
1491debfc3dSmrg 	}
1501debfc3dSmrg 
1511debfc3dSmrg       // NB: Need an array of char_type[__capacity], plus a terminating
1521debfc3dSmrg       // null char_type() element.
1531debfc3dSmrg       return _Alloc_traits::allocate(_M_get_allocator(), __capacity + 1);
1541debfc3dSmrg     }
1551debfc3dSmrg 
1561debfc3dSmrg   // NB: This is the special case for Input Iterators, used in
1571debfc3dSmrg   // istreambuf_iterators, etc.
1581debfc3dSmrg   // Input Iterators have a cost structure very different from
1591debfc3dSmrg   // pointers, calling for a different coding style.
1601debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
1611debfc3dSmrg     template<typename _InIterator>
1621debfc3dSmrg       void
1631debfc3dSmrg       basic_string<_CharT, _Traits, _Alloc>::
_M_construct(_InIterator __beg,_InIterator __end,std::input_iterator_tag)1641debfc3dSmrg       _M_construct(_InIterator __beg, _InIterator __end,
1651debfc3dSmrg 		   std::input_iterator_tag)
1661debfc3dSmrg       {
1671debfc3dSmrg 	size_type __len = 0;
1681debfc3dSmrg 	size_type __capacity = size_type(_S_local_capacity);
1691debfc3dSmrg 
1701debfc3dSmrg 	while (__beg != __end && __len < __capacity)
1711debfc3dSmrg 	  {
1721debfc3dSmrg 	    _M_data()[__len++] = *__beg;
1731debfc3dSmrg 	    ++__beg;
1741debfc3dSmrg 	  }
1751debfc3dSmrg 
1761debfc3dSmrg 	__try
1771debfc3dSmrg 	  {
1781debfc3dSmrg 	    while (__beg != __end)
1791debfc3dSmrg 	      {
1801debfc3dSmrg 		if (__len == __capacity)
1811debfc3dSmrg 		  {
1821debfc3dSmrg 		    // Allocate more space.
1831debfc3dSmrg 		    __capacity = __len + 1;
1841debfc3dSmrg 		    pointer __another = _M_create(__capacity, __len);
1851debfc3dSmrg 		    this->_S_copy(__another, _M_data(), __len);
1861debfc3dSmrg 		    _M_dispose();
1871debfc3dSmrg 		    _M_data(__another);
1881debfc3dSmrg 		    _M_capacity(__capacity);
1891debfc3dSmrg 		  }
1901debfc3dSmrg 		_M_data()[__len++] = *__beg;
1911debfc3dSmrg 		++__beg;
1921debfc3dSmrg 	      }
1931debfc3dSmrg 	  }
1941debfc3dSmrg 	__catch(...)
1951debfc3dSmrg 	  {
1961debfc3dSmrg 	    _M_dispose();
1971debfc3dSmrg 	    __throw_exception_again;
1981debfc3dSmrg 	  }
1991debfc3dSmrg 
2001debfc3dSmrg 	_M_set_length(__len);
2011debfc3dSmrg       }
2021debfc3dSmrg 
2031debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
2041debfc3dSmrg     template<typename _InIterator>
2051debfc3dSmrg       void
2061debfc3dSmrg       basic_string<_CharT, _Traits, _Alloc>::
_M_construct(_InIterator __beg,_InIterator __end,std::forward_iterator_tag)2071debfc3dSmrg       _M_construct(_InIterator __beg, _InIterator __end,
2081debfc3dSmrg 		   std::forward_iterator_tag)
2091debfc3dSmrg       {
2101debfc3dSmrg 	// NB: Not required, but considered best practice.
2111debfc3dSmrg 	if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end)
2121debfc3dSmrg 	  std::__throw_logic_error(__N("basic_string::"
2131debfc3dSmrg 				       "_M_construct null not valid"));
2141debfc3dSmrg 
2151debfc3dSmrg 	size_type __dnew = static_cast<size_type>(std::distance(__beg, __end));
2161debfc3dSmrg 
2171debfc3dSmrg 	if (__dnew > size_type(_S_local_capacity))
2181debfc3dSmrg 	  {
2191debfc3dSmrg 	    _M_data(_M_create(__dnew, size_type(0)));
2201debfc3dSmrg 	    _M_capacity(__dnew);
2211debfc3dSmrg 	  }
2221debfc3dSmrg 
2231debfc3dSmrg 	// Check for out_of_range and length_error exceptions.
2241debfc3dSmrg 	__try
2251debfc3dSmrg 	  { this->_S_copy_chars(_M_data(), __beg, __end); }
2261debfc3dSmrg 	__catch(...)
2271debfc3dSmrg 	  {
2281debfc3dSmrg 	    _M_dispose();
2291debfc3dSmrg 	    __throw_exception_again;
2301debfc3dSmrg 	  }
2311debfc3dSmrg 
2321debfc3dSmrg 	_M_set_length(__dnew);
2331debfc3dSmrg       }
2341debfc3dSmrg 
2351debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
2361debfc3dSmrg     void
2371debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
_M_construct(size_type __n,_CharT __c)2381debfc3dSmrg     _M_construct(size_type __n, _CharT __c)
2391debfc3dSmrg     {
2401debfc3dSmrg       if (__n > size_type(_S_local_capacity))
2411debfc3dSmrg 	{
2421debfc3dSmrg 	  _M_data(_M_create(__n, size_type(0)));
2431debfc3dSmrg 	  _M_capacity(__n);
2441debfc3dSmrg 	}
2451debfc3dSmrg 
2461debfc3dSmrg       if (__n)
2471debfc3dSmrg 	this->_S_assign(_M_data(), __n, __c);
2481debfc3dSmrg 
2491debfc3dSmrg       _M_set_length(__n);
2501debfc3dSmrg     }
2511debfc3dSmrg 
2521debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
2531debfc3dSmrg     void
2541debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
_M_assign(const basic_string & __str)2551debfc3dSmrg     _M_assign(const basic_string& __str)
2561debfc3dSmrg     {
2571debfc3dSmrg       if (this != &__str)
2581debfc3dSmrg 	{
2591debfc3dSmrg 	  const size_type __rsize = __str.length();
2601debfc3dSmrg 	  const size_type __capacity = capacity();
2611debfc3dSmrg 
2621debfc3dSmrg 	  if (__rsize > __capacity)
2631debfc3dSmrg 	    {
2641debfc3dSmrg 	      size_type __new_capacity = __rsize;
2651debfc3dSmrg 	      pointer __tmp = _M_create(__new_capacity, __capacity);
2661debfc3dSmrg 	      _M_dispose();
2671debfc3dSmrg 	      _M_data(__tmp);
2681debfc3dSmrg 	      _M_capacity(__new_capacity);
2691debfc3dSmrg 	    }
2701debfc3dSmrg 
2711debfc3dSmrg 	  if (__rsize)
2721debfc3dSmrg 	    this->_S_copy(_M_data(), __str._M_data(), __rsize);
2731debfc3dSmrg 
2741debfc3dSmrg 	  _M_set_length(__rsize);
2751debfc3dSmrg 	}
2761debfc3dSmrg     }
2771debfc3dSmrg 
2781debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
2791debfc3dSmrg     void
2801debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
reserve(size_type __res)2811debfc3dSmrg     reserve(size_type __res)
2821debfc3dSmrg     {
2831debfc3dSmrg       // Make sure we don't shrink below the current size.
2841debfc3dSmrg       if (__res < length())
2851debfc3dSmrg 	__res = length();
2861debfc3dSmrg 
2871debfc3dSmrg       const size_type __capacity = capacity();
2881debfc3dSmrg       if (__res != __capacity)
2891debfc3dSmrg 	{
2901debfc3dSmrg 	  if (__res > __capacity
2911debfc3dSmrg 	      || __res > size_type(_S_local_capacity))
2921debfc3dSmrg 	    {
2931debfc3dSmrg 	      pointer __tmp = _M_create(__res, __capacity);
2941debfc3dSmrg 	      this->_S_copy(__tmp, _M_data(), length() + 1);
2951debfc3dSmrg 	      _M_dispose();
2961debfc3dSmrg 	      _M_data(__tmp);
2971debfc3dSmrg 	      _M_capacity(__res);
2981debfc3dSmrg 	    }
2991debfc3dSmrg 	  else if (!_M_is_local())
3001debfc3dSmrg 	    {
3011debfc3dSmrg 	      this->_S_copy(_M_local_data(), _M_data(), length() + 1);
3021debfc3dSmrg 	      _M_destroy(__capacity);
3031debfc3dSmrg 	      _M_data(_M_local_data());
3041debfc3dSmrg 	    }
3051debfc3dSmrg 	}
3061debfc3dSmrg     }
3071debfc3dSmrg 
3081debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
3091debfc3dSmrg     void
3101debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
_M_mutate(size_type __pos,size_type __len1,const _CharT * __s,size_type __len2)3111debfc3dSmrg     _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
3121debfc3dSmrg 	      size_type __len2)
3131debfc3dSmrg     {
3141debfc3dSmrg       const size_type __how_much = length() - __pos - __len1;
3151debfc3dSmrg 
3161debfc3dSmrg       size_type __new_capacity = length() + __len2 - __len1;
3171debfc3dSmrg       pointer __r = _M_create(__new_capacity, capacity());
3181debfc3dSmrg 
3191debfc3dSmrg       if (__pos)
3201debfc3dSmrg 	this->_S_copy(__r, _M_data(), __pos);
3211debfc3dSmrg       if (__s && __len2)
3221debfc3dSmrg 	this->_S_copy(__r + __pos, __s, __len2);
3231debfc3dSmrg       if (__how_much)
3241debfc3dSmrg 	this->_S_copy(__r + __pos + __len2,
3251debfc3dSmrg 		      _M_data() + __pos + __len1, __how_much);
3261debfc3dSmrg 
3271debfc3dSmrg       _M_dispose();
3281debfc3dSmrg       _M_data(__r);
3291debfc3dSmrg       _M_capacity(__new_capacity);
3301debfc3dSmrg     }
3311debfc3dSmrg 
3321debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
3331debfc3dSmrg     void
3341debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
_M_erase(size_type __pos,size_type __n)3351debfc3dSmrg     _M_erase(size_type __pos, size_type __n)
3361debfc3dSmrg     {
3371debfc3dSmrg       const size_type __how_much = length() - __pos - __n;
3381debfc3dSmrg 
3391debfc3dSmrg       if (__how_much && __n)
3401debfc3dSmrg 	this->_S_move(_M_data() + __pos, _M_data() + __pos + __n, __how_much);
3411debfc3dSmrg 
3421debfc3dSmrg       _M_set_length(length() - __n);
3431debfc3dSmrg     }
3441debfc3dSmrg 
3451debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
3461debfc3dSmrg     void
3471debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
resize(size_type __n,_CharT __c)3481debfc3dSmrg     resize(size_type __n, _CharT __c)
3491debfc3dSmrg     {
3501debfc3dSmrg       const size_type __size = this->size();
3511debfc3dSmrg       if (__size < __n)
3521debfc3dSmrg 	this->append(__n - __size, __c);
3531debfc3dSmrg       else if (__n < __size)
3541debfc3dSmrg 	this->_M_set_length(__n);
3551debfc3dSmrg     }
3561debfc3dSmrg 
3571debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
3581debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>&
3591debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
_M_append(const _CharT * __s,size_type __n)3601debfc3dSmrg     _M_append(const _CharT* __s, size_type __n)
3611debfc3dSmrg     {
3621debfc3dSmrg       const size_type __len = __n + this->size();
3631debfc3dSmrg 
3641debfc3dSmrg       if (__len <= this->capacity())
3651debfc3dSmrg 	{
3661debfc3dSmrg 	  if (__n)
3671debfc3dSmrg 	    this->_S_copy(this->_M_data() + this->size(), __s, __n);
3681debfc3dSmrg 	}
3691debfc3dSmrg       else
3701debfc3dSmrg 	this->_M_mutate(this->size(), size_type(0), __s, __n);
3711debfc3dSmrg 
3721debfc3dSmrg       this->_M_set_length(__len);
3731debfc3dSmrg       return *this;
3741debfc3dSmrg     }
3751debfc3dSmrg 
3761debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
3771debfc3dSmrg     template<typename _InputIterator>
3781debfc3dSmrg       basic_string<_CharT, _Traits, _Alloc>&
3791debfc3dSmrg       basic_string<_CharT, _Traits, _Alloc>::
_M_replace_dispatch(const_iterator __i1,const_iterator __i2,_InputIterator __k1,_InputIterator __k2,std::__false_type)3801debfc3dSmrg       _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
3811debfc3dSmrg 			  _InputIterator __k1, _InputIterator __k2,
3821debfc3dSmrg 			  std::__false_type)
3831debfc3dSmrg       {
384*8feb0f0bSmrg 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
385*8feb0f0bSmrg 	// 2788. unintentionally require a default constructible allocator
386*8feb0f0bSmrg 	const basic_string __s(__k1, __k2, this->get_allocator());
3871debfc3dSmrg 	const size_type __n1 = __i2 - __i1;
3881debfc3dSmrg 	return _M_replace(__i1 - begin(), __n1, __s._M_data(),
3891debfc3dSmrg 			  __s.size());
3901debfc3dSmrg       }
3911debfc3dSmrg 
3921debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
3931debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>&
3941debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
_M_replace_aux(size_type __pos1,size_type __n1,size_type __n2,_CharT __c)3951debfc3dSmrg     _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
3961debfc3dSmrg 		   _CharT __c)
3971debfc3dSmrg     {
3981debfc3dSmrg       _M_check_length(__n1, __n2, "basic_string::_M_replace_aux");
3991debfc3dSmrg 
4001debfc3dSmrg       const size_type __old_size = this->size();
4011debfc3dSmrg       const size_type __new_size = __old_size + __n2 - __n1;
4021debfc3dSmrg 
4031debfc3dSmrg       if (__new_size <= this->capacity())
4041debfc3dSmrg 	{
4051debfc3dSmrg 	  pointer __p = this->_M_data() + __pos1;
4061debfc3dSmrg 
4071debfc3dSmrg 	  const size_type __how_much = __old_size - __pos1 - __n1;
4081debfc3dSmrg 	  if (__how_much && __n1 != __n2)
4091debfc3dSmrg 	    this->_S_move(__p + __n2, __p + __n1, __how_much);
4101debfc3dSmrg 	}
4111debfc3dSmrg       else
4121debfc3dSmrg 	this->_M_mutate(__pos1, __n1, 0, __n2);
4131debfc3dSmrg 
4141debfc3dSmrg       if (__n2)
4151debfc3dSmrg 	this->_S_assign(this->_M_data() + __pos1, __n2, __c);
4161debfc3dSmrg 
4171debfc3dSmrg       this->_M_set_length(__new_size);
4181debfc3dSmrg       return *this;
4191debfc3dSmrg     }
4201debfc3dSmrg 
4211debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
4221debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>&
4231debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
_M_replace(size_type __pos,size_type __len1,const _CharT * __s,const size_type __len2)4241debfc3dSmrg     _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
4251debfc3dSmrg 	       const size_type __len2)
4261debfc3dSmrg     {
4271debfc3dSmrg       _M_check_length(__len1, __len2, "basic_string::_M_replace");
4281debfc3dSmrg 
4291debfc3dSmrg       const size_type __old_size = this->size();
4301debfc3dSmrg       const size_type __new_size = __old_size + __len2 - __len1;
4311debfc3dSmrg 
4321debfc3dSmrg       if (__new_size <= this->capacity())
4331debfc3dSmrg 	{
4341debfc3dSmrg 	  pointer __p = this->_M_data() + __pos;
4351debfc3dSmrg 
4361debfc3dSmrg 	  const size_type __how_much = __old_size - __pos - __len1;
4371debfc3dSmrg 	  if (_M_disjunct(__s))
4381debfc3dSmrg 	    {
4391debfc3dSmrg 	      if (__how_much && __len1 != __len2)
4401debfc3dSmrg 		this->_S_move(__p + __len2, __p + __len1, __how_much);
4411debfc3dSmrg 	      if (__len2)
4421debfc3dSmrg 		this->_S_copy(__p, __s, __len2);
4431debfc3dSmrg 	    }
4441debfc3dSmrg 	  else
4451debfc3dSmrg 	    {
4461debfc3dSmrg 	      // Work in-place.
4471debfc3dSmrg 	      if (__len2 && __len2 <= __len1)
4481debfc3dSmrg 		this->_S_move(__p, __s, __len2);
4491debfc3dSmrg 	      if (__how_much && __len1 != __len2)
4501debfc3dSmrg 		this->_S_move(__p + __len2, __p + __len1, __how_much);
4511debfc3dSmrg 	      if (__len2 > __len1)
4521debfc3dSmrg 		{
4531debfc3dSmrg 		  if (__s + __len2 <= __p + __len1)
4541debfc3dSmrg 		    this->_S_move(__p, __s, __len2);
4551debfc3dSmrg 		  else if (__s >= __p + __len1)
4561debfc3dSmrg 		    this->_S_copy(__p, __s + __len2 - __len1, __len2);
4571debfc3dSmrg 		  else
4581debfc3dSmrg 		    {
4591debfc3dSmrg 		      const size_type __nleft = (__p + __len1) - __s;
4601debfc3dSmrg 		      this->_S_move(__p, __s, __nleft);
4611debfc3dSmrg 		      this->_S_copy(__p + __nleft, __p + __len2,
4621debfc3dSmrg 				    __len2 - __nleft);
4631debfc3dSmrg 		    }
4641debfc3dSmrg 		}
4651debfc3dSmrg 	    }
4661debfc3dSmrg 	}
4671debfc3dSmrg       else
4681debfc3dSmrg 	this->_M_mutate(__pos, __len1, __s, __len2);
4691debfc3dSmrg 
4701debfc3dSmrg       this->_M_set_length(__new_size);
4711debfc3dSmrg       return *this;
4721debfc3dSmrg     }
4731debfc3dSmrg 
4741debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
4751debfc3dSmrg     typename basic_string<_CharT, _Traits, _Alloc>::size_type
4761debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
copy(_CharT * __s,size_type __n,size_type __pos) const4771debfc3dSmrg     copy(_CharT* __s, size_type __n, size_type __pos) const
4781debfc3dSmrg     {
4791debfc3dSmrg       _M_check(__pos, "basic_string::copy");
4801debfc3dSmrg       __n = _M_limit(__pos, __n);
4811debfc3dSmrg       __glibcxx_requires_string_len(__s, __n);
4821debfc3dSmrg       if (__n)
4831debfc3dSmrg 	_S_copy(__s, _M_data() + __pos, __n);
4841debfc3dSmrg       // 21.3.5.7 par 3: do not append null.  (good.)
4851debfc3dSmrg       return __n;
4861debfc3dSmrg     }
4871debfc3dSmrg 
4881debfc3dSmrg #else  // !_GLIBCXX_USE_CXX11_ABI
4891debfc3dSmrg 
4901debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
4911debfc3dSmrg     const typename basic_string<_CharT, _Traits, _Alloc>::size_type
4921debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
4931debfc3dSmrg     _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4;
4941debfc3dSmrg 
4951debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
4961debfc3dSmrg     const _CharT
4971debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
4981debfc3dSmrg     _Rep::_S_terminal = _CharT();
4991debfc3dSmrg 
5001debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
5011debfc3dSmrg     const typename basic_string<_CharT, _Traits, _Alloc>::size_type
5021debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::npos;
5031debfc3dSmrg 
5041debfc3dSmrg   // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string)
5051debfc3dSmrg   // at static init time (before static ctors are run).
5061debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
5071debfc3dSmrg     typename basic_string<_CharT, _Traits, _Alloc>::size_type
5081debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[
5091debfc3dSmrg     (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) /
5101debfc3dSmrg       sizeof(size_type)];
5111debfc3dSmrg 
5121debfc3dSmrg   // NB: This is the special case for Input Iterators, used in
5131debfc3dSmrg   // istreambuf_iterators, etc.
5141debfc3dSmrg   // Input Iterators have a cost structure very different from
5151debfc3dSmrg   // pointers, calling for a different coding style.
5161debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
5171debfc3dSmrg     template<typename _InIterator>
5181debfc3dSmrg       _CharT*
5191debfc3dSmrg       basic_string<_CharT, _Traits, _Alloc>::
5201debfc3dSmrg       _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
5211debfc3dSmrg 		   input_iterator_tag)
5221debfc3dSmrg       {
5231debfc3dSmrg #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
5241debfc3dSmrg 	if (__beg == __end && __a == _Alloc())
5251debfc3dSmrg 	  return _S_empty_rep()._M_refdata();
5261debfc3dSmrg #endif
5271debfc3dSmrg 	// Avoid reallocation for common case.
5281debfc3dSmrg 	_CharT __buf[128];
5291debfc3dSmrg 	size_type __len = 0;
5301debfc3dSmrg 	while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT))
5311debfc3dSmrg 	  {
5321debfc3dSmrg 	    __buf[__len++] = *__beg;
5331debfc3dSmrg 	    ++__beg;
5341debfc3dSmrg 	  }
5351debfc3dSmrg 	_Rep* __r = _Rep::_S_create(__len, size_type(0), __a);
5361debfc3dSmrg 	_M_copy(__r->_M_refdata(), __buf, __len);
5371debfc3dSmrg 	__try
5381debfc3dSmrg 	  {
5391debfc3dSmrg 	    while (__beg != __end)
5401debfc3dSmrg 	      {
5411debfc3dSmrg 		if (__len == __r->_M_capacity)
5421debfc3dSmrg 		  {
5431debfc3dSmrg 		    // Allocate more space.
5441debfc3dSmrg 		    _Rep* __another = _Rep::_S_create(__len + 1, __len, __a);
5451debfc3dSmrg 		    _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len);
5461debfc3dSmrg 		    __r->_M_destroy(__a);
5471debfc3dSmrg 		    __r = __another;
5481debfc3dSmrg 		  }
5491debfc3dSmrg 		__r->_M_refdata()[__len++] = *__beg;
5501debfc3dSmrg 		++__beg;
5511debfc3dSmrg 	      }
5521debfc3dSmrg 	  }
5531debfc3dSmrg 	__catch(...)
5541debfc3dSmrg 	  {
5551debfc3dSmrg 	    __r->_M_destroy(__a);
5561debfc3dSmrg 	    __throw_exception_again;
5571debfc3dSmrg 	  }
5581debfc3dSmrg 	__r->_M_set_length_and_sharable(__len);
5591debfc3dSmrg 	return __r->_M_refdata();
5601debfc3dSmrg       }
5611debfc3dSmrg 
5621debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
5631debfc3dSmrg     template <typename _InIterator>
5641debfc3dSmrg       _CharT*
5651debfc3dSmrg       basic_string<_CharT, _Traits, _Alloc>::
5661debfc3dSmrg       _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
5671debfc3dSmrg 		   forward_iterator_tag)
5681debfc3dSmrg       {
5691debfc3dSmrg #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
5701debfc3dSmrg 	if (__beg == __end && __a == _Alloc())
5711debfc3dSmrg 	  return _S_empty_rep()._M_refdata();
5721debfc3dSmrg #endif
5731debfc3dSmrg 	// NB: Not required, but considered best practice.
5741debfc3dSmrg 	if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end)
5751debfc3dSmrg 	  __throw_logic_error(__N("basic_string::_S_construct null not valid"));
5761debfc3dSmrg 
5771debfc3dSmrg 	const size_type __dnew = static_cast<size_type>(std::distance(__beg,
5781debfc3dSmrg 								      __end));
5791debfc3dSmrg 	// Check for out_of_range and length_error exceptions.
5801debfc3dSmrg 	_Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a);
5811debfc3dSmrg 	__try
5821debfc3dSmrg 	  { _S_copy_chars(__r->_M_refdata(), __beg, __end); }
5831debfc3dSmrg 	__catch(...)
5841debfc3dSmrg 	  {
5851debfc3dSmrg 	    __r->_M_destroy(__a);
5861debfc3dSmrg 	    __throw_exception_again;
5871debfc3dSmrg 	  }
5881debfc3dSmrg 	__r->_M_set_length_and_sharable(__dnew);
5891debfc3dSmrg 	return __r->_M_refdata();
5901debfc3dSmrg       }
5911debfc3dSmrg 
5921debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
5931debfc3dSmrg     _CharT*
5941debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
5951debfc3dSmrg     _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
5961debfc3dSmrg     {
5971debfc3dSmrg #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
5981debfc3dSmrg       if (__n == 0 && __a == _Alloc())
5991debfc3dSmrg 	return _S_empty_rep()._M_refdata();
6001debfc3dSmrg #endif
6011debfc3dSmrg       // Check for out_of_range and length_error exceptions.
6021debfc3dSmrg       _Rep* __r = _Rep::_S_create(__n, size_type(0), __a);
6031debfc3dSmrg       if (__n)
6041debfc3dSmrg 	_M_assign(__r->_M_refdata(), __n, __c);
6051debfc3dSmrg 
6061debfc3dSmrg       __r->_M_set_length_and_sharable(__n);
6071debfc3dSmrg       return __r->_M_refdata();
6081debfc3dSmrg     }
6091debfc3dSmrg 
6101debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
6111debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
6121debfc3dSmrg     basic_string(const basic_string& __str)
6131debfc3dSmrg     : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()),
6141debfc3dSmrg 					  __str.get_allocator()),
6151debfc3dSmrg 		  __str.get_allocator())
6161debfc3dSmrg     { }
6171debfc3dSmrg 
6181debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
6191debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
6201debfc3dSmrg     basic_string(const _Alloc& __a)
6211debfc3dSmrg     : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a)
6221debfc3dSmrg     { }
6231debfc3dSmrg 
6241debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
6251debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
6261debfc3dSmrg     basic_string(const basic_string& __str, size_type __pos, const _Alloc& __a)
6271debfc3dSmrg     : _M_dataplus(_S_construct(__str._M_data()
6281debfc3dSmrg 			       + __str._M_check(__pos,
6291debfc3dSmrg 						"basic_string::basic_string"),
6301debfc3dSmrg 			       __str._M_data() + __str._M_limit(__pos, npos)
6311debfc3dSmrg 			       + __pos, __a), __a)
6321debfc3dSmrg     { }
6331debfc3dSmrg 
6341debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
6351debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
6361debfc3dSmrg     basic_string(const basic_string& __str, size_type __pos, size_type __n)
6371debfc3dSmrg     : _M_dataplus(_S_construct(__str._M_data()
6381debfc3dSmrg 			       + __str._M_check(__pos,
6391debfc3dSmrg 						"basic_string::basic_string"),
6401debfc3dSmrg 			       __str._M_data() + __str._M_limit(__pos, __n)
6411debfc3dSmrg 			       + __pos, _Alloc()), _Alloc())
6421debfc3dSmrg     { }
6431debfc3dSmrg 
6441debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
6451debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
6461debfc3dSmrg     basic_string(const basic_string& __str, size_type __pos,
6471debfc3dSmrg 		 size_type __n, const _Alloc& __a)
6481debfc3dSmrg     : _M_dataplus(_S_construct(__str._M_data()
6491debfc3dSmrg 			       + __str._M_check(__pos,
6501debfc3dSmrg 						"basic_string::basic_string"),
6511debfc3dSmrg 			       __str._M_data() + __str._M_limit(__pos, __n)
6521debfc3dSmrg 			       + __pos, __a), __a)
6531debfc3dSmrg     { }
6541debfc3dSmrg 
6551debfc3dSmrg   // TBD: DPG annotate
6561debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
6571debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
6581debfc3dSmrg     basic_string(const _CharT* __s, size_type __n, const _Alloc& __a)
6591debfc3dSmrg     : _M_dataplus(_S_construct(__s, __s + __n, __a), __a)
6601debfc3dSmrg     { }
6611debfc3dSmrg 
6621debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
6631debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
6641debfc3dSmrg     basic_string(size_type __n, _CharT __c, const _Alloc& __a)
6651debfc3dSmrg     : _M_dataplus(_S_construct(__n, __c, __a), __a)
6661debfc3dSmrg     { }
6671debfc3dSmrg 
6681debfc3dSmrg   // TBD: DPG annotate
6691debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
6701debfc3dSmrg     template<typename _InputIterator>
6711debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
6721debfc3dSmrg     basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a)
6731debfc3dSmrg     : _M_dataplus(_S_construct(__beg, __end, __a), __a)
6741debfc3dSmrg     { }
6751debfc3dSmrg 
6761debfc3dSmrg #if __cplusplus >= 201103L
6771debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
6781debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
6791debfc3dSmrg     basic_string(initializer_list<_CharT> __l, const _Alloc& __a)
6801debfc3dSmrg     : _M_dataplus(_S_construct(__l.begin(), __l.end(), __a), __a)
6811debfc3dSmrg     { }
6821debfc3dSmrg #endif
6831debfc3dSmrg 
6841debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
6851debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>&
6861debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
6871debfc3dSmrg     assign(const basic_string& __str)
6881debfc3dSmrg     {
6891debfc3dSmrg       if (_M_rep() != __str._M_rep())
6901debfc3dSmrg 	{
6911debfc3dSmrg 	  // XXX MT
6921debfc3dSmrg 	  const allocator_type __a = this->get_allocator();
6931debfc3dSmrg 	  _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator());
6941debfc3dSmrg 	  _M_rep()->_M_dispose(__a);
6951debfc3dSmrg 	  _M_data(__tmp);
6961debfc3dSmrg 	}
6971debfc3dSmrg       return *this;
6981debfc3dSmrg     }
6991debfc3dSmrg 
7001debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
7011debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>&
7021debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
7031debfc3dSmrg     assign(const _CharT* __s, size_type __n)
7041debfc3dSmrg     {
7051debfc3dSmrg       __glibcxx_requires_string_len(__s, __n);
7061debfc3dSmrg       _M_check_length(this->size(), __n, "basic_string::assign");
7071debfc3dSmrg       if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
7081debfc3dSmrg 	return _M_replace_safe(size_type(0), this->size(), __s, __n);
7091debfc3dSmrg       else
7101debfc3dSmrg 	{
7111debfc3dSmrg 	  // Work in-place.
7121debfc3dSmrg 	  const size_type __pos = __s - _M_data();
7131debfc3dSmrg 	  if (__pos >= __n)
7141debfc3dSmrg 	    _M_copy(_M_data(), __s, __n);
7151debfc3dSmrg 	  else if (__pos)
7161debfc3dSmrg 	    _M_move(_M_data(), __s, __n);
7171debfc3dSmrg 	  _M_rep()->_M_set_length_and_sharable(__n);
7181debfc3dSmrg 	  return *this;
7191debfc3dSmrg 	}
7201debfc3dSmrg      }
7211debfc3dSmrg 
7221debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
7231debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>&
7241debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
7251debfc3dSmrg     append(size_type __n, _CharT __c)
7261debfc3dSmrg     {
7271debfc3dSmrg       if (__n)
7281debfc3dSmrg 	{
7291debfc3dSmrg 	  _M_check_length(size_type(0), __n, "basic_string::append");
7301debfc3dSmrg 	  const size_type __len = __n + this->size();
7311debfc3dSmrg 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
7321debfc3dSmrg 	    this->reserve(__len);
7331debfc3dSmrg 	  _M_assign(_M_data() + this->size(), __n, __c);
7341debfc3dSmrg 	  _M_rep()->_M_set_length_and_sharable(__len);
7351debfc3dSmrg 	}
7361debfc3dSmrg       return *this;
7371debfc3dSmrg     }
7381debfc3dSmrg 
7391debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
7401debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>&
7411debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
7421debfc3dSmrg     append(const _CharT* __s, size_type __n)
7431debfc3dSmrg     {
7441debfc3dSmrg       __glibcxx_requires_string_len(__s, __n);
7451debfc3dSmrg       if (__n)
7461debfc3dSmrg 	{
7471debfc3dSmrg 	  _M_check_length(size_type(0), __n, "basic_string::append");
7481debfc3dSmrg 	  const size_type __len = __n + this->size();
7491debfc3dSmrg 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
7501debfc3dSmrg 	    {
7511debfc3dSmrg 	      if (_M_disjunct(__s))
7521debfc3dSmrg 		this->reserve(__len);
7531debfc3dSmrg 	      else
7541debfc3dSmrg 		{
7551debfc3dSmrg 		  const size_type __off = __s - _M_data();
7561debfc3dSmrg 		  this->reserve(__len);
7571debfc3dSmrg 		  __s = _M_data() + __off;
7581debfc3dSmrg 		}
7591debfc3dSmrg 	    }
7601debfc3dSmrg 	  _M_copy(_M_data() + this->size(), __s, __n);
7611debfc3dSmrg 	  _M_rep()->_M_set_length_and_sharable(__len);
7621debfc3dSmrg 	}
7631debfc3dSmrg       return *this;
7641debfc3dSmrg     }
7651debfc3dSmrg 
7661debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
7671debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>&
7681debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
7691debfc3dSmrg     append(const basic_string& __str)
7701debfc3dSmrg     {
7711debfc3dSmrg       const size_type __size = __str.size();
7721debfc3dSmrg       if (__size)
7731debfc3dSmrg 	{
7741debfc3dSmrg 	  const size_type __len = __size + this->size();
7751debfc3dSmrg 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
7761debfc3dSmrg 	    this->reserve(__len);
7771debfc3dSmrg 	  _M_copy(_M_data() + this->size(), __str._M_data(), __size);
7781debfc3dSmrg 	  _M_rep()->_M_set_length_and_sharable(__len);
7791debfc3dSmrg 	}
7801debfc3dSmrg       return *this;
7811debfc3dSmrg     }
7821debfc3dSmrg 
7831debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
7841debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>&
7851debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
7861debfc3dSmrg     append(const basic_string& __str, size_type __pos, size_type __n)
7871debfc3dSmrg     {
7881debfc3dSmrg       __str._M_check(__pos, "basic_string::append");
7891debfc3dSmrg       __n = __str._M_limit(__pos, __n);
7901debfc3dSmrg       if (__n)
7911debfc3dSmrg 	{
7921debfc3dSmrg 	  const size_type __len = __n + this->size();
7931debfc3dSmrg 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
7941debfc3dSmrg 	    this->reserve(__len);
7951debfc3dSmrg 	  _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n);
7961debfc3dSmrg 	  _M_rep()->_M_set_length_and_sharable(__len);
7971debfc3dSmrg 	}
7981debfc3dSmrg       return *this;
7991debfc3dSmrg     }
8001debfc3dSmrg 
8011debfc3dSmrg    template<typename _CharT, typename _Traits, typename _Alloc>
8021debfc3dSmrg      basic_string<_CharT, _Traits, _Alloc>&
8031debfc3dSmrg      basic_string<_CharT, _Traits, _Alloc>::
8041debfc3dSmrg      insert(size_type __pos, const _CharT* __s, size_type __n)
8051debfc3dSmrg      {
8061debfc3dSmrg        __glibcxx_requires_string_len(__s, __n);
8071debfc3dSmrg        _M_check(__pos, "basic_string::insert");
8081debfc3dSmrg        _M_check_length(size_type(0), __n, "basic_string::insert");
8091debfc3dSmrg        if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
8101debfc3dSmrg          return _M_replace_safe(__pos, size_type(0), __s, __n);
8111debfc3dSmrg        else
8121debfc3dSmrg          {
8131debfc3dSmrg            // Work in-place.
8141debfc3dSmrg            const size_type __off = __s - _M_data();
8151debfc3dSmrg            _M_mutate(__pos, 0, __n);
8161debfc3dSmrg            __s = _M_data() + __off;
8171debfc3dSmrg            _CharT* __p = _M_data() + __pos;
8181debfc3dSmrg            if (__s  + __n <= __p)
8191debfc3dSmrg              _M_copy(__p, __s, __n);
8201debfc3dSmrg            else if (__s >= __p)
8211debfc3dSmrg              _M_copy(__p, __s + __n, __n);
8221debfc3dSmrg            else
8231debfc3dSmrg              {
8241debfc3dSmrg 	       const size_type __nleft = __p - __s;
8251debfc3dSmrg                _M_copy(__p, __s, __nleft);
8261debfc3dSmrg                _M_copy(__p + __nleft, __p + __n, __n - __nleft);
8271debfc3dSmrg              }
8281debfc3dSmrg            return *this;
8291debfc3dSmrg          }
8301debfc3dSmrg      }
8311debfc3dSmrg 
8321debfc3dSmrg    template<typename _CharT, typename _Traits, typename _Alloc>
8331debfc3dSmrg      typename basic_string<_CharT, _Traits, _Alloc>::iterator
8341debfc3dSmrg      basic_string<_CharT, _Traits, _Alloc>::
8351debfc3dSmrg      erase(iterator __first, iterator __last)
8361debfc3dSmrg      {
8371debfc3dSmrg        _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
8381debfc3dSmrg 				&& __last <= _M_iend());
8391debfc3dSmrg 
8401debfc3dSmrg        // NB: This isn't just an optimization (bail out early when
8411debfc3dSmrg        // there is nothing to do, really), it's also a correctness
8421debfc3dSmrg        // issue vs MT, see libstdc++/40518.
8431debfc3dSmrg        const size_type __size = __last - __first;
8441debfc3dSmrg        if (__size)
8451debfc3dSmrg 	 {
8461debfc3dSmrg 	   const size_type __pos = __first - _M_ibegin();
8471debfc3dSmrg 	   _M_mutate(__pos, __size, size_type(0));
8481debfc3dSmrg 	   _M_rep()->_M_set_leaked();
8491debfc3dSmrg 	   return iterator(_M_data() + __pos);
8501debfc3dSmrg 	 }
8511debfc3dSmrg        else
8521debfc3dSmrg 	 return __first;
8531debfc3dSmrg      }
8541debfc3dSmrg 
8551debfc3dSmrg    template<typename _CharT, typename _Traits, typename _Alloc>
8561debfc3dSmrg      basic_string<_CharT, _Traits, _Alloc>&
8571debfc3dSmrg      basic_string<_CharT, _Traits, _Alloc>::
8581debfc3dSmrg      replace(size_type __pos, size_type __n1, const _CharT* __s,
8591debfc3dSmrg 	     size_type __n2)
8601debfc3dSmrg      {
8611debfc3dSmrg        __glibcxx_requires_string_len(__s, __n2);
8621debfc3dSmrg        _M_check(__pos, "basic_string::replace");
8631debfc3dSmrg        __n1 = _M_limit(__pos, __n1);
8641debfc3dSmrg        _M_check_length(__n1, __n2, "basic_string::replace");
8651debfc3dSmrg        bool __left;
8661debfc3dSmrg        if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
8671debfc3dSmrg          return _M_replace_safe(__pos, __n1, __s, __n2);
8681debfc3dSmrg        else if ((__left = __s + __n2 <= _M_data() + __pos)
8691debfc3dSmrg 		|| _M_data() + __pos + __n1 <= __s)
8701debfc3dSmrg 	 {
8711debfc3dSmrg 	   // Work in-place: non-overlapping case.
8721debfc3dSmrg 	   size_type __off = __s - _M_data();
8731debfc3dSmrg 	   __left ? __off : (__off += __n2 - __n1);
8741debfc3dSmrg 	   _M_mutate(__pos, __n1, __n2);
8751debfc3dSmrg 	   _M_copy(_M_data() + __pos, _M_data() + __off, __n2);
8761debfc3dSmrg 	   return *this;
8771debfc3dSmrg 	 }
8781debfc3dSmrg        else
8791debfc3dSmrg 	 {
8801debfc3dSmrg 	   // Todo: overlapping case.
8811debfc3dSmrg 	   const basic_string __tmp(__s, __n2);
8821debfc3dSmrg 	   return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
8831debfc3dSmrg 	 }
8841debfc3dSmrg      }
8851debfc3dSmrg 
8861debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
8871debfc3dSmrg     void
8881debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::_Rep::
8891debfc3dSmrg     _M_destroy(const _Alloc& __a) throw ()
8901debfc3dSmrg     {
8911debfc3dSmrg       const size_type __size = sizeof(_Rep_base) +
8921debfc3dSmrg 	                       (this->_M_capacity + 1) * sizeof(_CharT);
8931debfc3dSmrg       _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);
8941debfc3dSmrg     }
8951debfc3dSmrg 
8961debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
8971debfc3dSmrg     void
8981debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
8991debfc3dSmrg     _M_leak_hard()
9001debfc3dSmrg     {
9011debfc3dSmrg #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
9021debfc3dSmrg       if (_M_rep() == &_S_empty_rep())
9031debfc3dSmrg 	return;
9041debfc3dSmrg #endif
9051debfc3dSmrg       if (_M_rep()->_M_is_shared())
9061debfc3dSmrg 	_M_mutate(0, 0, 0);
9071debfc3dSmrg       _M_rep()->_M_set_leaked();
9081debfc3dSmrg     }
9091debfc3dSmrg 
9101debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
9111debfc3dSmrg     void
9121debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
9131debfc3dSmrg     _M_mutate(size_type __pos, size_type __len1, size_type __len2)
9141debfc3dSmrg     {
9151debfc3dSmrg       const size_type __old_size = this->size();
9161debfc3dSmrg       const size_type __new_size = __old_size + __len2 - __len1;
9171debfc3dSmrg       const size_type __how_much = __old_size - __pos - __len1;
9181debfc3dSmrg 
9191debfc3dSmrg       if (__new_size > this->capacity() || _M_rep()->_M_is_shared())
9201debfc3dSmrg 	{
9211debfc3dSmrg 	  // Must reallocate.
9221debfc3dSmrg 	  const allocator_type __a = get_allocator();
9231debfc3dSmrg 	  _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a);
9241debfc3dSmrg 
9251debfc3dSmrg 	  if (__pos)
9261debfc3dSmrg 	    _M_copy(__r->_M_refdata(), _M_data(), __pos);
9271debfc3dSmrg 	  if (__how_much)
9281debfc3dSmrg 	    _M_copy(__r->_M_refdata() + __pos + __len2,
9291debfc3dSmrg 		    _M_data() + __pos + __len1, __how_much);
9301debfc3dSmrg 
9311debfc3dSmrg 	  _M_rep()->_M_dispose(__a);
9321debfc3dSmrg 	  _M_data(__r->_M_refdata());
9331debfc3dSmrg 	}
9341debfc3dSmrg       else if (__how_much && __len1 != __len2)
9351debfc3dSmrg 	{
9361debfc3dSmrg 	  // Work in-place.
9371debfc3dSmrg 	  _M_move(_M_data() + __pos + __len2,
9381debfc3dSmrg 		  _M_data() + __pos + __len1, __how_much);
9391debfc3dSmrg 	}
9401debfc3dSmrg       _M_rep()->_M_set_length_and_sharable(__new_size);
9411debfc3dSmrg     }
9421debfc3dSmrg 
9431debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
9441debfc3dSmrg     void
9451debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
9461debfc3dSmrg     reserve(size_type __res)
9471debfc3dSmrg     {
9481debfc3dSmrg       if (__res != this->capacity() || _M_rep()->_M_is_shared())
9491debfc3dSmrg         {
9501debfc3dSmrg 	  // Make sure we don't shrink below the current size
9511debfc3dSmrg 	  if (__res < this->size())
9521debfc3dSmrg 	    __res = this->size();
9531debfc3dSmrg 	  const allocator_type __a = get_allocator();
9541debfc3dSmrg 	  _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size());
9551debfc3dSmrg 	  _M_rep()->_M_dispose(__a);
9561debfc3dSmrg 	  _M_data(__tmp);
9571debfc3dSmrg         }
9581debfc3dSmrg     }
9591debfc3dSmrg 
9601debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
9611debfc3dSmrg     void
9621debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
9631debfc3dSmrg     swap(basic_string& __s)
964c0a68be4Smrg     _GLIBCXX_NOEXCEPT_IF(allocator_traits<_Alloc>::is_always_equal::value)
9651debfc3dSmrg     {
9661debfc3dSmrg       if (_M_rep()->_M_is_leaked())
9671debfc3dSmrg 	_M_rep()->_M_set_sharable();
9681debfc3dSmrg       if (__s._M_rep()->_M_is_leaked())
9691debfc3dSmrg 	__s._M_rep()->_M_set_sharable();
9701debfc3dSmrg       if (this->get_allocator() == __s.get_allocator())
9711debfc3dSmrg 	{
9721debfc3dSmrg 	  _CharT* __tmp = _M_data();
9731debfc3dSmrg 	  _M_data(__s._M_data());
9741debfc3dSmrg 	  __s._M_data(__tmp);
9751debfc3dSmrg 	}
9761debfc3dSmrg       // The code below can usually be optimized away.
9771debfc3dSmrg       else
9781debfc3dSmrg 	{
9791debfc3dSmrg 	  const basic_string __tmp1(_M_ibegin(), _M_iend(),
9801debfc3dSmrg 				    __s.get_allocator());
9811debfc3dSmrg 	  const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(),
9821debfc3dSmrg 				    this->get_allocator());
9831debfc3dSmrg 	  *this = __tmp2;
9841debfc3dSmrg 	  __s = __tmp1;
9851debfc3dSmrg 	}
9861debfc3dSmrg     }
9871debfc3dSmrg 
9881debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
9891debfc3dSmrg     typename basic_string<_CharT, _Traits, _Alloc>::_Rep*
9901debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::_Rep::
9911debfc3dSmrg     _S_create(size_type __capacity, size_type __old_capacity,
9921debfc3dSmrg 	      const _Alloc& __alloc)
9931debfc3dSmrg     {
9941debfc3dSmrg       // _GLIBCXX_RESOLVE_LIB_DEFECTS
9951debfc3dSmrg       // 83.  String::npos vs. string::max_size()
9961debfc3dSmrg       if (__capacity > _S_max_size)
9971debfc3dSmrg 	__throw_length_error(__N("basic_string::_S_create"));
9981debfc3dSmrg 
9991debfc3dSmrg       // The standard places no restriction on allocating more memory
10001debfc3dSmrg       // than is strictly needed within this layer at the moment or as
10011debfc3dSmrg       // requested by an explicit application call to reserve().
10021debfc3dSmrg 
10031debfc3dSmrg       // Many malloc implementations perform quite poorly when an
10041debfc3dSmrg       // application attempts to allocate memory in a stepwise fashion
10051debfc3dSmrg       // growing each allocation size by only 1 char.  Additionally,
10061debfc3dSmrg       // it makes little sense to allocate less linear memory than the
10071debfc3dSmrg       // natural blocking size of the malloc implementation.
10081debfc3dSmrg       // Unfortunately, we would need a somewhat low-level calculation
10091debfc3dSmrg       // with tuned parameters to get this perfect for any particular
10101debfc3dSmrg       // malloc implementation.  Fortunately, generalizations about
10111debfc3dSmrg       // common features seen among implementations seems to suffice.
10121debfc3dSmrg 
10131debfc3dSmrg       // __pagesize need not match the actual VM page size for good
10141debfc3dSmrg       // results in practice, thus we pick a common value on the low
10151debfc3dSmrg       // side.  __malloc_header_size is an estimate of the amount of
10161debfc3dSmrg       // overhead per memory allocation (in practice seen N * sizeof
10171debfc3dSmrg       // (void*) where N is 0, 2 or 4).  According to folklore,
10181debfc3dSmrg       // picking this value on the high side is better than
10191debfc3dSmrg       // low-balling it (especially when this algorithm is used with
10201debfc3dSmrg       // malloc implementations that allocate memory blocks rounded up
10211debfc3dSmrg       // to a size which is a power of 2).
10221debfc3dSmrg       const size_type __pagesize = 4096;
10231debfc3dSmrg       const size_type __malloc_header_size = 4 * sizeof(void*);
10241debfc3dSmrg 
10251debfc3dSmrg       // The below implements an exponential growth policy, necessary to
10261debfc3dSmrg       // meet amortized linear time requirements of the library: see
10271debfc3dSmrg       // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
10281debfc3dSmrg       // It's active for allocations requiring an amount of memory above
10291debfc3dSmrg       // system pagesize. This is consistent with the requirements of the
10301debfc3dSmrg       // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html
10311debfc3dSmrg       if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
10321debfc3dSmrg 	__capacity = 2 * __old_capacity;
10331debfc3dSmrg 
10341debfc3dSmrg       // NB: Need an array of char_type[__capacity], plus a terminating
10351debfc3dSmrg       // null char_type() element, plus enough for the _Rep data structure.
10361debfc3dSmrg       // Whew. Seemingly so needy, yet so elemental.
10371debfc3dSmrg       size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
10381debfc3dSmrg 
10391debfc3dSmrg       const size_type __adj_size = __size + __malloc_header_size;
10401debfc3dSmrg       if (__adj_size > __pagesize && __capacity > __old_capacity)
10411debfc3dSmrg 	{
10421debfc3dSmrg 	  const size_type __extra = __pagesize - __adj_size % __pagesize;
10431debfc3dSmrg 	  __capacity += __extra / sizeof(_CharT);
10441debfc3dSmrg 	  // Never allocate a string bigger than _S_max_size.
10451debfc3dSmrg 	  if (__capacity > _S_max_size)
10461debfc3dSmrg 	    __capacity = _S_max_size;
10471debfc3dSmrg 	  __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
10481debfc3dSmrg 	}
10491debfc3dSmrg 
10501debfc3dSmrg       // NB: Might throw, but no worries about a leak, mate: _Rep()
10511debfc3dSmrg       // does not throw.
10521debfc3dSmrg       void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
10531debfc3dSmrg       _Rep *__p = new (__place) _Rep;
10541debfc3dSmrg       __p->_M_capacity = __capacity;
10551debfc3dSmrg       // ABI compatibility - 3.4.x set in _S_create both
10561debfc3dSmrg       // _M_refcount and _M_length.  All callers of _S_create
10571debfc3dSmrg       // in basic_string.tcc then set just _M_length.
10581debfc3dSmrg       // In 4.0.x and later both _M_refcount and _M_length
10591debfc3dSmrg       // are initialized in the callers, unfortunately we can
10601debfc3dSmrg       // have 3.4.x compiled code with _S_create callers inlined
10611debfc3dSmrg       // calling 4.0.x+ _S_create.
10621debfc3dSmrg       __p->_M_set_sharable();
10631debfc3dSmrg       return __p;
10641debfc3dSmrg     }
10651debfc3dSmrg 
10661debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
10671debfc3dSmrg     _CharT*
10681debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::_Rep::
10691debfc3dSmrg     _M_clone(const _Alloc& __alloc, size_type __res)
10701debfc3dSmrg     {
10711debfc3dSmrg       // Requested capacity of the clone.
10721debfc3dSmrg       const size_type __requested_cap = this->_M_length + __res;
10731debfc3dSmrg       _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity,
10741debfc3dSmrg 				  __alloc);
10751debfc3dSmrg       if (this->_M_length)
10761debfc3dSmrg 	_M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length);
10771debfc3dSmrg 
10781debfc3dSmrg       __r->_M_set_length_and_sharable(this->_M_length);
10791debfc3dSmrg       return __r->_M_refdata();
10801debfc3dSmrg     }
10811debfc3dSmrg 
10821debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
10831debfc3dSmrg     void
10841debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
10851debfc3dSmrg     resize(size_type __n, _CharT __c)
10861debfc3dSmrg     {
10871debfc3dSmrg       const size_type __size = this->size();
10881debfc3dSmrg       _M_check_length(__size, __n, "basic_string::resize");
10891debfc3dSmrg       if (__size < __n)
10901debfc3dSmrg 	this->append(__n - __size, __c);
10911debfc3dSmrg       else if (__n < __size)
10921debfc3dSmrg 	this->erase(__n);
10931debfc3dSmrg       // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
10941debfc3dSmrg     }
10951debfc3dSmrg 
10961debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
10971debfc3dSmrg     template<typename _InputIterator>
10981debfc3dSmrg       basic_string<_CharT, _Traits, _Alloc>&
10991debfc3dSmrg       basic_string<_CharT, _Traits, _Alloc>::
11001debfc3dSmrg       _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
11011debfc3dSmrg 			  _InputIterator __k2, __false_type)
11021debfc3dSmrg       {
11031debfc3dSmrg 	const basic_string __s(__k1, __k2);
11041debfc3dSmrg 	const size_type __n1 = __i2 - __i1;
11051debfc3dSmrg 	_M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch");
11061debfc3dSmrg 	return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(),
11071debfc3dSmrg 			       __s.size());
11081debfc3dSmrg       }
11091debfc3dSmrg 
11101debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
11111debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>&
11121debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
11131debfc3dSmrg     _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
11141debfc3dSmrg 		   _CharT __c)
11151debfc3dSmrg     {
11161debfc3dSmrg       _M_check_length(__n1, __n2, "basic_string::_M_replace_aux");
11171debfc3dSmrg       _M_mutate(__pos1, __n1, __n2);
11181debfc3dSmrg       if (__n2)
11191debfc3dSmrg 	_M_assign(_M_data() + __pos1, __n2, __c);
11201debfc3dSmrg       return *this;
11211debfc3dSmrg     }
11221debfc3dSmrg 
11231debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
11241debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>&
11251debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
11261debfc3dSmrg     _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
11271debfc3dSmrg 		    size_type __n2)
11281debfc3dSmrg     {
11291debfc3dSmrg       _M_mutate(__pos1, __n1, __n2);
11301debfc3dSmrg       if (__n2)
11311debfc3dSmrg 	_M_copy(_M_data() + __pos1, __s, __n2);
11321debfc3dSmrg       return *this;
11331debfc3dSmrg     }
11341debfc3dSmrg 
11351debfc3dSmrg     template<typename _CharT, typename _Traits, typename _Alloc>
11361debfc3dSmrg     typename basic_string<_CharT, _Traits, _Alloc>::size_type
11371debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
11381debfc3dSmrg     copy(_CharT* __s, size_type __n, size_type __pos) const
11391debfc3dSmrg     {
11401debfc3dSmrg       _M_check(__pos, "basic_string::copy");
11411debfc3dSmrg       __n = _M_limit(__pos, __n);
11421debfc3dSmrg       __glibcxx_requires_string_len(__s, __n);
11431debfc3dSmrg       if (__n)
11441debfc3dSmrg 	_M_copy(__s, _M_data() + __pos, __n);
11451debfc3dSmrg       // 21.3.5.7 par 3: do not append null.  (good.)
11461debfc3dSmrg       return __n;
11471debfc3dSmrg     }
11481debfc3dSmrg #endif  // !_GLIBCXX_USE_CXX11_ABI
11491debfc3dSmrg 
11501debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
11511debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>
operator +(const _CharT * __lhs,const basic_string<_CharT,_Traits,_Alloc> & __rhs)11521debfc3dSmrg     operator+(const _CharT* __lhs,
11531debfc3dSmrg 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)
11541debfc3dSmrg     {
11551debfc3dSmrg       __glibcxx_requires_string(__lhs);
11561debfc3dSmrg       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
11571debfc3dSmrg       typedef typename __string_type::size_type	  __size_type;
1158*8feb0f0bSmrg       typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
1159*8feb0f0bSmrg 	rebind<_CharT>::other _Char_alloc_type;
1160*8feb0f0bSmrg       typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits;
11611debfc3dSmrg       const __size_type __len = _Traits::length(__lhs);
1162*8feb0f0bSmrg       __string_type __str(_Alloc_traits::_S_select_on_copy(
1163*8feb0f0bSmrg           __rhs.get_allocator()));
11641debfc3dSmrg       __str.reserve(__len + __rhs.size());
11651debfc3dSmrg       __str.append(__lhs, __len);
11661debfc3dSmrg       __str.append(__rhs);
11671debfc3dSmrg       return __str;
11681debfc3dSmrg     }
11691debfc3dSmrg 
11701debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
11711debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>
operator +(_CharT __lhs,const basic_string<_CharT,_Traits,_Alloc> & __rhs)11721debfc3dSmrg     operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs)
11731debfc3dSmrg     {
11741debfc3dSmrg       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
11751debfc3dSmrg       typedef typename __string_type::size_type	  __size_type;
1176*8feb0f0bSmrg       typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
1177*8feb0f0bSmrg 	rebind<_CharT>::other _Char_alloc_type;
1178*8feb0f0bSmrg       typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits;
1179*8feb0f0bSmrg       __string_type __str(_Alloc_traits::_S_select_on_copy(
1180*8feb0f0bSmrg           __rhs.get_allocator()));
11811debfc3dSmrg       const __size_type __len = __rhs.size();
11821debfc3dSmrg       __str.reserve(__len + 1);
11831debfc3dSmrg       __str.append(__size_type(1), __lhs);
11841debfc3dSmrg       __str.append(__rhs);
11851debfc3dSmrg       return __str;
11861debfc3dSmrg     }
11871debfc3dSmrg 
11881debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
11891debfc3dSmrg     typename basic_string<_CharT, _Traits, _Alloc>::size_type
11901debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
find(const _CharT * __s,size_type __pos,size_type __n) const11911debfc3dSmrg     find(const _CharT* __s, size_type __pos, size_type __n) const
11921debfc3dSmrg     _GLIBCXX_NOEXCEPT
11931debfc3dSmrg     {
11941debfc3dSmrg       __glibcxx_requires_string_len(__s, __n);
11951debfc3dSmrg       const size_type __size = this->size();
11961debfc3dSmrg 
11971debfc3dSmrg       if (__n == 0)
11981debfc3dSmrg 	return __pos <= __size ? __pos : npos;
11991debfc3dSmrg       if (__pos >= __size)
12001debfc3dSmrg 	return npos;
12011debfc3dSmrg 
12021debfc3dSmrg       const _CharT __elem0 = __s[0];
12031debfc3dSmrg       const _CharT* const __data = data();
12041debfc3dSmrg       const _CharT* __first = __data + __pos;
12051debfc3dSmrg       const _CharT* const __last = __data + __size;
12061debfc3dSmrg       size_type __len = __size - __pos;
12071debfc3dSmrg 
12081debfc3dSmrg       while (__len >= __n)
12091debfc3dSmrg 	{
12101debfc3dSmrg 	  // Find the first occurrence of __elem0:
12111debfc3dSmrg 	  __first = traits_type::find(__first, __len - __n + 1, __elem0);
12121debfc3dSmrg 	  if (!__first)
12131debfc3dSmrg 	    return npos;
12141debfc3dSmrg 	  // Compare the full strings from the first occurrence of __elem0.
12151debfc3dSmrg 	  // We already know that __first[0] == __s[0] but compare them again
12161debfc3dSmrg 	  // anyway because __s is probably aligned, which helps memcmp.
12171debfc3dSmrg 	  if (traits_type::compare(__first, __s, __n) == 0)
12181debfc3dSmrg 	    return __first - __data;
12191debfc3dSmrg 	  __len = __last - ++__first;
12201debfc3dSmrg 	}
12211debfc3dSmrg       return npos;
12221debfc3dSmrg     }
12231debfc3dSmrg 
12241debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
12251debfc3dSmrg     typename basic_string<_CharT, _Traits, _Alloc>::size_type
12261debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
find(_CharT __c,size_type __pos) const12271debfc3dSmrg     find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
12281debfc3dSmrg     {
12291debfc3dSmrg       size_type __ret = npos;
12301debfc3dSmrg       const size_type __size = this->size();
12311debfc3dSmrg       if (__pos < __size)
12321debfc3dSmrg 	{
12331debfc3dSmrg 	  const _CharT* __data = _M_data();
12341debfc3dSmrg 	  const size_type __n = __size - __pos;
12351debfc3dSmrg 	  const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
12361debfc3dSmrg 	  if (__p)
12371debfc3dSmrg 	    __ret = __p - __data;
12381debfc3dSmrg 	}
12391debfc3dSmrg       return __ret;
12401debfc3dSmrg     }
12411debfc3dSmrg 
12421debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
12431debfc3dSmrg     typename basic_string<_CharT, _Traits, _Alloc>::size_type
12441debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
rfind(const _CharT * __s,size_type __pos,size_type __n) const12451debfc3dSmrg     rfind(const _CharT* __s, size_type __pos, size_type __n) const
12461debfc3dSmrg     _GLIBCXX_NOEXCEPT
12471debfc3dSmrg     {
12481debfc3dSmrg       __glibcxx_requires_string_len(__s, __n);
12491debfc3dSmrg       const size_type __size = this->size();
12501debfc3dSmrg       if (__n <= __size)
12511debfc3dSmrg 	{
12521debfc3dSmrg 	  __pos = std::min(size_type(__size - __n), __pos);
12531debfc3dSmrg 	  const _CharT* __data = _M_data();
12541debfc3dSmrg 	  do
12551debfc3dSmrg 	    {
12561debfc3dSmrg 	      if (traits_type::compare(__data + __pos, __s, __n) == 0)
12571debfc3dSmrg 		return __pos;
12581debfc3dSmrg 	    }
12591debfc3dSmrg 	  while (__pos-- > 0);
12601debfc3dSmrg 	}
12611debfc3dSmrg       return npos;
12621debfc3dSmrg     }
12631debfc3dSmrg 
12641debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
12651debfc3dSmrg     typename basic_string<_CharT, _Traits, _Alloc>::size_type
12661debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
rfind(_CharT __c,size_type __pos) const12671debfc3dSmrg     rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
12681debfc3dSmrg     {
12691debfc3dSmrg       size_type __size = this->size();
12701debfc3dSmrg       if (__size)
12711debfc3dSmrg 	{
12721debfc3dSmrg 	  if (--__size > __pos)
12731debfc3dSmrg 	    __size = __pos;
12741debfc3dSmrg 	  for (++__size; __size-- > 0; )
12751debfc3dSmrg 	    if (traits_type::eq(_M_data()[__size], __c))
12761debfc3dSmrg 	      return __size;
12771debfc3dSmrg 	}
12781debfc3dSmrg       return npos;
12791debfc3dSmrg     }
12801debfc3dSmrg 
12811debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
12821debfc3dSmrg     typename basic_string<_CharT, _Traits, _Alloc>::size_type
12831debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
find_first_of(const _CharT * __s,size_type __pos,size_type __n) const12841debfc3dSmrg     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
12851debfc3dSmrg     _GLIBCXX_NOEXCEPT
12861debfc3dSmrg     {
12871debfc3dSmrg       __glibcxx_requires_string_len(__s, __n);
12881debfc3dSmrg       for (; __n && __pos < this->size(); ++__pos)
12891debfc3dSmrg 	{
12901debfc3dSmrg 	  const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]);
12911debfc3dSmrg 	  if (__p)
12921debfc3dSmrg 	    return __pos;
12931debfc3dSmrg 	}
12941debfc3dSmrg       return npos;
12951debfc3dSmrg     }
12961debfc3dSmrg 
12971debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
12981debfc3dSmrg     typename basic_string<_CharT, _Traits, _Alloc>::size_type
12991debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
find_last_of(const _CharT * __s,size_type __pos,size_type __n) const13001debfc3dSmrg     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
13011debfc3dSmrg     _GLIBCXX_NOEXCEPT
13021debfc3dSmrg     {
13031debfc3dSmrg       __glibcxx_requires_string_len(__s, __n);
13041debfc3dSmrg       size_type __size = this->size();
13051debfc3dSmrg       if (__size && __n)
13061debfc3dSmrg 	{
13071debfc3dSmrg 	  if (--__size > __pos)
13081debfc3dSmrg 	    __size = __pos;
13091debfc3dSmrg 	  do
13101debfc3dSmrg 	    {
13111debfc3dSmrg 	      if (traits_type::find(__s, __n, _M_data()[__size]))
13121debfc3dSmrg 		return __size;
13131debfc3dSmrg 	    }
13141debfc3dSmrg 	  while (__size-- != 0);
13151debfc3dSmrg 	}
13161debfc3dSmrg       return npos;
13171debfc3dSmrg     }
13181debfc3dSmrg 
13191debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
13201debfc3dSmrg     typename basic_string<_CharT, _Traits, _Alloc>::size_type
13211debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
find_first_not_of(const _CharT * __s,size_type __pos,size_type __n) const13221debfc3dSmrg     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
13231debfc3dSmrg     _GLIBCXX_NOEXCEPT
13241debfc3dSmrg     {
13251debfc3dSmrg       __glibcxx_requires_string_len(__s, __n);
13261debfc3dSmrg       for (; __pos < this->size(); ++__pos)
13271debfc3dSmrg 	if (!traits_type::find(__s, __n, _M_data()[__pos]))
13281debfc3dSmrg 	  return __pos;
13291debfc3dSmrg       return npos;
13301debfc3dSmrg     }
13311debfc3dSmrg 
13321debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
13331debfc3dSmrg     typename basic_string<_CharT, _Traits, _Alloc>::size_type
13341debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
find_first_not_of(_CharT __c,size_type __pos) const13351debfc3dSmrg     find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
13361debfc3dSmrg     {
13371debfc3dSmrg       for (; __pos < this->size(); ++__pos)
13381debfc3dSmrg 	if (!traits_type::eq(_M_data()[__pos], __c))
13391debfc3dSmrg 	  return __pos;
13401debfc3dSmrg       return npos;
13411debfc3dSmrg     }
13421debfc3dSmrg 
13431debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
13441debfc3dSmrg     typename basic_string<_CharT, _Traits, _Alloc>::size_type
13451debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
find_last_not_of(const _CharT * __s,size_type __pos,size_type __n) const13461debfc3dSmrg     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
13471debfc3dSmrg     _GLIBCXX_NOEXCEPT
13481debfc3dSmrg     {
13491debfc3dSmrg       __glibcxx_requires_string_len(__s, __n);
13501debfc3dSmrg       size_type __size = this->size();
13511debfc3dSmrg       if (__size)
13521debfc3dSmrg 	{
13531debfc3dSmrg 	  if (--__size > __pos)
13541debfc3dSmrg 	    __size = __pos;
13551debfc3dSmrg 	  do
13561debfc3dSmrg 	    {
13571debfc3dSmrg 	      if (!traits_type::find(__s, __n, _M_data()[__size]))
13581debfc3dSmrg 		return __size;
13591debfc3dSmrg 	    }
13601debfc3dSmrg 	  while (__size--);
13611debfc3dSmrg 	}
13621debfc3dSmrg       return npos;
13631debfc3dSmrg     }
13641debfc3dSmrg 
13651debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
13661debfc3dSmrg     typename basic_string<_CharT, _Traits, _Alloc>::size_type
13671debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
find_last_not_of(_CharT __c,size_type __pos) const13681debfc3dSmrg     find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
13691debfc3dSmrg     {
13701debfc3dSmrg       size_type __size = this->size();
13711debfc3dSmrg       if (__size)
13721debfc3dSmrg 	{
13731debfc3dSmrg 	  if (--__size > __pos)
13741debfc3dSmrg 	    __size = __pos;
13751debfc3dSmrg 	  do
13761debfc3dSmrg 	    {
13771debfc3dSmrg 	      if (!traits_type::eq(_M_data()[__size], __c))
13781debfc3dSmrg 		return __size;
13791debfc3dSmrg 	    }
13801debfc3dSmrg 	  while (__size--);
13811debfc3dSmrg 	}
13821debfc3dSmrg       return npos;
13831debfc3dSmrg     }
13841debfc3dSmrg 
13851debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
13861debfc3dSmrg     int
13871debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
compare(size_type __pos,size_type __n,const basic_string & __str) const13881debfc3dSmrg     compare(size_type __pos, size_type __n, const basic_string& __str) const
13891debfc3dSmrg     {
13901debfc3dSmrg       _M_check(__pos, "basic_string::compare");
13911debfc3dSmrg       __n = _M_limit(__pos, __n);
13921debfc3dSmrg       const size_type __osize = __str.size();
13931debfc3dSmrg       const size_type __len = std::min(__n, __osize);
13941debfc3dSmrg       int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
13951debfc3dSmrg       if (!__r)
13961debfc3dSmrg 	__r = _S_compare(__n, __osize);
13971debfc3dSmrg       return __r;
13981debfc3dSmrg     }
13991debfc3dSmrg 
14001debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
14011debfc3dSmrg     int
14021debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
compare(size_type __pos1,size_type __n1,const basic_string & __str,size_type __pos2,size_type __n2) const14031debfc3dSmrg     compare(size_type __pos1, size_type __n1, const basic_string& __str,
14041debfc3dSmrg 	    size_type __pos2, size_type __n2) const
14051debfc3dSmrg     {
14061debfc3dSmrg       _M_check(__pos1, "basic_string::compare");
14071debfc3dSmrg       __str._M_check(__pos2, "basic_string::compare");
14081debfc3dSmrg       __n1 = _M_limit(__pos1, __n1);
14091debfc3dSmrg       __n2 = __str._M_limit(__pos2, __n2);
14101debfc3dSmrg       const size_type __len = std::min(__n1, __n2);
14111debfc3dSmrg       int __r = traits_type::compare(_M_data() + __pos1,
14121debfc3dSmrg 				     __str.data() + __pos2, __len);
14131debfc3dSmrg       if (!__r)
14141debfc3dSmrg 	__r = _S_compare(__n1, __n2);
14151debfc3dSmrg       return __r;
14161debfc3dSmrg     }
14171debfc3dSmrg 
14181debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
14191debfc3dSmrg     int
14201debfc3dSmrg     basic_string<_CharT, _Traits, _Alloc>::
compare(const _CharT * __s) const14211debfc3dSmrg     compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT
14221debfc3dSmrg     {
14231debfc3dSmrg       __glibcxx_requires_string(__s);
14241debfc3dSmrg       const size_type __size = this->size();
14251debfc3dSmrg       const size_type __osize = traits_type::length(__s);
14261debfc3dSmrg       const size_type __len = std::min(__size, __osize);
14271debfc3dSmrg       int __r = traits_type::compare(_M_data(), __s, __len);
14281debfc3dSmrg       if (!__r)
14291debfc3dSmrg 	__r = _S_compare(__size, __osize);
14301debfc3dSmrg       return __r;
14311debfc3dSmrg     }
14321debfc3dSmrg 
14331debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
14341debfc3dSmrg     int
14351debfc3dSmrg     basic_string <_CharT, _Traits, _Alloc>::
compare(size_type __pos,size_type __n1,const _CharT * __s) const14361debfc3dSmrg     compare(size_type __pos, size_type __n1, const _CharT* __s) const
14371debfc3dSmrg     {
14381debfc3dSmrg       __glibcxx_requires_string(__s);
14391debfc3dSmrg       _M_check(__pos, "basic_string::compare");
14401debfc3dSmrg       __n1 = _M_limit(__pos, __n1);
14411debfc3dSmrg       const size_type __osize = traits_type::length(__s);
14421debfc3dSmrg       const size_type __len = std::min(__n1, __osize);
14431debfc3dSmrg       int __r = traits_type::compare(_M_data() + __pos, __s, __len);
14441debfc3dSmrg       if (!__r)
14451debfc3dSmrg 	__r = _S_compare(__n1, __osize);
14461debfc3dSmrg       return __r;
14471debfc3dSmrg     }
14481debfc3dSmrg 
14491debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
14501debfc3dSmrg     int
14511debfc3dSmrg     basic_string <_CharT, _Traits, _Alloc>::
compare(size_type __pos,size_type __n1,const _CharT * __s,size_type __n2) const14521debfc3dSmrg     compare(size_type __pos, size_type __n1, const _CharT* __s,
14531debfc3dSmrg 	    size_type __n2) const
14541debfc3dSmrg     {
14551debfc3dSmrg       __glibcxx_requires_string_len(__s, __n2);
14561debfc3dSmrg       _M_check(__pos, "basic_string::compare");
14571debfc3dSmrg       __n1 = _M_limit(__pos, __n1);
14581debfc3dSmrg       const size_type __len = std::min(__n1, __n2);
14591debfc3dSmrg       int __r = traits_type::compare(_M_data() + __pos, __s, __len);
14601debfc3dSmrg       if (!__r)
14611debfc3dSmrg 	__r = _S_compare(__n1, __n2);
14621debfc3dSmrg       return __r;
14631debfc3dSmrg     }
14641debfc3dSmrg 
14651debfc3dSmrg   // 21.3.7.9 basic_string::getline and operators
14661debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
14671debfc3dSmrg     basic_istream<_CharT, _Traits>&
operator >>(basic_istream<_CharT,_Traits> & __in,basic_string<_CharT,_Traits,_Alloc> & __str)14681debfc3dSmrg     operator>>(basic_istream<_CharT, _Traits>& __in,
14691debfc3dSmrg 	       basic_string<_CharT, _Traits, _Alloc>& __str)
14701debfc3dSmrg     {
14711debfc3dSmrg       typedef basic_istream<_CharT, _Traits>		__istream_type;
14721debfc3dSmrg       typedef basic_string<_CharT, _Traits, _Alloc>	__string_type;
14731debfc3dSmrg       typedef typename __istream_type::ios_base         __ios_base;
14741debfc3dSmrg       typedef typename __istream_type::int_type		__int_type;
14751debfc3dSmrg       typedef typename __string_type::size_type		__size_type;
14761debfc3dSmrg       typedef ctype<_CharT>				__ctype_type;
14771debfc3dSmrg       typedef typename __ctype_type::ctype_base         __ctype_base;
14781debfc3dSmrg 
14791debfc3dSmrg       __size_type __extracted = 0;
14801debfc3dSmrg       typename __ios_base::iostate __err = __ios_base::goodbit;
14811debfc3dSmrg       typename __istream_type::sentry __cerb(__in, false);
14821debfc3dSmrg       if (__cerb)
14831debfc3dSmrg 	{
14841debfc3dSmrg 	  __try
14851debfc3dSmrg 	    {
14861debfc3dSmrg 	      // Avoid reallocation for common case.
14871debfc3dSmrg 	      __str.erase();
14881debfc3dSmrg 	      _CharT __buf[128];
14891debfc3dSmrg 	      __size_type __len = 0;
14901debfc3dSmrg 	      const streamsize __w = __in.width();
14911debfc3dSmrg 	      const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
14921debfc3dSmrg 		                              : __str.max_size();
14931debfc3dSmrg 	      const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
14941debfc3dSmrg 	      const __int_type __eof = _Traits::eof();
14951debfc3dSmrg 	      __int_type __c = __in.rdbuf()->sgetc();
14961debfc3dSmrg 
14971debfc3dSmrg 	      while (__extracted < __n
14981debfc3dSmrg 		     && !_Traits::eq_int_type(__c, __eof)
14991debfc3dSmrg 		     && !__ct.is(__ctype_base::space,
15001debfc3dSmrg 				 _Traits::to_char_type(__c)))
15011debfc3dSmrg 		{
15021debfc3dSmrg 		  if (__len == sizeof(__buf) / sizeof(_CharT))
15031debfc3dSmrg 		    {
15041debfc3dSmrg 		      __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
15051debfc3dSmrg 		      __len = 0;
15061debfc3dSmrg 		    }
15071debfc3dSmrg 		  __buf[__len++] = _Traits::to_char_type(__c);
15081debfc3dSmrg 		  ++__extracted;
15091debfc3dSmrg 		  __c = __in.rdbuf()->snextc();
15101debfc3dSmrg 		}
15111debfc3dSmrg 	      __str.append(__buf, __len);
15121debfc3dSmrg 
15131debfc3dSmrg 	      if (_Traits::eq_int_type(__c, __eof))
15141debfc3dSmrg 		__err |= __ios_base::eofbit;
15151debfc3dSmrg 	      __in.width(0);
15161debfc3dSmrg 	    }
15171debfc3dSmrg 	  __catch(__cxxabiv1::__forced_unwind&)
15181debfc3dSmrg 	    {
15191debfc3dSmrg 	      __in._M_setstate(__ios_base::badbit);
15201debfc3dSmrg 	      __throw_exception_again;
15211debfc3dSmrg 	    }
15221debfc3dSmrg 	  __catch(...)
15231debfc3dSmrg 	    {
15241debfc3dSmrg 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
15251debfc3dSmrg 	      // 91. Description of operator>> and getline() for string<>
15261debfc3dSmrg 	      // might cause endless loop
15271debfc3dSmrg 	      __in._M_setstate(__ios_base::badbit);
15281debfc3dSmrg 	    }
15291debfc3dSmrg 	}
15301debfc3dSmrg       // 211.  operator>>(istream&, string&) doesn't set failbit
15311debfc3dSmrg       if (!__extracted)
15321debfc3dSmrg 	__err |= __ios_base::failbit;
15331debfc3dSmrg       if (__err)
15341debfc3dSmrg 	__in.setstate(__err);
15351debfc3dSmrg       return __in;
15361debfc3dSmrg     }
15371debfc3dSmrg 
15381debfc3dSmrg   template<typename _CharT, typename _Traits, typename _Alloc>
15391debfc3dSmrg     basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT,_Traits> & __in,basic_string<_CharT,_Traits,_Alloc> & __str,_CharT __delim)15401debfc3dSmrg     getline(basic_istream<_CharT, _Traits>& __in,
15411debfc3dSmrg 	    basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
15421debfc3dSmrg     {
15431debfc3dSmrg       typedef basic_istream<_CharT, _Traits>		__istream_type;
15441debfc3dSmrg       typedef basic_string<_CharT, _Traits, _Alloc>	__string_type;
15451debfc3dSmrg       typedef typename __istream_type::ios_base         __ios_base;
15461debfc3dSmrg       typedef typename __istream_type::int_type		__int_type;
15471debfc3dSmrg       typedef typename __string_type::size_type		__size_type;
15481debfc3dSmrg 
15491debfc3dSmrg       __size_type __extracted = 0;
15501debfc3dSmrg       const __size_type __n = __str.max_size();
15511debfc3dSmrg       typename __ios_base::iostate __err = __ios_base::goodbit;
15521debfc3dSmrg       typename __istream_type::sentry __cerb(__in, true);
15531debfc3dSmrg       if (__cerb)
15541debfc3dSmrg 	{
15551debfc3dSmrg 	  __try
15561debfc3dSmrg 	    {
15571debfc3dSmrg 	      __str.erase();
15581debfc3dSmrg 	      const __int_type __idelim = _Traits::to_int_type(__delim);
15591debfc3dSmrg 	      const __int_type __eof = _Traits::eof();
15601debfc3dSmrg 	      __int_type __c = __in.rdbuf()->sgetc();
15611debfc3dSmrg 
15621debfc3dSmrg 	      while (__extracted < __n
15631debfc3dSmrg 		     && !_Traits::eq_int_type(__c, __eof)
15641debfc3dSmrg 		     && !_Traits::eq_int_type(__c, __idelim))
15651debfc3dSmrg 		{
15661debfc3dSmrg 		  __str += _Traits::to_char_type(__c);
15671debfc3dSmrg 		  ++__extracted;
15681debfc3dSmrg 		  __c = __in.rdbuf()->snextc();
15691debfc3dSmrg 		}
15701debfc3dSmrg 
15711debfc3dSmrg 	      if (_Traits::eq_int_type(__c, __eof))
15721debfc3dSmrg 		__err |= __ios_base::eofbit;
15731debfc3dSmrg 	      else if (_Traits::eq_int_type(__c, __idelim))
15741debfc3dSmrg 		{
15751debfc3dSmrg 		  ++__extracted;
15761debfc3dSmrg 		  __in.rdbuf()->sbumpc();
15771debfc3dSmrg 		}
15781debfc3dSmrg 	      else
15791debfc3dSmrg 		__err |= __ios_base::failbit;
15801debfc3dSmrg 	    }
15811debfc3dSmrg 	  __catch(__cxxabiv1::__forced_unwind&)
15821debfc3dSmrg 	    {
15831debfc3dSmrg 	      __in._M_setstate(__ios_base::badbit);
15841debfc3dSmrg 	      __throw_exception_again;
15851debfc3dSmrg 	    }
15861debfc3dSmrg 	  __catch(...)
15871debfc3dSmrg 	    {
15881debfc3dSmrg 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
15891debfc3dSmrg 	      // 91. Description of operator>> and getline() for string<>
15901debfc3dSmrg 	      // might cause endless loop
15911debfc3dSmrg 	      __in._M_setstate(__ios_base::badbit);
15921debfc3dSmrg 	    }
15931debfc3dSmrg 	}
15941debfc3dSmrg       if (!__extracted)
15951debfc3dSmrg 	__err |= __ios_base::failbit;
15961debfc3dSmrg       if (__err)
15971debfc3dSmrg 	__in.setstate(__err);
15981debfc3dSmrg       return __in;
15991debfc3dSmrg     }
16001debfc3dSmrg 
16011debfc3dSmrg   // Inhibit implicit instantiations for required instantiations,
16021debfc3dSmrg   // which are defined via explicit instantiations elsewhere.
16031debfc3dSmrg #if _GLIBCXX_EXTERN_TEMPLATE
1604*8feb0f0bSmrg   // The explicit instantiation definitions in src/c++11/string-inst.cc and
1605*8feb0f0bSmrg   // src/c++17/string-inst.cc only instantiate the members required for C++17
1606*8feb0f0bSmrg   // and earlier standards (so not C++20's starts_with and ends_with).
1607*8feb0f0bSmrg   // Suppress the explicit instantiation declarations for C++20, so C++20
1608*8feb0f0bSmrg   // code will implicitly instantiate std::string and std::wstring as needed.
1609c0a68be4Smrg # if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0
16101debfc3dSmrg   extern template class basic_string<char>;
16111debfc3dSmrg # elif ! _GLIBCXX_USE_CXX11_ABI
16121debfc3dSmrg   // Still need to prevent implicit instantiation of the COW empty rep,
16131debfc3dSmrg   // to ensure the definition in libstdc++.so is unique (PR 86138).
16141debfc3dSmrg   extern template basic_string<char>::size_type
16151debfc3dSmrg     basic_string<char>::_Rep::_S_empty_rep_storage[];
16161debfc3dSmrg # endif
16171debfc3dSmrg 
16181debfc3dSmrg   extern template
16191debfc3dSmrg     basic_istream<char>&
16201debfc3dSmrg     operator>>(basic_istream<char>&, string&);
16211debfc3dSmrg   extern template
16221debfc3dSmrg     basic_ostream<char>&
16231debfc3dSmrg     operator<<(basic_ostream<char>&, const string&);
16241debfc3dSmrg   extern template
16251debfc3dSmrg     basic_istream<char>&
16261debfc3dSmrg     getline(basic_istream<char>&, string&, char);
16271debfc3dSmrg   extern template
16281debfc3dSmrg     basic_istream<char>&
16291debfc3dSmrg     getline(basic_istream<char>&, string&);
16301debfc3dSmrg 
16311debfc3dSmrg #ifdef _GLIBCXX_USE_WCHAR_T
1632c0a68be4Smrg # if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0
16331debfc3dSmrg   extern template class basic_string<wchar_t>;
16341debfc3dSmrg # elif ! _GLIBCXX_USE_CXX11_ABI
16351debfc3dSmrg   extern template basic_string<wchar_t>::size_type
16361debfc3dSmrg     basic_string<wchar_t>::_Rep::_S_empty_rep_storage[];
16371debfc3dSmrg # endif
16381debfc3dSmrg 
16391debfc3dSmrg   extern template
16401debfc3dSmrg     basic_istream<wchar_t>&
16411debfc3dSmrg     operator>>(basic_istream<wchar_t>&, wstring&);
16421debfc3dSmrg   extern template
16431debfc3dSmrg     basic_ostream<wchar_t>&
16441debfc3dSmrg     operator<<(basic_ostream<wchar_t>&, const wstring&);
16451debfc3dSmrg   extern template
16461debfc3dSmrg     basic_istream<wchar_t>&
16471debfc3dSmrg     getline(basic_istream<wchar_t>&, wstring&, wchar_t);
16481debfc3dSmrg   extern template
16491debfc3dSmrg     basic_istream<wchar_t>&
16501debfc3dSmrg     getline(basic_istream<wchar_t>&, wstring&);
16511debfc3dSmrg #endif // _GLIBCXX_USE_WCHAR_T
16521debfc3dSmrg #endif // _GLIBCXX_EXTERN_TEMPLATE
16531debfc3dSmrg 
16541debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
16551debfc3dSmrg } // namespace std
16561debfc3dSmrg 
16571debfc3dSmrg #endif
1658