xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/basic_string.tcc (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj // Components for manipulating sequences of characters -*- C++ -*-
238fd1498Szrj 
338fd1498Szrj // Copyright (C) 1997-2018 Free Software Foundation, Inc.
438fd1498Szrj //
538fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
638fd1498Szrj // software; you can redistribute it and/or modify it under the
738fd1498Szrj // terms of the GNU General Public License as published by the
838fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj // any later version.
1038fd1498Szrj 
1138fd1498Szrj // This library is distributed in the hope that it will be useful,
1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1438fd1498Szrj // GNU General Public License for more details.
1538fd1498Szrj 
1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
1838fd1498Szrj // 3.1, as published by the Free Software Foundation.
1938fd1498Szrj 
2038fd1498Szrj // You should have received a copy of the GNU General Public License and
2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2338fd1498Szrj // <http://www.gnu.org/licenses/>.
2438fd1498Szrj 
2538fd1498Szrj /** @file bits/basic_string.tcc
2638fd1498Szrj  *  This is an internal header file, included by other library headers.
2738fd1498Szrj  *  Do not attempt to use it directly. @headername{string}
2838fd1498Szrj  */
2938fd1498Szrj 
3038fd1498Szrj //
3138fd1498Szrj // ISO C++ 14882: 21  Strings library
3238fd1498Szrj //
3338fd1498Szrj 
3438fd1498Szrj // Written by Jason Merrill based upon the specification by Takanori Adachi
3538fd1498Szrj // in ANSI X3J16/94-0013R2.  Rewritten by Nathan Myers to ISO-14882.
3638fd1498Szrj // Non-reference-counted implementation written by Paolo Carlini and
3738fd1498Szrj // updated by Jonathan Wakely for ISO-14882-2011.
3838fd1498Szrj 
3938fd1498Szrj #ifndef _BASIC_STRING_TCC
4038fd1498Szrj #define _BASIC_STRING_TCC 1
4138fd1498Szrj 
4238fd1498Szrj #pragma GCC system_header
4338fd1498Szrj 
4438fd1498Szrj #include <bits/cxxabi_forced.h>
4538fd1498Szrj 
4638fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
4738fd1498Szrj {
4838fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
4938fd1498Szrj 
5038fd1498Szrj #if _GLIBCXX_USE_CXX11_ABI
5138fd1498Szrj 
5238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
5338fd1498Szrj     const typename basic_string<_CharT, _Traits, _Alloc>::size_type
5438fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::npos;
5538fd1498Szrj 
5638fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
5738fd1498Szrj     void
5838fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
swap(basic_string & __s)5938fd1498Szrj     swap(basic_string& __s) _GLIBCXX_NOEXCEPT
6038fd1498Szrj     {
6138fd1498Szrj       if (this == &__s)
6238fd1498Szrj 	return;
6338fd1498Szrj 
6438fd1498Szrj       _Alloc_traits::_S_on_swap(_M_get_allocator(), __s._M_get_allocator());
6538fd1498Szrj 
6638fd1498Szrj       if (_M_is_local())
6738fd1498Szrj 	if (__s._M_is_local())
6838fd1498Szrj 	  {
6938fd1498Szrj 	    if (length() && __s.length())
7038fd1498Szrj 	      {
7138fd1498Szrj 		_CharT __tmp_data[_S_local_capacity + 1];
7238fd1498Szrj 		traits_type::copy(__tmp_data, __s._M_local_buf,
7338fd1498Szrj 				  _S_local_capacity + 1);
7438fd1498Szrj 		traits_type::copy(__s._M_local_buf, _M_local_buf,
7538fd1498Szrj 				  _S_local_capacity + 1);
7638fd1498Szrj 		traits_type::copy(_M_local_buf, __tmp_data,
7738fd1498Szrj 				  _S_local_capacity + 1);
7838fd1498Szrj 	      }
7938fd1498Szrj 	    else if (__s.length())
8038fd1498Szrj 	      {
8138fd1498Szrj 		traits_type::copy(_M_local_buf, __s._M_local_buf,
8238fd1498Szrj 				  _S_local_capacity + 1);
8338fd1498Szrj 		_M_length(__s.length());
8438fd1498Szrj 		__s._M_set_length(0);
8538fd1498Szrj 		return;
8638fd1498Szrj 	      }
8738fd1498Szrj 	    else if (length())
8838fd1498Szrj 	      {
8938fd1498Szrj 		traits_type::copy(__s._M_local_buf, _M_local_buf,
9038fd1498Szrj 				  _S_local_capacity + 1);
9138fd1498Szrj 		__s._M_length(length());
9238fd1498Szrj 		_M_set_length(0);
9338fd1498Szrj 		return;
9438fd1498Szrj 	      }
9538fd1498Szrj 	  }
9638fd1498Szrj 	else
9738fd1498Szrj 	  {
9838fd1498Szrj 	    const size_type __tmp_capacity = __s._M_allocated_capacity;
9938fd1498Szrj 	    traits_type::copy(__s._M_local_buf, _M_local_buf,
10038fd1498Szrj 			      _S_local_capacity + 1);
10138fd1498Szrj 	    _M_data(__s._M_data());
10238fd1498Szrj 	    __s._M_data(__s._M_local_buf);
10338fd1498Szrj 	    _M_capacity(__tmp_capacity);
10438fd1498Szrj 	  }
10538fd1498Szrj       else
10638fd1498Szrj 	{
10738fd1498Szrj 	  const size_type __tmp_capacity = _M_allocated_capacity;
10838fd1498Szrj 	  if (__s._M_is_local())
10938fd1498Szrj 	    {
11038fd1498Szrj 	      traits_type::copy(_M_local_buf, __s._M_local_buf,
11138fd1498Szrj 				_S_local_capacity + 1);
11238fd1498Szrj 	      __s._M_data(_M_data());
11338fd1498Szrj 	      _M_data(_M_local_buf);
11438fd1498Szrj 	    }
11538fd1498Szrj 	  else
11638fd1498Szrj 	    {
11738fd1498Szrj 	      pointer __tmp_ptr = _M_data();
11838fd1498Szrj 	      _M_data(__s._M_data());
11938fd1498Szrj 	      __s._M_data(__tmp_ptr);
12038fd1498Szrj 	      _M_capacity(__s._M_allocated_capacity);
12138fd1498Szrj 	    }
12238fd1498Szrj 	  __s._M_capacity(__tmp_capacity);
12338fd1498Szrj 	}
12438fd1498Szrj 
12538fd1498Szrj       const size_type __tmp_length = length();
12638fd1498Szrj       _M_length(__s.length());
12738fd1498Szrj       __s._M_length(__tmp_length);
12838fd1498Szrj     }
12938fd1498Szrj 
13038fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
13138fd1498Szrj     typename basic_string<_CharT, _Traits, _Alloc>::pointer
13238fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
_M_create(size_type & __capacity,size_type __old_capacity)13338fd1498Szrj     _M_create(size_type& __capacity, size_type __old_capacity)
13438fd1498Szrj     {
13538fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
13638fd1498Szrj       // 83.  String::npos vs. string::max_size()
13738fd1498Szrj       if (__capacity > max_size())
13838fd1498Szrj 	std::__throw_length_error(__N("basic_string::_M_create"));
13938fd1498Szrj 
14038fd1498Szrj       // The below implements an exponential growth policy, necessary to
14138fd1498Szrj       // meet amortized linear time requirements of the library: see
14238fd1498Szrj       // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
14338fd1498Szrj       if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
14438fd1498Szrj 	{
14538fd1498Szrj 	  __capacity = 2 * __old_capacity;
14638fd1498Szrj 	  // Never allocate a string bigger than max_size.
14738fd1498Szrj 	  if (__capacity > max_size())
14838fd1498Szrj 	    __capacity = max_size();
14938fd1498Szrj 	}
15038fd1498Szrj 
15138fd1498Szrj       // NB: Need an array of char_type[__capacity], plus a terminating
15238fd1498Szrj       // null char_type() element.
15338fd1498Szrj       return _Alloc_traits::allocate(_M_get_allocator(), __capacity + 1);
15438fd1498Szrj     }
15538fd1498Szrj 
15638fd1498Szrj   // NB: This is the special case for Input Iterators, used in
15738fd1498Szrj   // istreambuf_iterators, etc.
15838fd1498Szrj   // Input Iterators have a cost structure very different from
15938fd1498Szrj   // pointers, calling for a different coding style.
16038fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
16138fd1498Szrj     template<typename _InIterator>
16238fd1498Szrj       void
16338fd1498Szrj       basic_string<_CharT, _Traits, _Alloc>::
_M_construct(_InIterator __beg,_InIterator __end,std::input_iterator_tag)16438fd1498Szrj       _M_construct(_InIterator __beg, _InIterator __end,
16538fd1498Szrj 		   std::input_iterator_tag)
16638fd1498Szrj       {
16738fd1498Szrj 	size_type __len = 0;
16838fd1498Szrj 	size_type __capacity = size_type(_S_local_capacity);
16938fd1498Szrj 
17038fd1498Szrj 	while (__beg != __end && __len < __capacity)
17138fd1498Szrj 	  {
17238fd1498Szrj 	    _M_data()[__len++] = *__beg;
17338fd1498Szrj 	    ++__beg;
17438fd1498Szrj 	  }
17538fd1498Szrj 
17638fd1498Szrj 	__try
17738fd1498Szrj 	  {
17838fd1498Szrj 	    while (__beg != __end)
17938fd1498Szrj 	      {
18038fd1498Szrj 		if (__len == __capacity)
18138fd1498Szrj 		  {
18238fd1498Szrj 		    // Allocate more space.
18338fd1498Szrj 		    __capacity = __len + 1;
18438fd1498Szrj 		    pointer __another = _M_create(__capacity, __len);
18538fd1498Szrj 		    this->_S_copy(__another, _M_data(), __len);
18638fd1498Szrj 		    _M_dispose();
18738fd1498Szrj 		    _M_data(__another);
18838fd1498Szrj 		    _M_capacity(__capacity);
18938fd1498Szrj 		  }
19038fd1498Szrj 		_M_data()[__len++] = *__beg;
19138fd1498Szrj 		++__beg;
19238fd1498Szrj 	      }
19338fd1498Szrj 	  }
19438fd1498Szrj 	__catch(...)
19538fd1498Szrj 	  {
19638fd1498Szrj 	    _M_dispose();
19738fd1498Szrj 	    __throw_exception_again;
19838fd1498Szrj 	  }
19938fd1498Szrj 
20038fd1498Szrj 	_M_set_length(__len);
20138fd1498Szrj       }
20238fd1498Szrj 
20338fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
20438fd1498Szrj     template<typename _InIterator>
20538fd1498Szrj       void
20638fd1498Szrj       basic_string<_CharT, _Traits, _Alloc>::
_M_construct(_InIterator __beg,_InIterator __end,std::forward_iterator_tag)20738fd1498Szrj       _M_construct(_InIterator __beg, _InIterator __end,
20838fd1498Szrj 		   std::forward_iterator_tag)
20938fd1498Szrj       {
21038fd1498Szrj 	// NB: Not required, but considered best practice.
21138fd1498Szrj 	if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end)
21238fd1498Szrj 	  std::__throw_logic_error(__N("basic_string::"
21338fd1498Szrj 				       "_M_construct null not valid"));
21438fd1498Szrj 
21538fd1498Szrj 	size_type __dnew = static_cast<size_type>(std::distance(__beg, __end));
21638fd1498Szrj 
21738fd1498Szrj 	if (__dnew > size_type(_S_local_capacity))
21838fd1498Szrj 	  {
21938fd1498Szrj 	    _M_data(_M_create(__dnew, size_type(0)));
22038fd1498Szrj 	    _M_capacity(__dnew);
22138fd1498Szrj 	  }
22238fd1498Szrj 
22338fd1498Szrj 	// Check for out_of_range and length_error exceptions.
22438fd1498Szrj 	__try
22538fd1498Szrj 	  { this->_S_copy_chars(_M_data(), __beg, __end); }
22638fd1498Szrj 	__catch(...)
22738fd1498Szrj 	  {
22838fd1498Szrj 	    _M_dispose();
22938fd1498Szrj 	    __throw_exception_again;
23038fd1498Szrj 	  }
23138fd1498Szrj 
23238fd1498Szrj 	_M_set_length(__dnew);
23338fd1498Szrj       }
23438fd1498Szrj 
23538fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
23638fd1498Szrj     void
23738fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
_M_construct(size_type __n,_CharT __c)23838fd1498Szrj     _M_construct(size_type __n, _CharT __c)
23938fd1498Szrj     {
24038fd1498Szrj       if (__n > size_type(_S_local_capacity))
24138fd1498Szrj 	{
24238fd1498Szrj 	  _M_data(_M_create(__n, size_type(0)));
24338fd1498Szrj 	  _M_capacity(__n);
24438fd1498Szrj 	}
24538fd1498Szrj 
24638fd1498Szrj       if (__n)
24738fd1498Szrj 	this->_S_assign(_M_data(), __n, __c);
24838fd1498Szrj 
24938fd1498Szrj       _M_set_length(__n);
25038fd1498Szrj     }
25138fd1498Szrj 
25238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
25338fd1498Szrj     void
25438fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
_M_assign(const basic_string & __str)25538fd1498Szrj     _M_assign(const basic_string& __str)
25638fd1498Szrj     {
25738fd1498Szrj       if (this != &__str)
25838fd1498Szrj 	{
25938fd1498Szrj 	  const size_type __rsize = __str.length();
26038fd1498Szrj 	  const size_type __capacity = capacity();
26138fd1498Szrj 
26238fd1498Szrj 	  if (__rsize > __capacity)
26338fd1498Szrj 	    {
26438fd1498Szrj 	      size_type __new_capacity = __rsize;
26538fd1498Szrj 	      pointer __tmp = _M_create(__new_capacity, __capacity);
26638fd1498Szrj 	      _M_dispose();
26738fd1498Szrj 	      _M_data(__tmp);
26838fd1498Szrj 	      _M_capacity(__new_capacity);
26938fd1498Szrj 	    }
27038fd1498Szrj 
27138fd1498Szrj 	  if (__rsize)
27238fd1498Szrj 	    this->_S_copy(_M_data(), __str._M_data(), __rsize);
27338fd1498Szrj 
27438fd1498Szrj 	  _M_set_length(__rsize);
27538fd1498Szrj 	}
27638fd1498Szrj     }
27738fd1498Szrj 
27838fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
27938fd1498Szrj     void
28038fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
reserve(size_type __res)28138fd1498Szrj     reserve(size_type __res)
28238fd1498Szrj     {
28338fd1498Szrj       // Make sure we don't shrink below the current size.
28438fd1498Szrj       if (__res < length())
28538fd1498Szrj 	__res = length();
28638fd1498Szrj 
28738fd1498Szrj       const size_type __capacity = capacity();
28838fd1498Szrj       if (__res != __capacity)
28938fd1498Szrj 	{
29038fd1498Szrj 	  if (__res > __capacity
29138fd1498Szrj 	      || __res > size_type(_S_local_capacity))
29238fd1498Szrj 	    {
29338fd1498Szrj 	      pointer __tmp = _M_create(__res, __capacity);
29438fd1498Szrj 	      this->_S_copy(__tmp, _M_data(), length() + 1);
29538fd1498Szrj 	      _M_dispose();
29638fd1498Szrj 	      _M_data(__tmp);
29738fd1498Szrj 	      _M_capacity(__res);
29838fd1498Szrj 	    }
29938fd1498Szrj 	  else if (!_M_is_local())
30038fd1498Szrj 	    {
30138fd1498Szrj 	      this->_S_copy(_M_local_data(), _M_data(), length() + 1);
30238fd1498Szrj 	      _M_destroy(__capacity);
30338fd1498Szrj 	      _M_data(_M_local_data());
30438fd1498Szrj 	    }
30538fd1498Szrj 	}
30638fd1498Szrj     }
30738fd1498Szrj 
30838fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
30938fd1498Szrj     void
31038fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
_M_mutate(size_type __pos,size_type __len1,const _CharT * __s,size_type __len2)31138fd1498Szrj     _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
31238fd1498Szrj 	      size_type __len2)
31338fd1498Szrj     {
31438fd1498Szrj       const size_type __how_much = length() - __pos - __len1;
31538fd1498Szrj 
31638fd1498Szrj       size_type __new_capacity = length() + __len2 - __len1;
31738fd1498Szrj       pointer __r = _M_create(__new_capacity, capacity());
31838fd1498Szrj 
31938fd1498Szrj       if (__pos)
32038fd1498Szrj 	this->_S_copy(__r, _M_data(), __pos);
32138fd1498Szrj       if (__s && __len2)
32238fd1498Szrj 	this->_S_copy(__r + __pos, __s, __len2);
32338fd1498Szrj       if (__how_much)
32438fd1498Szrj 	this->_S_copy(__r + __pos + __len2,
32538fd1498Szrj 		      _M_data() + __pos + __len1, __how_much);
32638fd1498Szrj 
32738fd1498Szrj       _M_dispose();
32838fd1498Szrj       _M_data(__r);
32938fd1498Szrj       _M_capacity(__new_capacity);
33038fd1498Szrj     }
33138fd1498Szrj 
33238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
33338fd1498Szrj     void
33438fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
_M_erase(size_type __pos,size_type __n)33538fd1498Szrj     _M_erase(size_type __pos, size_type __n)
33638fd1498Szrj     {
33738fd1498Szrj       const size_type __how_much = length() - __pos - __n;
33838fd1498Szrj 
33938fd1498Szrj       if (__how_much && __n)
34038fd1498Szrj 	this->_S_move(_M_data() + __pos, _M_data() + __pos + __n, __how_much);
34138fd1498Szrj 
34238fd1498Szrj       _M_set_length(length() - __n);
34338fd1498Szrj     }
34438fd1498Szrj 
34538fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
34638fd1498Szrj     void
34738fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
resize(size_type __n,_CharT __c)34838fd1498Szrj     resize(size_type __n, _CharT __c)
34938fd1498Szrj     {
35038fd1498Szrj       const size_type __size = this->size();
35138fd1498Szrj       if (__size < __n)
35238fd1498Szrj 	this->append(__n - __size, __c);
35338fd1498Szrj       else if (__n < __size)
35438fd1498Szrj 	this->_M_set_length(__n);
35538fd1498Szrj     }
35638fd1498Szrj 
35738fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
35838fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>&
35938fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
_M_append(const _CharT * __s,size_type __n)36038fd1498Szrj     _M_append(const _CharT* __s, size_type __n)
36138fd1498Szrj     {
36238fd1498Szrj       const size_type __len = __n + this->size();
36338fd1498Szrj 
36438fd1498Szrj       if (__len <= this->capacity())
36538fd1498Szrj 	{
36638fd1498Szrj 	  if (__n)
36738fd1498Szrj 	    this->_S_copy(this->_M_data() + this->size(), __s, __n);
36838fd1498Szrj 	}
36938fd1498Szrj       else
37038fd1498Szrj 	this->_M_mutate(this->size(), size_type(0), __s, __n);
37138fd1498Szrj 
37238fd1498Szrj       this->_M_set_length(__len);
37338fd1498Szrj       return *this;
37438fd1498Szrj     }
37538fd1498Szrj 
37638fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
37738fd1498Szrj     template<typename _InputIterator>
37838fd1498Szrj       basic_string<_CharT, _Traits, _Alloc>&
37938fd1498Szrj       basic_string<_CharT, _Traits, _Alloc>::
_M_replace_dispatch(const_iterator __i1,const_iterator __i2,_InputIterator __k1,_InputIterator __k2,std::__false_type)38038fd1498Szrj       _M_replace_dispatch(const_iterator __i1, const_iterator __i2,
38138fd1498Szrj 			  _InputIterator __k1, _InputIterator __k2,
38238fd1498Szrj 			  std::__false_type)
38338fd1498Szrj       {
38438fd1498Szrj 	const basic_string __s(__k1, __k2);
38538fd1498Szrj 	const size_type __n1 = __i2 - __i1;
38638fd1498Szrj 	return _M_replace(__i1 - begin(), __n1, __s._M_data(),
38738fd1498Szrj 			  __s.size());
38838fd1498Szrj       }
38938fd1498Szrj 
39038fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
39138fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>&
39238fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
_M_replace_aux(size_type __pos1,size_type __n1,size_type __n2,_CharT __c)39338fd1498Szrj     _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
39438fd1498Szrj 		   _CharT __c)
39538fd1498Szrj     {
39638fd1498Szrj       _M_check_length(__n1, __n2, "basic_string::_M_replace_aux");
39738fd1498Szrj 
39838fd1498Szrj       const size_type __old_size = this->size();
39938fd1498Szrj       const size_type __new_size = __old_size + __n2 - __n1;
40038fd1498Szrj 
40138fd1498Szrj       if (__new_size <= this->capacity())
40238fd1498Szrj 	{
40338fd1498Szrj 	  pointer __p = this->_M_data() + __pos1;
40438fd1498Szrj 
40538fd1498Szrj 	  const size_type __how_much = __old_size - __pos1 - __n1;
40638fd1498Szrj 	  if (__how_much && __n1 != __n2)
40738fd1498Szrj 	    this->_S_move(__p + __n2, __p + __n1, __how_much);
40838fd1498Szrj 	}
40938fd1498Szrj       else
41038fd1498Szrj 	this->_M_mutate(__pos1, __n1, 0, __n2);
41138fd1498Szrj 
41238fd1498Szrj       if (__n2)
41338fd1498Szrj 	this->_S_assign(this->_M_data() + __pos1, __n2, __c);
41438fd1498Szrj 
41538fd1498Szrj       this->_M_set_length(__new_size);
41638fd1498Szrj       return *this;
41738fd1498Szrj     }
41838fd1498Szrj 
41938fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
42038fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>&
42138fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
_M_replace(size_type __pos,size_type __len1,const _CharT * __s,const size_type __len2)42238fd1498Szrj     _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
42338fd1498Szrj 	       const size_type __len2)
42438fd1498Szrj     {
42538fd1498Szrj       _M_check_length(__len1, __len2, "basic_string::_M_replace");
42638fd1498Szrj 
42738fd1498Szrj       const size_type __old_size = this->size();
42838fd1498Szrj       const size_type __new_size = __old_size + __len2 - __len1;
42938fd1498Szrj 
43038fd1498Szrj       if (__new_size <= this->capacity())
43138fd1498Szrj 	{
43238fd1498Szrj 	  pointer __p = this->_M_data() + __pos;
43338fd1498Szrj 
43438fd1498Szrj 	  const size_type __how_much = __old_size - __pos - __len1;
43538fd1498Szrj 	  if (_M_disjunct(__s))
43638fd1498Szrj 	    {
43738fd1498Szrj 	      if (__how_much && __len1 != __len2)
43838fd1498Szrj 		this->_S_move(__p + __len2, __p + __len1, __how_much);
43938fd1498Szrj 	      if (__len2)
44038fd1498Szrj 		this->_S_copy(__p, __s, __len2);
44138fd1498Szrj 	    }
44238fd1498Szrj 	  else
44338fd1498Szrj 	    {
44438fd1498Szrj 	      // Work in-place.
44538fd1498Szrj 	      if (__len2 && __len2 <= __len1)
44638fd1498Szrj 		this->_S_move(__p, __s, __len2);
44738fd1498Szrj 	      if (__how_much && __len1 != __len2)
44838fd1498Szrj 		this->_S_move(__p + __len2, __p + __len1, __how_much);
44938fd1498Szrj 	      if (__len2 > __len1)
45038fd1498Szrj 		{
45138fd1498Szrj 		  if (__s + __len2 <= __p + __len1)
45238fd1498Szrj 		    this->_S_move(__p, __s, __len2);
45338fd1498Szrj 		  else if (__s >= __p + __len1)
45438fd1498Szrj 		    this->_S_copy(__p, __s + __len2 - __len1, __len2);
45538fd1498Szrj 		  else
45638fd1498Szrj 		    {
45738fd1498Szrj 		      const size_type __nleft = (__p + __len1) - __s;
45838fd1498Szrj 		      this->_S_move(__p, __s, __nleft);
45938fd1498Szrj 		      this->_S_copy(__p + __nleft, __p + __len2,
46038fd1498Szrj 				    __len2 - __nleft);
46138fd1498Szrj 		    }
46238fd1498Szrj 		}
46338fd1498Szrj 	    }
46438fd1498Szrj 	}
46538fd1498Szrj       else
46638fd1498Szrj 	this->_M_mutate(__pos, __len1, __s, __len2);
46738fd1498Szrj 
46838fd1498Szrj       this->_M_set_length(__new_size);
46938fd1498Szrj       return *this;
47038fd1498Szrj     }
47138fd1498Szrj 
47238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
47338fd1498Szrj     typename basic_string<_CharT, _Traits, _Alloc>::size_type
47438fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
copy(_CharT * __s,size_type __n,size_type __pos) const47538fd1498Szrj     copy(_CharT* __s, size_type __n, size_type __pos) const
47638fd1498Szrj     {
47738fd1498Szrj       _M_check(__pos, "basic_string::copy");
47838fd1498Szrj       __n = _M_limit(__pos, __n);
47938fd1498Szrj       __glibcxx_requires_string_len(__s, __n);
48038fd1498Szrj       if (__n)
48138fd1498Szrj 	_S_copy(__s, _M_data() + __pos, __n);
48238fd1498Szrj       // 21.3.5.7 par 3: do not append null.  (good.)
48338fd1498Szrj       return __n;
48438fd1498Szrj     }
48538fd1498Szrj 
48638fd1498Szrj #else  // !_GLIBCXX_USE_CXX11_ABI
48738fd1498Szrj 
48838fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
48938fd1498Szrj     const typename basic_string<_CharT, _Traits, _Alloc>::size_type
49038fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
49138fd1498Szrj     _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4;
49238fd1498Szrj 
49338fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
49438fd1498Szrj     const _CharT
49538fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
49638fd1498Szrj     _Rep::_S_terminal = _CharT();
49738fd1498Szrj 
49838fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
49938fd1498Szrj     const typename basic_string<_CharT, _Traits, _Alloc>::size_type
50038fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::npos;
50138fd1498Szrj 
50238fd1498Szrj   // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string)
50338fd1498Szrj   // at static init time (before static ctors are run).
50438fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
50538fd1498Szrj     typename basic_string<_CharT, _Traits, _Alloc>::size_type
50638fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[
50738fd1498Szrj     (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) /
50838fd1498Szrj       sizeof(size_type)];
50938fd1498Szrj 
51038fd1498Szrj   // NB: This is the special case for Input Iterators, used in
51138fd1498Szrj   // istreambuf_iterators, etc.
51238fd1498Szrj   // Input Iterators have a cost structure very different from
51338fd1498Szrj   // pointers, calling for a different coding style.
51438fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
51538fd1498Szrj     template<typename _InIterator>
51638fd1498Szrj       _CharT*
51738fd1498Szrj       basic_string<_CharT, _Traits, _Alloc>::
51838fd1498Szrj       _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
51938fd1498Szrj 		   input_iterator_tag)
52038fd1498Szrj       {
52138fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
52238fd1498Szrj 	if (__beg == __end && __a == _Alloc())
52338fd1498Szrj 	  return _S_empty_rep()._M_refdata();
52438fd1498Szrj #endif
52538fd1498Szrj 	// Avoid reallocation for common case.
52638fd1498Szrj 	_CharT __buf[128];
52738fd1498Szrj 	size_type __len = 0;
52838fd1498Szrj 	while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT))
52938fd1498Szrj 	  {
53038fd1498Szrj 	    __buf[__len++] = *__beg;
53138fd1498Szrj 	    ++__beg;
53238fd1498Szrj 	  }
53338fd1498Szrj 	_Rep* __r = _Rep::_S_create(__len, size_type(0), __a);
53438fd1498Szrj 	_M_copy(__r->_M_refdata(), __buf, __len);
53538fd1498Szrj 	__try
53638fd1498Szrj 	  {
53738fd1498Szrj 	    while (__beg != __end)
53838fd1498Szrj 	      {
53938fd1498Szrj 		if (__len == __r->_M_capacity)
54038fd1498Szrj 		  {
54138fd1498Szrj 		    // Allocate more space.
54238fd1498Szrj 		    _Rep* __another = _Rep::_S_create(__len + 1, __len, __a);
54338fd1498Szrj 		    _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len);
54438fd1498Szrj 		    __r->_M_destroy(__a);
54538fd1498Szrj 		    __r = __another;
54638fd1498Szrj 		  }
54738fd1498Szrj 		__r->_M_refdata()[__len++] = *__beg;
54838fd1498Szrj 		++__beg;
54938fd1498Szrj 	      }
55038fd1498Szrj 	  }
55138fd1498Szrj 	__catch(...)
55238fd1498Szrj 	  {
55338fd1498Szrj 	    __r->_M_destroy(__a);
55438fd1498Szrj 	    __throw_exception_again;
55538fd1498Szrj 	  }
55638fd1498Szrj 	__r->_M_set_length_and_sharable(__len);
55738fd1498Szrj 	return __r->_M_refdata();
55838fd1498Szrj       }
55938fd1498Szrj 
56038fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
56138fd1498Szrj     template <typename _InIterator>
56238fd1498Szrj       _CharT*
56338fd1498Szrj       basic_string<_CharT, _Traits, _Alloc>::
56438fd1498Szrj       _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
56538fd1498Szrj 		   forward_iterator_tag)
56638fd1498Szrj       {
56738fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
56838fd1498Szrj 	if (__beg == __end && __a == _Alloc())
56938fd1498Szrj 	  return _S_empty_rep()._M_refdata();
57038fd1498Szrj #endif
57138fd1498Szrj 	// NB: Not required, but considered best practice.
57238fd1498Szrj 	if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end)
57338fd1498Szrj 	  __throw_logic_error(__N("basic_string::_S_construct null not valid"));
57438fd1498Szrj 
57538fd1498Szrj 	const size_type __dnew = static_cast<size_type>(std::distance(__beg,
57638fd1498Szrj 								      __end));
57738fd1498Szrj 	// Check for out_of_range and length_error exceptions.
57838fd1498Szrj 	_Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a);
57938fd1498Szrj 	__try
58038fd1498Szrj 	  { _S_copy_chars(__r->_M_refdata(), __beg, __end); }
58138fd1498Szrj 	__catch(...)
58238fd1498Szrj 	  {
58338fd1498Szrj 	    __r->_M_destroy(__a);
58438fd1498Szrj 	    __throw_exception_again;
58538fd1498Szrj 	  }
58638fd1498Szrj 	__r->_M_set_length_and_sharable(__dnew);
58738fd1498Szrj 	return __r->_M_refdata();
58838fd1498Szrj       }
58938fd1498Szrj 
59038fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
59138fd1498Szrj     _CharT*
59238fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
59338fd1498Szrj     _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
59438fd1498Szrj     {
59538fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
59638fd1498Szrj       if (__n == 0 && __a == _Alloc())
59738fd1498Szrj 	return _S_empty_rep()._M_refdata();
59838fd1498Szrj #endif
59938fd1498Szrj       // Check for out_of_range and length_error exceptions.
60038fd1498Szrj       _Rep* __r = _Rep::_S_create(__n, size_type(0), __a);
60138fd1498Szrj       if (__n)
60238fd1498Szrj 	_M_assign(__r->_M_refdata(), __n, __c);
60338fd1498Szrj 
60438fd1498Szrj       __r->_M_set_length_and_sharable(__n);
60538fd1498Szrj       return __r->_M_refdata();
60638fd1498Szrj     }
60738fd1498Szrj 
60838fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
60938fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
61038fd1498Szrj     basic_string(const basic_string& __str)
61138fd1498Szrj     : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()),
61238fd1498Szrj 					  __str.get_allocator()),
61338fd1498Szrj 		  __str.get_allocator())
61438fd1498Szrj     { }
61538fd1498Szrj 
61638fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
61738fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
61838fd1498Szrj     basic_string(const _Alloc& __a)
61938fd1498Szrj     : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a)
62038fd1498Szrj     { }
62138fd1498Szrj 
62238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
62338fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
62438fd1498Szrj     basic_string(const basic_string& __str, size_type __pos, const _Alloc& __a)
62538fd1498Szrj     : _M_dataplus(_S_construct(__str._M_data()
62638fd1498Szrj 			       + __str._M_check(__pos,
62738fd1498Szrj 						"basic_string::basic_string"),
62838fd1498Szrj 			       __str._M_data() + __str._M_limit(__pos, npos)
62938fd1498Szrj 			       + __pos, __a), __a)
63038fd1498Szrj     { }
63138fd1498Szrj 
63238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
63338fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
63438fd1498Szrj     basic_string(const basic_string& __str, size_type __pos, size_type __n)
63538fd1498Szrj     : _M_dataplus(_S_construct(__str._M_data()
63638fd1498Szrj 			       + __str._M_check(__pos,
63738fd1498Szrj 						"basic_string::basic_string"),
63838fd1498Szrj 			       __str._M_data() + __str._M_limit(__pos, __n)
63938fd1498Szrj 			       + __pos, _Alloc()), _Alloc())
64038fd1498Szrj     { }
64138fd1498Szrj 
64238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
64338fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
64438fd1498Szrj     basic_string(const basic_string& __str, size_type __pos,
64538fd1498Szrj 		 size_type __n, const _Alloc& __a)
64638fd1498Szrj     : _M_dataplus(_S_construct(__str._M_data()
64738fd1498Szrj 			       + __str._M_check(__pos,
64838fd1498Szrj 						"basic_string::basic_string"),
64938fd1498Szrj 			       __str._M_data() + __str._M_limit(__pos, __n)
65038fd1498Szrj 			       + __pos, __a), __a)
65138fd1498Szrj     { }
65238fd1498Szrj 
65338fd1498Szrj   // TBD: DPG annotate
65438fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
65538fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
65638fd1498Szrj     basic_string(const _CharT* __s, size_type __n, const _Alloc& __a)
65738fd1498Szrj     : _M_dataplus(_S_construct(__s, __s + __n, __a), __a)
65838fd1498Szrj     { }
65938fd1498Szrj 
66038fd1498Szrj   // TBD: DPG annotate
66138fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
66238fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
66338fd1498Szrj     basic_string(const _CharT* __s, const _Alloc& __a)
66438fd1498Szrj     : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) :
66538fd1498Szrj 			       __s + npos, __a), __a)
66638fd1498Szrj     { }
66738fd1498Szrj 
66838fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
66938fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
67038fd1498Szrj     basic_string(size_type __n, _CharT __c, const _Alloc& __a)
67138fd1498Szrj     : _M_dataplus(_S_construct(__n, __c, __a), __a)
67238fd1498Szrj     { }
67338fd1498Szrj 
67438fd1498Szrj   // TBD: DPG annotate
67538fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
67638fd1498Szrj     template<typename _InputIterator>
67738fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
67838fd1498Szrj     basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a)
67938fd1498Szrj     : _M_dataplus(_S_construct(__beg, __end, __a), __a)
68038fd1498Szrj     { }
68138fd1498Szrj 
68238fd1498Szrj #if __cplusplus >= 201103L
68338fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
68438fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
68538fd1498Szrj     basic_string(initializer_list<_CharT> __l, const _Alloc& __a)
68638fd1498Szrj     : _M_dataplus(_S_construct(__l.begin(), __l.end(), __a), __a)
68738fd1498Szrj     { }
68838fd1498Szrj #endif
68938fd1498Szrj 
69038fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
69138fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>&
69238fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
69338fd1498Szrj     assign(const basic_string& __str)
69438fd1498Szrj     {
69538fd1498Szrj       if (_M_rep() != __str._M_rep())
69638fd1498Szrj 	{
69738fd1498Szrj 	  // XXX MT
69838fd1498Szrj 	  const allocator_type __a = this->get_allocator();
69938fd1498Szrj 	  _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator());
70038fd1498Szrj 	  _M_rep()->_M_dispose(__a);
70138fd1498Szrj 	  _M_data(__tmp);
70238fd1498Szrj 	}
70338fd1498Szrj       return *this;
70438fd1498Szrj     }
70538fd1498Szrj 
70638fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
70738fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>&
70838fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
70938fd1498Szrj     assign(const _CharT* __s, size_type __n)
71038fd1498Szrj     {
71138fd1498Szrj       __glibcxx_requires_string_len(__s, __n);
71238fd1498Szrj       _M_check_length(this->size(), __n, "basic_string::assign");
71338fd1498Szrj       if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
71438fd1498Szrj 	return _M_replace_safe(size_type(0), this->size(), __s, __n);
71538fd1498Szrj       else
71638fd1498Szrj 	{
71738fd1498Szrj 	  // Work in-place.
71838fd1498Szrj 	  const size_type __pos = __s - _M_data();
71938fd1498Szrj 	  if (__pos >= __n)
72038fd1498Szrj 	    _M_copy(_M_data(), __s, __n);
72138fd1498Szrj 	  else if (__pos)
72238fd1498Szrj 	    _M_move(_M_data(), __s, __n);
72338fd1498Szrj 	  _M_rep()->_M_set_length_and_sharable(__n);
72438fd1498Szrj 	  return *this;
72538fd1498Szrj 	}
72638fd1498Szrj      }
72738fd1498Szrj 
72838fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
72938fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>&
73038fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
73138fd1498Szrj     append(size_type __n, _CharT __c)
73238fd1498Szrj     {
73338fd1498Szrj       if (__n)
73438fd1498Szrj 	{
73538fd1498Szrj 	  _M_check_length(size_type(0), __n, "basic_string::append");
73638fd1498Szrj 	  const size_type __len = __n + this->size();
73738fd1498Szrj 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
73838fd1498Szrj 	    this->reserve(__len);
73938fd1498Szrj 	  _M_assign(_M_data() + this->size(), __n, __c);
74038fd1498Szrj 	  _M_rep()->_M_set_length_and_sharable(__len);
74138fd1498Szrj 	}
74238fd1498Szrj       return *this;
74338fd1498Szrj     }
74438fd1498Szrj 
74538fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
74638fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>&
74738fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
74838fd1498Szrj     append(const _CharT* __s, size_type __n)
74938fd1498Szrj     {
75038fd1498Szrj       __glibcxx_requires_string_len(__s, __n);
75138fd1498Szrj       if (__n)
75238fd1498Szrj 	{
75338fd1498Szrj 	  _M_check_length(size_type(0), __n, "basic_string::append");
75438fd1498Szrj 	  const size_type __len = __n + this->size();
75538fd1498Szrj 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
75638fd1498Szrj 	    {
75738fd1498Szrj 	      if (_M_disjunct(__s))
75838fd1498Szrj 		this->reserve(__len);
75938fd1498Szrj 	      else
76038fd1498Szrj 		{
76138fd1498Szrj 		  const size_type __off = __s - _M_data();
76238fd1498Szrj 		  this->reserve(__len);
76338fd1498Szrj 		  __s = _M_data() + __off;
76438fd1498Szrj 		}
76538fd1498Szrj 	    }
76638fd1498Szrj 	  _M_copy(_M_data() + this->size(), __s, __n);
76738fd1498Szrj 	  _M_rep()->_M_set_length_and_sharable(__len);
76838fd1498Szrj 	}
76938fd1498Szrj       return *this;
77038fd1498Szrj     }
77138fd1498Szrj 
77238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
77338fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>&
77438fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
77538fd1498Szrj     append(const basic_string& __str)
77638fd1498Szrj     {
77738fd1498Szrj       const size_type __size = __str.size();
77838fd1498Szrj       if (__size)
77938fd1498Szrj 	{
78038fd1498Szrj 	  const size_type __len = __size + this->size();
78138fd1498Szrj 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
78238fd1498Szrj 	    this->reserve(__len);
78338fd1498Szrj 	  _M_copy(_M_data() + this->size(), __str._M_data(), __size);
78438fd1498Szrj 	  _M_rep()->_M_set_length_and_sharable(__len);
78538fd1498Szrj 	}
78638fd1498Szrj       return *this;
78738fd1498Szrj     }
78838fd1498Szrj 
78938fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
79038fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>&
79138fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
79238fd1498Szrj     append(const basic_string& __str, size_type __pos, size_type __n)
79338fd1498Szrj     {
79438fd1498Szrj       __str._M_check(__pos, "basic_string::append");
79538fd1498Szrj       __n = __str._M_limit(__pos, __n);
79638fd1498Szrj       if (__n)
79738fd1498Szrj 	{
79838fd1498Szrj 	  const size_type __len = __n + this->size();
79938fd1498Szrj 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
80038fd1498Szrj 	    this->reserve(__len);
80138fd1498Szrj 	  _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n);
80238fd1498Szrj 	  _M_rep()->_M_set_length_and_sharable(__len);
80338fd1498Szrj 	}
80438fd1498Szrj       return *this;
80538fd1498Szrj     }
80638fd1498Szrj 
80738fd1498Szrj    template<typename _CharT, typename _Traits, typename _Alloc>
80838fd1498Szrj      basic_string<_CharT, _Traits, _Alloc>&
80938fd1498Szrj      basic_string<_CharT, _Traits, _Alloc>::
81038fd1498Szrj      insert(size_type __pos, const _CharT* __s, size_type __n)
81138fd1498Szrj      {
81238fd1498Szrj        __glibcxx_requires_string_len(__s, __n);
81338fd1498Szrj        _M_check(__pos, "basic_string::insert");
81438fd1498Szrj        _M_check_length(size_type(0), __n, "basic_string::insert");
81538fd1498Szrj        if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
81638fd1498Szrj          return _M_replace_safe(__pos, size_type(0), __s, __n);
81738fd1498Szrj        else
81838fd1498Szrj          {
81938fd1498Szrj            // Work in-place.
82038fd1498Szrj            const size_type __off = __s - _M_data();
82138fd1498Szrj            _M_mutate(__pos, 0, __n);
82238fd1498Szrj            __s = _M_data() + __off;
82338fd1498Szrj            _CharT* __p = _M_data() + __pos;
82438fd1498Szrj            if (__s  + __n <= __p)
82538fd1498Szrj              _M_copy(__p, __s, __n);
82638fd1498Szrj            else if (__s >= __p)
82738fd1498Szrj              _M_copy(__p, __s + __n, __n);
82838fd1498Szrj            else
82938fd1498Szrj              {
83038fd1498Szrj 	       const size_type __nleft = __p - __s;
83138fd1498Szrj                _M_copy(__p, __s, __nleft);
83238fd1498Szrj                _M_copy(__p + __nleft, __p + __n, __n - __nleft);
83338fd1498Szrj              }
83438fd1498Szrj            return *this;
83538fd1498Szrj          }
83638fd1498Szrj      }
83738fd1498Szrj 
83838fd1498Szrj    template<typename _CharT, typename _Traits, typename _Alloc>
83938fd1498Szrj      typename basic_string<_CharT, _Traits, _Alloc>::iterator
84038fd1498Szrj      basic_string<_CharT, _Traits, _Alloc>::
84138fd1498Szrj      erase(iterator __first, iterator __last)
84238fd1498Szrj      {
84338fd1498Szrj        _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
84438fd1498Szrj 				&& __last <= _M_iend());
84538fd1498Szrj 
84638fd1498Szrj        // NB: This isn't just an optimization (bail out early when
84738fd1498Szrj        // there is nothing to do, really), it's also a correctness
84838fd1498Szrj        // issue vs MT, see libstdc++/40518.
84938fd1498Szrj        const size_type __size = __last - __first;
85038fd1498Szrj        if (__size)
85138fd1498Szrj 	 {
85238fd1498Szrj 	   const size_type __pos = __first - _M_ibegin();
85338fd1498Szrj 	   _M_mutate(__pos, __size, size_type(0));
85438fd1498Szrj 	   _M_rep()->_M_set_leaked();
85538fd1498Szrj 	   return iterator(_M_data() + __pos);
85638fd1498Szrj 	 }
85738fd1498Szrj        else
85838fd1498Szrj 	 return __first;
85938fd1498Szrj      }
86038fd1498Szrj 
86138fd1498Szrj    template<typename _CharT, typename _Traits, typename _Alloc>
86238fd1498Szrj      basic_string<_CharT, _Traits, _Alloc>&
86338fd1498Szrj      basic_string<_CharT, _Traits, _Alloc>::
86438fd1498Szrj      replace(size_type __pos, size_type __n1, const _CharT* __s,
86538fd1498Szrj 	     size_type __n2)
86638fd1498Szrj      {
86738fd1498Szrj        __glibcxx_requires_string_len(__s, __n2);
86838fd1498Szrj        _M_check(__pos, "basic_string::replace");
86938fd1498Szrj        __n1 = _M_limit(__pos, __n1);
87038fd1498Szrj        _M_check_length(__n1, __n2, "basic_string::replace");
87138fd1498Szrj        bool __left;
87238fd1498Szrj        if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
87338fd1498Szrj          return _M_replace_safe(__pos, __n1, __s, __n2);
87438fd1498Szrj        else if ((__left = __s + __n2 <= _M_data() + __pos)
87538fd1498Szrj 		|| _M_data() + __pos + __n1 <= __s)
87638fd1498Szrj 	 {
87738fd1498Szrj 	   // Work in-place: non-overlapping case.
87838fd1498Szrj 	   size_type __off = __s - _M_data();
87938fd1498Szrj 	   __left ? __off : (__off += __n2 - __n1);
88038fd1498Szrj 	   _M_mutate(__pos, __n1, __n2);
88138fd1498Szrj 	   _M_copy(_M_data() + __pos, _M_data() + __off, __n2);
88238fd1498Szrj 	   return *this;
88338fd1498Szrj 	 }
88438fd1498Szrj        else
88538fd1498Szrj 	 {
88638fd1498Szrj 	   // Todo: overlapping case.
88738fd1498Szrj 	   const basic_string __tmp(__s, __n2);
88838fd1498Szrj 	   return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
88938fd1498Szrj 	 }
89038fd1498Szrj      }
89138fd1498Szrj 
89238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
89338fd1498Szrj     void
89438fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::_Rep::
89538fd1498Szrj     _M_destroy(const _Alloc& __a) throw ()
89638fd1498Szrj     {
89738fd1498Szrj       const size_type __size = sizeof(_Rep_base) +
89838fd1498Szrj 	                       (this->_M_capacity + 1) * sizeof(_CharT);
89938fd1498Szrj       _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);
90038fd1498Szrj     }
90138fd1498Szrj 
90238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
90338fd1498Szrj     void
90438fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
90538fd1498Szrj     _M_leak_hard()
90638fd1498Szrj     {
90738fd1498Szrj #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
90838fd1498Szrj       if (_M_rep() == &_S_empty_rep())
90938fd1498Szrj 	return;
91038fd1498Szrj #endif
91138fd1498Szrj       if (_M_rep()->_M_is_shared())
91238fd1498Szrj 	_M_mutate(0, 0, 0);
91338fd1498Szrj       _M_rep()->_M_set_leaked();
91438fd1498Szrj     }
91538fd1498Szrj 
91638fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
91738fd1498Szrj     void
91838fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
91938fd1498Szrj     _M_mutate(size_type __pos, size_type __len1, size_type __len2)
92038fd1498Szrj     {
92138fd1498Szrj       const size_type __old_size = this->size();
92238fd1498Szrj       const size_type __new_size = __old_size + __len2 - __len1;
92338fd1498Szrj       const size_type __how_much = __old_size - __pos - __len1;
92438fd1498Szrj 
92538fd1498Szrj       if (__new_size > this->capacity() || _M_rep()->_M_is_shared())
92638fd1498Szrj 	{
92738fd1498Szrj 	  // Must reallocate.
92838fd1498Szrj 	  const allocator_type __a = get_allocator();
92938fd1498Szrj 	  _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a);
93038fd1498Szrj 
93138fd1498Szrj 	  if (__pos)
93238fd1498Szrj 	    _M_copy(__r->_M_refdata(), _M_data(), __pos);
93338fd1498Szrj 	  if (__how_much)
93438fd1498Szrj 	    _M_copy(__r->_M_refdata() + __pos + __len2,
93538fd1498Szrj 		    _M_data() + __pos + __len1, __how_much);
93638fd1498Szrj 
93738fd1498Szrj 	  _M_rep()->_M_dispose(__a);
93838fd1498Szrj 	  _M_data(__r->_M_refdata());
93938fd1498Szrj 	}
94038fd1498Szrj       else if (__how_much && __len1 != __len2)
94138fd1498Szrj 	{
94238fd1498Szrj 	  // Work in-place.
94338fd1498Szrj 	  _M_move(_M_data() + __pos + __len2,
94438fd1498Szrj 		  _M_data() + __pos + __len1, __how_much);
94538fd1498Szrj 	}
94638fd1498Szrj       _M_rep()->_M_set_length_and_sharable(__new_size);
94738fd1498Szrj     }
94838fd1498Szrj 
94938fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
95038fd1498Szrj     void
95138fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
95238fd1498Szrj     reserve(size_type __res)
95338fd1498Szrj     {
95438fd1498Szrj       if (__res != this->capacity() || _M_rep()->_M_is_shared())
95538fd1498Szrj         {
95638fd1498Szrj 	  // Make sure we don't shrink below the current size
95738fd1498Szrj 	  if (__res < this->size())
95838fd1498Szrj 	    __res = this->size();
95938fd1498Szrj 	  const allocator_type __a = get_allocator();
96038fd1498Szrj 	  _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size());
96138fd1498Szrj 	  _M_rep()->_M_dispose(__a);
96238fd1498Szrj 	  _M_data(__tmp);
96338fd1498Szrj         }
96438fd1498Szrj     }
96538fd1498Szrj 
96638fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
96738fd1498Szrj     void
96838fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
96938fd1498Szrj     swap(basic_string& __s)
97038fd1498Szrj     {
97138fd1498Szrj       if (_M_rep()->_M_is_leaked())
97238fd1498Szrj 	_M_rep()->_M_set_sharable();
97338fd1498Szrj       if (__s._M_rep()->_M_is_leaked())
97438fd1498Szrj 	__s._M_rep()->_M_set_sharable();
97538fd1498Szrj       if (this->get_allocator() == __s.get_allocator())
97638fd1498Szrj 	{
97738fd1498Szrj 	  _CharT* __tmp = _M_data();
97838fd1498Szrj 	  _M_data(__s._M_data());
97938fd1498Szrj 	  __s._M_data(__tmp);
98038fd1498Szrj 	}
98138fd1498Szrj       // The code below can usually be optimized away.
98238fd1498Szrj       else
98338fd1498Szrj 	{
98438fd1498Szrj 	  const basic_string __tmp1(_M_ibegin(), _M_iend(),
98538fd1498Szrj 				    __s.get_allocator());
98638fd1498Szrj 	  const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(),
98738fd1498Szrj 				    this->get_allocator());
98838fd1498Szrj 	  *this = __tmp2;
98938fd1498Szrj 	  __s = __tmp1;
99038fd1498Szrj 	}
99138fd1498Szrj     }
99238fd1498Szrj 
99338fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
99438fd1498Szrj     typename basic_string<_CharT, _Traits, _Alloc>::_Rep*
99538fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::_Rep::
99638fd1498Szrj     _S_create(size_type __capacity, size_type __old_capacity,
99738fd1498Szrj 	      const _Alloc& __alloc)
99838fd1498Szrj     {
99938fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
100038fd1498Szrj       // 83.  String::npos vs. string::max_size()
100138fd1498Szrj       if (__capacity > _S_max_size)
100238fd1498Szrj 	__throw_length_error(__N("basic_string::_S_create"));
100338fd1498Szrj 
100438fd1498Szrj       // The standard places no restriction on allocating more memory
100538fd1498Szrj       // than is strictly needed within this layer at the moment or as
100638fd1498Szrj       // requested by an explicit application call to reserve().
100738fd1498Szrj 
100838fd1498Szrj       // Many malloc implementations perform quite poorly when an
100938fd1498Szrj       // application attempts to allocate memory in a stepwise fashion
101038fd1498Szrj       // growing each allocation size by only 1 char.  Additionally,
101138fd1498Szrj       // it makes little sense to allocate less linear memory than the
101238fd1498Szrj       // natural blocking size of the malloc implementation.
101338fd1498Szrj       // Unfortunately, we would need a somewhat low-level calculation
101438fd1498Szrj       // with tuned parameters to get this perfect for any particular
101538fd1498Szrj       // malloc implementation.  Fortunately, generalizations about
101638fd1498Szrj       // common features seen among implementations seems to suffice.
101738fd1498Szrj 
101838fd1498Szrj       // __pagesize need not match the actual VM page size for good
101938fd1498Szrj       // results in practice, thus we pick a common value on the low
102038fd1498Szrj       // side.  __malloc_header_size is an estimate of the amount of
102138fd1498Szrj       // overhead per memory allocation (in practice seen N * sizeof
102238fd1498Szrj       // (void*) where N is 0, 2 or 4).  According to folklore,
102338fd1498Szrj       // picking this value on the high side is better than
102438fd1498Szrj       // low-balling it (especially when this algorithm is used with
102538fd1498Szrj       // malloc implementations that allocate memory blocks rounded up
102638fd1498Szrj       // to a size which is a power of 2).
102738fd1498Szrj       const size_type __pagesize = 4096;
102838fd1498Szrj       const size_type __malloc_header_size = 4 * sizeof(void*);
102938fd1498Szrj 
103038fd1498Szrj       // The below implements an exponential growth policy, necessary to
103138fd1498Szrj       // meet amortized linear time requirements of the library: see
103238fd1498Szrj       // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
103338fd1498Szrj       // It's active for allocations requiring an amount of memory above
103438fd1498Szrj       // system pagesize. This is consistent with the requirements of the
103538fd1498Szrj       // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html
103638fd1498Szrj       if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
103738fd1498Szrj 	__capacity = 2 * __old_capacity;
103838fd1498Szrj 
103938fd1498Szrj       // NB: Need an array of char_type[__capacity], plus a terminating
104038fd1498Szrj       // null char_type() element, plus enough for the _Rep data structure.
104138fd1498Szrj       // Whew. Seemingly so needy, yet so elemental.
104238fd1498Szrj       size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
104338fd1498Szrj 
104438fd1498Szrj       const size_type __adj_size = __size + __malloc_header_size;
104538fd1498Szrj       if (__adj_size > __pagesize && __capacity > __old_capacity)
104638fd1498Szrj 	{
104738fd1498Szrj 	  const size_type __extra = __pagesize - __adj_size % __pagesize;
104838fd1498Szrj 	  __capacity += __extra / sizeof(_CharT);
104938fd1498Szrj 	  // Never allocate a string bigger than _S_max_size.
105038fd1498Szrj 	  if (__capacity > _S_max_size)
105138fd1498Szrj 	    __capacity = _S_max_size;
105238fd1498Szrj 	  __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
105338fd1498Szrj 	}
105438fd1498Szrj 
105538fd1498Szrj       // NB: Might throw, but no worries about a leak, mate: _Rep()
105638fd1498Szrj       // does not throw.
105738fd1498Szrj       void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
105838fd1498Szrj       _Rep *__p = new (__place) _Rep;
105938fd1498Szrj       __p->_M_capacity = __capacity;
106038fd1498Szrj       // ABI compatibility - 3.4.x set in _S_create both
106138fd1498Szrj       // _M_refcount and _M_length.  All callers of _S_create
106238fd1498Szrj       // in basic_string.tcc then set just _M_length.
106338fd1498Szrj       // In 4.0.x and later both _M_refcount and _M_length
106438fd1498Szrj       // are initialized in the callers, unfortunately we can
106538fd1498Szrj       // have 3.4.x compiled code with _S_create callers inlined
106638fd1498Szrj       // calling 4.0.x+ _S_create.
106738fd1498Szrj       __p->_M_set_sharable();
106838fd1498Szrj       return __p;
106938fd1498Szrj     }
107038fd1498Szrj 
107138fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
107238fd1498Szrj     _CharT*
107338fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::_Rep::
107438fd1498Szrj     _M_clone(const _Alloc& __alloc, size_type __res)
107538fd1498Szrj     {
107638fd1498Szrj       // Requested capacity of the clone.
107738fd1498Szrj       const size_type __requested_cap = this->_M_length + __res;
107838fd1498Szrj       _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity,
107938fd1498Szrj 				  __alloc);
108038fd1498Szrj       if (this->_M_length)
108138fd1498Szrj 	_M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length);
108238fd1498Szrj 
108338fd1498Szrj       __r->_M_set_length_and_sharable(this->_M_length);
108438fd1498Szrj       return __r->_M_refdata();
108538fd1498Szrj     }
108638fd1498Szrj 
108738fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
108838fd1498Szrj     void
108938fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
109038fd1498Szrj     resize(size_type __n, _CharT __c)
109138fd1498Szrj     {
109238fd1498Szrj       const size_type __size = this->size();
109338fd1498Szrj       _M_check_length(__size, __n, "basic_string::resize");
109438fd1498Szrj       if (__size < __n)
109538fd1498Szrj 	this->append(__n - __size, __c);
109638fd1498Szrj       else if (__n < __size)
109738fd1498Szrj 	this->erase(__n);
109838fd1498Szrj       // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
109938fd1498Szrj     }
110038fd1498Szrj 
110138fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
110238fd1498Szrj     template<typename _InputIterator>
110338fd1498Szrj       basic_string<_CharT, _Traits, _Alloc>&
110438fd1498Szrj       basic_string<_CharT, _Traits, _Alloc>::
110538fd1498Szrj       _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
110638fd1498Szrj 			  _InputIterator __k2, __false_type)
110738fd1498Szrj       {
110838fd1498Szrj 	const basic_string __s(__k1, __k2);
110938fd1498Szrj 	const size_type __n1 = __i2 - __i1;
111038fd1498Szrj 	_M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch");
111138fd1498Szrj 	return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(),
111238fd1498Szrj 			       __s.size());
111338fd1498Szrj       }
111438fd1498Szrj 
111538fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
111638fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>&
111738fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
111838fd1498Szrj     _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
111938fd1498Szrj 		   _CharT __c)
112038fd1498Szrj     {
112138fd1498Szrj       _M_check_length(__n1, __n2, "basic_string::_M_replace_aux");
112238fd1498Szrj       _M_mutate(__pos1, __n1, __n2);
112338fd1498Szrj       if (__n2)
112438fd1498Szrj 	_M_assign(_M_data() + __pos1, __n2, __c);
112538fd1498Szrj       return *this;
112638fd1498Szrj     }
112738fd1498Szrj 
112838fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
112938fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>&
113038fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
113138fd1498Szrj     _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
113238fd1498Szrj 		    size_type __n2)
113338fd1498Szrj     {
113438fd1498Szrj       _M_mutate(__pos1, __n1, __n2);
113538fd1498Szrj       if (__n2)
113638fd1498Szrj 	_M_copy(_M_data() + __pos1, __s, __n2);
113738fd1498Szrj       return *this;
113838fd1498Szrj     }
113938fd1498Szrj 
114038fd1498Szrj     template<typename _CharT, typename _Traits, typename _Alloc>
114138fd1498Szrj     typename basic_string<_CharT, _Traits, _Alloc>::size_type
114238fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
114338fd1498Szrj     copy(_CharT* __s, size_type __n, size_type __pos) const
114438fd1498Szrj     {
114538fd1498Szrj       _M_check(__pos, "basic_string::copy");
114638fd1498Szrj       __n = _M_limit(__pos, __n);
114738fd1498Szrj       __glibcxx_requires_string_len(__s, __n);
114838fd1498Szrj       if (__n)
114938fd1498Szrj 	_M_copy(__s, _M_data() + __pos, __n);
115038fd1498Szrj       // 21.3.5.7 par 3: do not append null.  (good.)
115138fd1498Szrj       return __n;
115238fd1498Szrj     }
115338fd1498Szrj #endif  // !_GLIBCXX_USE_CXX11_ABI
115438fd1498Szrj 
115538fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
115638fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>
operator +(const _CharT * __lhs,const basic_string<_CharT,_Traits,_Alloc> & __rhs)115738fd1498Szrj     operator+(const _CharT* __lhs,
115838fd1498Szrj 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)
115938fd1498Szrj     {
116038fd1498Szrj       __glibcxx_requires_string(__lhs);
116138fd1498Szrj       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
116238fd1498Szrj       typedef typename __string_type::size_type	  __size_type;
116338fd1498Szrj       const __size_type __len = _Traits::length(__lhs);
116438fd1498Szrj       __string_type __str;
116538fd1498Szrj       __str.reserve(__len + __rhs.size());
116638fd1498Szrj       __str.append(__lhs, __len);
116738fd1498Szrj       __str.append(__rhs);
116838fd1498Szrj       return __str;
116938fd1498Szrj     }
117038fd1498Szrj 
117138fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
117238fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>
operator +(_CharT __lhs,const basic_string<_CharT,_Traits,_Alloc> & __rhs)117338fd1498Szrj     operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs)
117438fd1498Szrj     {
117538fd1498Szrj       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
117638fd1498Szrj       typedef typename __string_type::size_type	  __size_type;
117738fd1498Szrj       __string_type __str;
117838fd1498Szrj       const __size_type __len = __rhs.size();
117938fd1498Szrj       __str.reserve(__len + 1);
118038fd1498Szrj       __str.append(__size_type(1), __lhs);
118138fd1498Szrj       __str.append(__rhs);
118238fd1498Szrj       return __str;
118338fd1498Szrj     }
118438fd1498Szrj 
118538fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
118638fd1498Szrj     typename basic_string<_CharT, _Traits, _Alloc>::size_type
118738fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
find(const _CharT * __s,size_type __pos,size_type __n) const118838fd1498Szrj     find(const _CharT* __s, size_type __pos, size_type __n) const
118938fd1498Szrj     _GLIBCXX_NOEXCEPT
119038fd1498Szrj     {
119138fd1498Szrj       __glibcxx_requires_string_len(__s, __n);
119238fd1498Szrj       const size_type __size = this->size();
119338fd1498Szrj 
119438fd1498Szrj       if (__n == 0)
119538fd1498Szrj 	return __pos <= __size ? __pos : npos;
119638fd1498Szrj       if (__pos >= __size)
119738fd1498Szrj 	return npos;
119838fd1498Szrj 
119938fd1498Szrj       const _CharT __elem0 = __s[0];
120038fd1498Szrj       const _CharT* const __data = data();
120138fd1498Szrj       const _CharT* __first = __data + __pos;
120238fd1498Szrj       const _CharT* const __last = __data + __size;
120338fd1498Szrj       size_type __len = __size - __pos;
120438fd1498Szrj 
120538fd1498Szrj       while (__len >= __n)
120638fd1498Szrj 	{
120738fd1498Szrj 	  // Find the first occurrence of __elem0:
120838fd1498Szrj 	  __first = traits_type::find(__first, __len - __n + 1, __elem0);
120938fd1498Szrj 	  if (!__first)
121038fd1498Szrj 	    return npos;
121138fd1498Szrj 	  // Compare the full strings from the first occurrence of __elem0.
121238fd1498Szrj 	  // We already know that __first[0] == __s[0] but compare them again
121338fd1498Szrj 	  // anyway because __s is probably aligned, which helps memcmp.
121438fd1498Szrj 	  if (traits_type::compare(__first, __s, __n) == 0)
121538fd1498Szrj 	    return __first - __data;
121638fd1498Szrj 	  __len = __last - ++__first;
121738fd1498Szrj 	}
121838fd1498Szrj       return npos;
121938fd1498Szrj     }
122038fd1498Szrj 
122138fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
122238fd1498Szrj     typename basic_string<_CharT, _Traits, _Alloc>::size_type
122338fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
find(_CharT __c,size_type __pos) const122438fd1498Szrj     find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
122538fd1498Szrj     {
122638fd1498Szrj       size_type __ret = npos;
122738fd1498Szrj       const size_type __size = this->size();
122838fd1498Szrj       if (__pos < __size)
122938fd1498Szrj 	{
123038fd1498Szrj 	  const _CharT* __data = _M_data();
123138fd1498Szrj 	  const size_type __n = __size - __pos;
123238fd1498Szrj 	  const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
123338fd1498Szrj 	  if (__p)
123438fd1498Szrj 	    __ret = __p - __data;
123538fd1498Szrj 	}
123638fd1498Szrj       return __ret;
123738fd1498Szrj     }
123838fd1498Szrj 
123938fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
124038fd1498Szrj     typename basic_string<_CharT, _Traits, _Alloc>::size_type
124138fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
rfind(const _CharT * __s,size_type __pos,size_type __n) const124238fd1498Szrj     rfind(const _CharT* __s, size_type __pos, size_type __n) const
124338fd1498Szrj     _GLIBCXX_NOEXCEPT
124438fd1498Szrj     {
124538fd1498Szrj       __glibcxx_requires_string_len(__s, __n);
124638fd1498Szrj       const size_type __size = this->size();
124738fd1498Szrj       if (__n <= __size)
124838fd1498Szrj 	{
124938fd1498Szrj 	  __pos = std::min(size_type(__size - __n), __pos);
125038fd1498Szrj 	  const _CharT* __data = _M_data();
125138fd1498Szrj 	  do
125238fd1498Szrj 	    {
125338fd1498Szrj 	      if (traits_type::compare(__data + __pos, __s, __n) == 0)
125438fd1498Szrj 		return __pos;
125538fd1498Szrj 	    }
125638fd1498Szrj 	  while (__pos-- > 0);
125738fd1498Szrj 	}
125838fd1498Szrj       return npos;
125938fd1498Szrj     }
126038fd1498Szrj 
126138fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
126238fd1498Szrj     typename basic_string<_CharT, _Traits, _Alloc>::size_type
126338fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
rfind(_CharT __c,size_type __pos) const126438fd1498Szrj     rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
126538fd1498Szrj     {
126638fd1498Szrj       size_type __size = this->size();
126738fd1498Szrj       if (__size)
126838fd1498Szrj 	{
126938fd1498Szrj 	  if (--__size > __pos)
127038fd1498Szrj 	    __size = __pos;
127138fd1498Szrj 	  for (++__size; __size-- > 0; )
127238fd1498Szrj 	    if (traits_type::eq(_M_data()[__size], __c))
127338fd1498Szrj 	      return __size;
127438fd1498Szrj 	}
127538fd1498Szrj       return npos;
127638fd1498Szrj     }
127738fd1498Szrj 
127838fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
127938fd1498Szrj     typename basic_string<_CharT, _Traits, _Alloc>::size_type
128038fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
find_first_of(const _CharT * __s,size_type __pos,size_type __n) const128138fd1498Szrj     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
128238fd1498Szrj     _GLIBCXX_NOEXCEPT
128338fd1498Szrj     {
128438fd1498Szrj       __glibcxx_requires_string_len(__s, __n);
128538fd1498Szrj       for (; __n && __pos < this->size(); ++__pos)
128638fd1498Szrj 	{
128738fd1498Szrj 	  const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]);
128838fd1498Szrj 	  if (__p)
128938fd1498Szrj 	    return __pos;
129038fd1498Szrj 	}
129138fd1498Szrj       return npos;
129238fd1498Szrj     }
129338fd1498Szrj 
129438fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
129538fd1498Szrj     typename basic_string<_CharT, _Traits, _Alloc>::size_type
129638fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
find_last_of(const _CharT * __s,size_type __pos,size_type __n) const129738fd1498Szrj     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
129838fd1498Szrj     _GLIBCXX_NOEXCEPT
129938fd1498Szrj     {
130038fd1498Szrj       __glibcxx_requires_string_len(__s, __n);
130138fd1498Szrj       size_type __size = this->size();
130238fd1498Szrj       if (__size && __n)
130338fd1498Szrj 	{
130438fd1498Szrj 	  if (--__size > __pos)
130538fd1498Szrj 	    __size = __pos;
130638fd1498Szrj 	  do
130738fd1498Szrj 	    {
130838fd1498Szrj 	      if (traits_type::find(__s, __n, _M_data()[__size]))
130938fd1498Szrj 		return __size;
131038fd1498Szrj 	    }
131138fd1498Szrj 	  while (__size-- != 0);
131238fd1498Szrj 	}
131338fd1498Szrj       return npos;
131438fd1498Szrj     }
131538fd1498Szrj 
131638fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
131738fd1498Szrj     typename basic_string<_CharT, _Traits, _Alloc>::size_type
131838fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
find_first_not_of(const _CharT * __s,size_type __pos,size_type __n) const131938fd1498Szrj     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
132038fd1498Szrj     _GLIBCXX_NOEXCEPT
132138fd1498Szrj     {
132238fd1498Szrj       __glibcxx_requires_string_len(__s, __n);
132338fd1498Szrj       for (; __pos < this->size(); ++__pos)
132438fd1498Szrj 	if (!traits_type::find(__s, __n, _M_data()[__pos]))
132538fd1498Szrj 	  return __pos;
132638fd1498Szrj       return npos;
132738fd1498Szrj     }
132838fd1498Szrj 
132938fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
133038fd1498Szrj     typename basic_string<_CharT, _Traits, _Alloc>::size_type
133138fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
find_first_not_of(_CharT __c,size_type __pos) const133238fd1498Szrj     find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
133338fd1498Szrj     {
133438fd1498Szrj       for (; __pos < this->size(); ++__pos)
133538fd1498Szrj 	if (!traits_type::eq(_M_data()[__pos], __c))
133638fd1498Szrj 	  return __pos;
133738fd1498Szrj       return npos;
133838fd1498Szrj     }
133938fd1498Szrj 
134038fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
134138fd1498Szrj     typename basic_string<_CharT, _Traits, _Alloc>::size_type
134238fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
find_last_not_of(const _CharT * __s,size_type __pos,size_type __n) const134338fd1498Szrj     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
134438fd1498Szrj     _GLIBCXX_NOEXCEPT
134538fd1498Szrj     {
134638fd1498Szrj       __glibcxx_requires_string_len(__s, __n);
134738fd1498Szrj       size_type __size = this->size();
134838fd1498Szrj       if (__size)
134938fd1498Szrj 	{
135038fd1498Szrj 	  if (--__size > __pos)
135138fd1498Szrj 	    __size = __pos;
135238fd1498Szrj 	  do
135338fd1498Szrj 	    {
135438fd1498Szrj 	      if (!traits_type::find(__s, __n, _M_data()[__size]))
135538fd1498Szrj 		return __size;
135638fd1498Szrj 	    }
135738fd1498Szrj 	  while (__size--);
135838fd1498Szrj 	}
135938fd1498Szrj       return npos;
136038fd1498Szrj     }
136138fd1498Szrj 
136238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
136338fd1498Szrj     typename basic_string<_CharT, _Traits, _Alloc>::size_type
136438fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
find_last_not_of(_CharT __c,size_type __pos) const136538fd1498Szrj     find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
136638fd1498Szrj     {
136738fd1498Szrj       size_type __size = this->size();
136838fd1498Szrj       if (__size)
136938fd1498Szrj 	{
137038fd1498Szrj 	  if (--__size > __pos)
137138fd1498Szrj 	    __size = __pos;
137238fd1498Szrj 	  do
137338fd1498Szrj 	    {
137438fd1498Szrj 	      if (!traits_type::eq(_M_data()[__size], __c))
137538fd1498Szrj 		return __size;
137638fd1498Szrj 	    }
137738fd1498Szrj 	  while (__size--);
137838fd1498Szrj 	}
137938fd1498Szrj       return npos;
138038fd1498Szrj     }
138138fd1498Szrj 
138238fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
138338fd1498Szrj     int
138438fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
compare(size_type __pos,size_type __n,const basic_string & __str) const138538fd1498Szrj     compare(size_type __pos, size_type __n, const basic_string& __str) const
138638fd1498Szrj     {
138738fd1498Szrj       _M_check(__pos, "basic_string::compare");
138838fd1498Szrj       __n = _M_limit(__pos, __n);
138938fd1498Szrj       const size_type __osize = __str.size();
139038fd1498Szrj       const size_type __len = std::min(__n, __osize);
139138fd1498Szrj       int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
139238fd1498Szrj       if (!__r)
139338fd1498Szrj 	__r = _S_compare(__n, __osize);
139438fd1498Szrj       return __r;
139538fd1498Szrj     }
139638fd1498Szrj 
139738fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
139838fd1498Szrj     int
139938fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
compare(size_type __pos1,size_type __n1,const basic_string & __str,size_type __pos2,size_type __n2) const140038fd1498Szrj     compare(size_type __pos1, size_type __n1, const basic_string& __str,
140138fd1498Szrj 	    size_type __pos2, size_type __n2) const
140238fd1498Szrj     {
140338fd1498Szrj       _M_check(__pos1, "basic_string::compare");
140438fd1498Szrj       __str._M_check(__pos2, "basic_string::compare");
140538fd1498Szrj       __n1 = _M_limit(__pos1, __n1);
140638fd1498Szrj       __n2 = __str._M_limit(__pos2, __n2);
140738fd1498Szrj       const size_type __len = std::min(__n1, __n2);
140838fd1498Szrj       int __r = traits_type::compare(_M_data() + __pos1,
140938fd1498Szrj 				     __str.data() + __pos2, __len);
141038fd1498Szrj       if (!__r)
141138fd1498Szrj 	__r = _S_compare(__n1, __n2);
141238fd1498Szrj       return __r;
141338fd1498Szrj     }
141438fd1498Szrj 
141538fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
141638fd1498Szrj     int
141738fd1498Szrj     basic_string<_CharT, _Traits, _Alloc>::
compare(const _CharT * __s) const141838fd1498Szrj     compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT
141938fd1498Szrj     {
142038fd1498Szrj       __glibcxx_requires_string(__s);
142138fd1498Szrj       const size_type __size = this->size();
142238fd1498Szrj       const size_type __osize = traits_type::length(__s);
142338fd1498Szrj       const size_type __len = std::min(__size, __osize);
142438fd1498Szrj       int __r = traits_type::compare(_M_data(), __s, __len);
142538fd1498Szrj       if (!__r)
142638fd1498Szrj 	__r = _S_compare(__size, __osize);
142738fd1498Szrj       return __r;
142838fd1498Szrj     }
142938fd1498Szrj 
143038fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
143138fd1498Szrj     int
143238fd1498Szrj     basic_string <_CharT, _Traits, _Alloc>::
compare(size_type __pos,size_type __n1,const _CharT * __s) const143338fd1498Szrj     compare(size_type __pos, size_type __n1, const _CharT* __s) const
143438fd1498Szrj     {
143538fd1498Szrj       __glibcxx_requires_string(__s);
143638fd1498Szrj       _M_check(__pos, "basic_string::compare");
143738fd1498Szrj       __n1 = _M_limit(__pos, __n1);
143838fd1498Szrj       const size_type __osize = traits_type::length(__s);
143938fd1498Szrj       const size_type __len = std::min(__n1, __osize);
144038fd1498Szrj       int __r = traits_type::compare(_M_data() + __pos, __s, __len);
144138fd1498Szrj       if (!__r)
144238fd1498Szrj 	__r = _S_compare(__n1, __osize);
144338fd1498Szrj       return __r;
144438fd1498Szrj     }
144538fd1498Szrj 
144638fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
144738fd1498Szrj     int
144838fd1498Szrj     basic_string <_CharT, _Traits, _Alloc>::
compare(size_type __pos,size_type __n1,const _CharT * __s,size_type __n2) const144938fd1498Szrj     compare(size_type __pos, size_type __n1, const _CharT* __s,
145038fd1498Szrj 	    size_type __n2) const
145138fd1498Szrj     {
145238fd1498Szrj       __glibcxx_requires_string_len(__s, __n2);
145338fd1498Szrj       _M_check(__pos, "basic_string::compare");
145438fd1498Szrj       __n1 = _M_limit(__pos, __n1);
145538fd1498Szrj       const size_type __len = std::min(__n1, __n2);
145638fd1498Szrj       int __r = traits_type::compare(_M_data() + __pos, __s, __len);
145738fd1498Szrj       if (!__r)
145838fd1498Szrj 	__r = _S_compare(__n1, __n2);
145938fd1498Szrj       return __r;
146038fd1498Szrj     }
146138fd1498Szrj 
146238fd1498Szrj   // 21.3.7.9 basic_string::getline and operators
146338fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
146438fd1498Szrj     basic_istream<_CharT, _Traits>&
operator >>(basic_istream<_CharT,_Traits> & __in,basic_string<_CharT,_Traits,_Alloc> & __str)146538fd1498Szrj     operator>>(basic_istream<_CharT, _Traits>& __in,
146638fd1498Szrj 	       basic_string<_CharT, _Traits, _Alloc>& __str)
146738fd1498Szrj     {
146838fd1498Szrj       typedef basic_istream<_CharT, _Traits>		__istream_type;
146938fd1498Szrj       typedef basic_string<_CharT, _Traits, _Alloc>	__string_type;
147038fd1498Szrj       typedef typename __istream_type::ios_base         __ios_base;
147138fd1498Szrj       typedef typename __istream_type::int_type		__int_type;
147238fd1498Szrj       typedef typename __string_type::size_type		__size_type;
147338fd1498Szrj       typedef ctype<_CharT>				__ctype_type;
147438fd1498Szrj       typedef typename __ctype_type::ctype_base         __ctype_base;
147538fd1498Szrj 
147638fd1498Szrj       __size_type __extracted = 0;
147738fd1498Szrj       typename __ios_base::iostate __err = __ios_base::goodbit;
147838fd1498Szrj       typename __istream_type::sentry __cerb(__in, false);
147938fd1498Szrj       if (__cerb)
148038fd1498Szrj 	{
148138fd1498Szrj 	  __try
148238fd1498Szrj 	    {
148338fd1498Szrj 	      // Avoid reallocation for common case.
148438fd1498Szrj 	      __str.erase();
148538fd1498Szrj 	      _CharT __buf[128];
148638fd1498Szrj 	      __size_type __len = 0;
148738fd1498Szrj 	      const streamsize __w = __in.width();
148838fd1498Szrj 	      const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
148938fd1498Szrj 		                              : __str.max_size();
149038fd1498Szrj 	      const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
149138fd1498Szrj 	      const __int_type __eof = _Traits::eof();
149238fd1498Szrj 	      __int_type __c = __in.rdbuf()->sgetc();
149338fd1498Szrj 
149438fd1498Szrj 	      while (__extracted < __n
149538fd1498Szrj 		     && !_Traits::eq_int_type(__c, __eof)
149638fd1498Szrj 		     && !__ct.is(__ctype_base::space,
149738fd1498Szrj 				 _Traits::to_char_type(__c)))
149838fd1498Szrj 		{
149938fd1498Szrj 		  if (__len == sizeof(__buf) / sizeof(_CharT))
150038fd1498Szrj 		    {
150138fd1498Szrj 		      __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
150238fd1498Szrj 		      __len = 0;
150338fd1498Szrj 		    }
150438fd1498Szrj 		  __buf[__len++] = _Traits::to_char_type(__c);
150538fd1498Szrj 		  ++__extracted;
150638fd1498Szrj 		  __c = __in.rdbuf()->snextc();
150738fd1498Szrj 		}
150838fd1498Szrj 	      __str.append(__buf, __len);
150938fd1498Szrj 
151038fd1498Szrj 	      if (_Traits::eq_int_type(__c, __eof))
151138fd1498Szrj 		__err |= __ios_base::eofbit;
151238fd1498Szrj 	      __in.width(0);
151338fd1498Szrj 	    }
151438fd1498Szrj 	  __catch(__cxxabiv1::__forced_unwind&)
151538fd1498Szrj 	    {
151638fd1498Szrj 	      __in._M_setstate(__ios_base::badbit);
151738fd1498Szrj 	      __throw_exception_again;
151838fd1498Szrj 	    }
151938fd1498Szrj 	  __catch(...)
152038fd1498Szrj 	    {
152138fd1498Szrj 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
152238fd1498Szrj 	      // 91. Description of operator>> and getline() for string<>
152338fd1498Szrj 	      // might cause endless loop
152438fd1498Szrj 	      __in._M_setstate(__ios_base::badbit);
152538fd1498Szrj 	    }
152638fd1498Szrj 	}
152738fd1498Szrj       // 211.  operator>>(istream&, string&) doesn't set failbit
152838fd1498Szrj       if (!__extracted)
152938fd1498Szrj 	__err |= __ios_base::failbit;
153038fd1498Szrj       if (__err)
153138fd1498Szrj 	__in.setstate(__err);
153238fd1498Szrj       return __in;
153338fd1498Szrj     }
153438fd1498Szrj 
153538fd1498Szrj   template<typename _CharT, typename _Traits, typename _Alloc>
153638fd1498Szrj     basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT,_Traits> & __in,basic_string<_CharT,_Traits,_Alloc> & __str,_CharT __delim)153738fd1498Szrj     getline(basic_istream<_CharT, _Traits>& __in,
153838fd1498Szrj 	    basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
153938fd1498Szrj     {
154038fd1498Szrj       typedef basic_istream<_CharT, _Traits>		__istream_type;
154138fd1498Szrj       typedef basic_string<_CharT, _Traits, _Alloc>	__string_type;
154238fd1498Szrj       typedef typename __istream_type::ios_base         __ios_base;
154338fd1498Szrj       typedef typename __istream_type::int_type		__int_type;
154438fd1498Szrj       typedef typename __string_type::size_type		__size_type;
154538fd1498Szrj 
154638fd1498Szrj       __size_type __extracted = 0;
154738fd1498Szrj       const __size_type __n = __str.max_size();
154838fd1498Szrj       typename __ios_base::iostate __err = __ios_base::goodbit;
154938fd1498Szrj       typename __istream_type::sentry __cerb(__in, true);
155038fd1498Szrj       if (__cerb)
155138fd1498Szrj 	{
155238fd1498Szrj 	  __try
155338fd1498Szrj 	    {
155438fd1498Szrj 	      __str.erase();
155538fd1498Szrj 	      const __int_type __idelim = _Traits::to_int_type(__delim);
155638fd1498Szrj 	      const __int_type __eof = _Traits::eof();
155738fd1498Szrj 	      __int_type __c = __in.rdbuf()->sgetc();
155838fd1498Szrj 
155938fd1498Szrj 	      while (__extracted < __n
156038fd1498Szrj 		     && !_Traits::eq_int_type(__c, __eof)
156138fd1498Szrj 		     && !_Traits::eq_int_type(__c, __idelim))
156238fd1498Szrj 		{
156338fd1498Szrj 		  __str += _Traits::to_char_type(__c);
156438fd1498Szrj 		  ++__extracted;
156538fd1498Szrj 		  __c = __in.rdbuf()->snextc();
156638fd1498Szrj 		}
156738fd1498Szrj 
156838fd1498Szrj 	      if (_Traits::eq_int_type(__c, __eof))
156938fd1498Szrj 		__err |= __ios_base::eofbit;
157038fd1498Szrj 	      else if (_Traits::eq_int_type(__c, __idelim))
157138fd1498Szrj 		{
157238fd1498Szrj 		  ++__extracted;
157338fd1498Szrj 		  __in.rdbuf()->sbumpc();
157438fd1498Szrj 		}
157538fd1498Szrj 	      else
157638fd1498Szrj 		__err |= __ios_base::failbit;
157738fd1498Szrj 	    }
157838fd1498Szrj 	  __catch(__cxxabiv1::__forced_unwind&)
157938fd1498Szrj 	    {
158038fd1498Szrj 	      __in._M_setstate(__ios_base::badbit);
158138fd1498Szrj 	      __throw_exception_again;
158238fd1498Szrj 	    }
158338fd1498Szrj 	  __catch(...)
158438fd1498Szrj 	    {
158538fd1498Szrj 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
158638fd1498Szrj 	      // 91. Description of operator>> and getline() for string<>
158738fd1498Szrj 	      // might cause endless loop
158838fd1498Szrj 	      __in._M_setstate(__ios_base::badbit);
158938fd1498Szrj 	    }
159038fd1498Szrj 	}
159138fd1498Szrj       if (!__extracted)
159238fd1498Szrj 	__err |= __ios_base::failbit;
159338fd1498Szrj       if (__err)
159438fd1498Szrj 	__in.setstate(__err);
159538fd1498Szrj       return __in;
159638fd1498Szrj     }
159738fd1498Szrj 
159838fd1498Szrj   // Inhibit implicit instantiations for required instantiations,
159938fd1498Szrj   // which are defined via explicit instantiations elsewhere.
1600*58e805e6Szrj #if _GLIBCXX_EXTERN_TEMPLATE
1601*58e805e6Szrj   // The explicit instantiations definitions in src/c++11/string-inst.cc
1602*58e805e6Szrj   // are compiled as C++14, so the new C++17 members aren't instantiated.
1603*58e805e6Szrj   // Until those definitions are compiled as C++17 suppress the declaration,
1604*58e805e6Szrj   // so C++17 code will implicitly instantiate std::string and std::wstring
1605*58e805e6Szrj   // as needed.
1606*58e805e6Szrj # if __cplusplus <= 201402L && _GLIBCXX_EXTERN_TEMPLATE > 0
160738fd1498Szrj   extern template class basic_string<char>;
1608*58e805e6Szrj # elif ! _GLIBCXX_USE_CXX11_ABI
1609*58e805e6Szrj   // Still need to prevent implicit instantiation of the COW empty rep,
1610*58e805e6Szrj   // to ensure the definition in libstdc++.so is unique (PR 86138).
1611*58e805e6Szrj   extern template basic_string<char>::size_type
1612*58e805e6Szrj     basic_string<char>::_Rep::_S_empty_rep_storage[];
1613*58e805e6Szrj # endif
1614*58e805e6Szrj 
161538fd1498Szrj   extern template
161638fd1498Szrj     basic_istream<char>&
161738fd1498Szrj     operator>>(basic_istream<char>&, string&);
161838fd1498Szrj   extern template
161938fd1498Szrj     basic_ostream<char>&
162038fd1498Szrj     operator<<(basic_ostream<char>&, const string&);
162138fd1498Szrj   extern template
162238fd1498Szrj     basic_istream<char>&
162338fd1498Szrj     getline(basic_istream<char>&, string&, char);
162438fd1498Szrj   extern template
162538fd1498Szrj     basic_istream<char>&
162638fd1498Szrj     getline(basic_istream<char>&, string&);
162738fd1498Szrj 
162838fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T
1629*58e805e6Szrj # if __cplusplus <= 201402L && _GLIBCXX_EXTERN_TEMPLATE > 0
163038fd1498Szrj   extern template class basic_string<wchar_t>;
1631*58e805e6Szrj # elif ! _GLIBCXX_USE_CXX11_ABI
1632*58e805e6Szrj   extern template basic_string<wchar_t>::size_type
1633*58e805e6Szrj     basic_string<wchar_t>::_Rep::_S_empty_rep_storage[];
1634*58e805e6Szrj # endif
1635*58e805e6Szrj 
163638fd1498Szrj   extern template
163738fd1498Szrj     basic_istream<wchar_t>&
163838fd1498Szrj     operator>>(basic_istream<wchar_t>&, wstring&);
163938fd1498Szrj   extern template
164038fd1498Szrj     basic_ostream<wchar_t>&
164138fd1498Szrj     operator<<(basic_ostream<wchar_t>&, const wstring&);
164238fd1498Szrj   extern template
164338fd1498Szrj     basic_istream<wchar_t>&
164438fd1498Szrj     getline(basic_istream<wchar_t>&, wstring&, wchar_t);
164538fd1498Szrj   extern template
164638fd1498Szrj     basic_istream<wchar_t>&
164738fd1498Szrj     getline(basic_istream<wchar_t>&, wstring&);
1648*58e805e6Szrj #endif // _GLIBCXX_USE_WCHAR_T
1649*58e805e6Szrj #endif // _GLIBCXX_EXTERN_TEMPLATE
165038fd1498Szrj 
165138fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
165238fd1498Szrj } // namespace std
165338fd1498Szrj 
165438fd1498Szrj #endif
1655