xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/bits/basic_string.tcc (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino // Components for manipulating sequences of characters -*- C++ -*-
2*e4b17023SJohn Marino 
3*e4b17023SJohn Marino // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4*e4b17023SJohn Marino // 2006, 2007, 2008, 2009, 2010, 2011
5*e4b17023SJohn Marino // Free Software Foundation, Inc.
6*e4b17023SJohn Marino //
7*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library.  This library is free
8*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the
9*e4b17023SJohn Marino // terms of the GNU General Public License as published by the
10*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option)
11*e4b17023SJohn Marino // any later version.
12*e4b17023SJohn Marino 
13*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful,
14*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of
15*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*e4b17023SJohn Marino // GNU General Public License for more details.
17*e4b17023SJohn Marino 
18*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
19*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
20*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
21*e4b17023SJohn Marino 
22*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
23*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
24*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
25*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
26*e4b17023SJohn Marino 
27*e4b17023SJohn Marino /** @file bits/basic_string.tcc
28*e4b17023SJohn Marino  *  This is an internal header file, included by other library headers.
29*e4b17023SJohn Marino  *  Do not attempt to use it directly. @headername{string}
30*e4b17023SJohn Marino  */
31*e4b17023SJohn Marino 
32*e4b17023SJohn Marino //
33*e4b17023SJohn Marino // ISO C++ 14882: 21  Strings library
34*e4b17023SJohn Marino //
35*e4b17023SJohn Marino 
36*e4b17023SJohn Marino // Written by Jason Merrill based upon the specification by Takanori Adachi
37*e4b17023SJohn Marino // in ANSI X3J16/94-0013R2.  Rewritten by Nathan Myers to ISO-14882.
38*e4b17023SJohn Marino 
39*e4b17023SJohn Marino #ifndef _BASIC_STRING_TCC
40*e4b17023SJohn Marino #define _BASIC_STRING_TCC 1
41*e4b17023SJohn Marino 
42*e4b17023SJohn Marino #pragma GCC system_header
43*e4b17023SJohn Marino 
44*e4b17023SJohn Marino #include <bits/cxxabi_forced.h>
45*e4b17023SJohn Marino 
46*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default)
47*e4b17023SJohn Marino {
48*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION
49*e4b17023SJohn Marino 
50*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
51*e4b17023SJohn Marino     const typename basic_string<_CharT, _Traits, _Alloc>::size_type
52*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
53*e4b17023SJohn Marino     _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4;
54*e4b17023SJohn Marino 
55*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
56*e4b17023SJohn Marino     const _CharT
57*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
58*e4b17023SJohn Marino     _Rep::_S_terminal = _CharT();
59*e4b17023SJohn Marino 
60*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
61*e4b17023SJohn Marino     const typename basic_string<_CharT, _Traits, _Alloc>::size_type
62*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::npos;
63*e4b17023SJohn Marino 
64*e4b17023SJohn Marino   // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string)
65*e4b17023SJohn Marino   // at static init time (before static ctors are run).
66*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
67*e4b17023SJohn Marino     typename basic_string<_CharT, _Traits, _Alloc>::size_type
68*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[
69*e4b17023SJohn Marino     (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) /
70*e4b17023SJohn Marino       sizeof(size_type)];
71*e4b17023SJohn Marino 
72*e4b17023SJohn Marino   // NB: This is the special case for Input Iterators, used in
73*e4b17023SJohn Marino   // istreambuf_iterators, etc.
74*e4b17023SJohn Marino   // Input Iterators have a cost structure very different from
75*e4b17023SJohn Marino   // pointers, calling for a different coding style.
76*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
77*e4b17023SJohn Marino     template<typename _InIterator>
78*e4b17023SJohn Marino       _CharT*
79*e4b17023SJohn Marino       basic_string<_CharT, _Traits, _Alloc>::
_S_construct(_InIterator __beg,_InIterator __end,const _Alloc & __a,input_iterator_tag)80*e4b17023SJohn Marino       _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
81*e4b17023SJohn Marino 		   input_iterator_tag)
82*e4b17023SJohn Marino       {
83*e4b17023SJohn Marino #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
84*e4b17023SJohn Marino 	if (__beg == __end && __a == _Alloc())
85*e4b17023SJohn Marino 	  return _S_empty_rep()._M_refdata();
86*e4b17023SJohn Marino #endif
87*e4b17023SJohn Marino 	// Avoid reallocation for common case.
88*e4b17023SJohn Marino 	_CharT __buf[128];
89*e4b17023SJohn Marino 	size_type __len = 0;
90*e4b17023SJohn Marino 	while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT))
91*e4b17023SJohn Marino 	  {
92*e4b17023SJohn Marino 	    __buf[__len++] = *__beg;
93*e4b17023SJohn Marino 	    ++__beg;
94*e4b17023SJohn Marino 	  }
95*e4b17023SJohn Marino 	_Rep* __r = _Rep::_S_create(__len, size_type(0), __a);
96*e4b17023SJohn Marino 	_M_copy(__r->_M_refdata(), __buf, __len);
97*e4b17023SJohn Marino 	__try
98*e4b17023SJohn Marino 	  {
99*e4b17023SJohn Marino 	    while (__beg != __end)
100*e4b17023SJohn Marino 	      {
101*e4b17023SJohn Marino 		if (__len == __r->_M_capacity)
102*e4b17023SJohn Marino 		  {
103*e4b17023SJohn Marino 		    // Allocate more space.
104*e4b17023SJohn Marino 		    _Rep* __another = _Rep::_S_create(__len + 1, __len, __a);
105*e4b17023SJohn Marino 		    _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len);
106*e4b17023SJohn Marino 		    __r->_M_destroy(__a);
107*e4b17023SJohn Marino 		    __r = __another;
108*e4b17023SJohn Marino 		  }
109*e4b17023SJohn Marino 		__r->_M_refdata()[__len++] = *__beg;
110*e4b17023SJohn Marino 		++__beg;
111*e4b17023SJohn Marino 	      }
112*e4b17023SJohn Marino 	  }
113*e4b17023SJohn Marino 	__catch(...)
114*e4b17023SJohn Marino 	  {
115*e4b17023SJohn Marino 	    __r->_M_destroy(__a);
116*e4b17023SJohn Marino 	    __throw_exception_again;
117*e4b17023SJohn Marino 	  }
118*e4b17023SJohn Marino 	__r->_M_set_length_and_sharable(__len);
119*e4b17023SJohn Marino 	return __r->_M_refdata();
120*e4b17023SJohn Marino       }
121*e4b17023SJohn Marino 
122*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
123*e4b17023SJohn Marino     template <typename _InIterator>
124*e4b17023SJohn Marino       _CharT*
125*e4b17023SJohn Marino       basic_string<_CharT, _Traits, _Alloc>::
_S_construct(_InIterator __beg,_InIterator __end,const _Alloc & __a,forward_iterator_tag)126*e4b17023SJohn Marino       _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
127*e4b17023SJohn Marino 		   forward_iterator_tag)
128*e4b17023SJohn Marino       {
129*e4b17023SJohn Marino #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
130*e4b17023SJohn Marino 	if (__beg == __end && __a == _Alloc())
131*e4b17023SJohn Marino 	  return _S_empty_rep()._M_refdata();
132*e4b17023SJohn Marino #endif
133*e4b17023SJohn Marino 	// NB: Not required, but considered best practice.
134*e4b17023SJohn Marino 	if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end)
135*e4b17023SJohn Marino 	  __throw_logic_error(__N("basic_string::_S_construct null not valid"));
136*e4b17023SJohn Marino 
137*e4b17023SJohn Marino 	const size_type __dnew = static_cast<size_type>(std::distance(__beg,
138*e4b17023SJohn Marino 								      __end));
139*e4b17023SJohn Marino 	// Check for out_of_range and length_error exceptions.
140*e4b17023SJohn Marino 	_Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a);
141*e4b17023SJohn Marino 	__try
142*e4b17023SJohn Marino 	  { _S_copy_chars(__r->_M_refdata(), __beg, __end); }
143*e4b17023SJohn Marino 	__catch(...)
144*e4b17023SJohn Marino 	  {
145*e4b17023SJohn Marino 	    __r->_M_destroy(__a);
146*e4b17023SJohn Marino 	    __throw_exception_again;
147*e4b17023SJohn Marino 	  }
148*e4b17023SJohn Marino 	__r->_M_set_length_and_sharable(__dnew);
149*e4b17023SJohn Marino 	return __r->_M_refdata();
150*e4b17023SJohn Marino       }
151*e4b17023SJohn Marino 
152*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
153*e4b17023SJohn Marino     _CharT*
154*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
_S_construct(size_type __n,_CharT __c,const _Alloc & __a)155*e4b17023SJohn Marino     _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
156*e4b17023SJohn Marino     {
157*e4b17023SJohn Marino #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
158*e4b17023SJohn Marino       if (__n == 0 && __a == _Alloc())
159*e4b17023SJohn Marino 	return _S_empty_rep()._M_refdata();
160*e4b17023SJohn Marino #endif
161*e4b17023SJohn Marino       // Check for out_of_range and length_error exceptions.
162*e4b17023SJohn Marino       _Rep* __r = _Rep::_S_create(__n, size_type(0), __a);
163*e4b17023SJohn Marino       if (__n)
164*e4b17023SJohn Marino 	_M_assign(__r->_M_refdata(), __n, __c);
165*e4b17023SJohn Marino 
166*e4b17023SJohn Marino       __r->_M_set_length_and_sharable(__n);
167*e4b17023SJohn Marino       return __r->_M_refdata();
168*e4b17023SJohn Marino     }
169*e4b17023SJohn Marino 
170*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
171*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
basic_string(const basic_string & __str)172*e4b17023SJohn Marino     basic_string(const basic_string& __str)
173*e4b17023SJohn Marino     : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()),
174*e4b17023SJohn Marino 					  __str.get_allocator()),
175*e4b17023SJohn Marino 		  __str.get_allocator())
176*e4b17023SJohn Marino     { }
177*e4b17023SJohn Marino 
178*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
179*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
basic_string(const _Alloc & __a)180*e4b17023SJohn Marino     basic_string(const _Alloc& __a)
181*e4b17023SJohn Marino     : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a)
182*e4b17023SJohn Marino     { }
183*e4b17023SJohn Marino 
184*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
185*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
basic_string(const basic_string & __str,size_type __pos,size_type __n)186*e4b17023SJohn Marino     basic_string(const basic_string& __str, size_type __pos, size_type __n)
187*e4b17023SJohn Marino     : _M_dataplus(_S_construct(__str._M_data()
188*e4b17023SJohn Marino 			       + __str._M_check(__pos,
189*e4b17023SJohn Marino 						"basic_string::basic_string"),
190*e4b17023SJohn Marino 			       __str._M_data() + __str._M_limit(__pos, __n)
191*e4b17023SJohn Marino 			       + __pos, _Alloc()), _Alloc())
192*e4b17023SJohn Marino     { }
193*e4b17023SJohn Marino 
194*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
195*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
basic_string(const basic_string & __str,size_type __pos,size_type __n,const _Alloc & __a)196*e4b17023SJohn Marino     basic_string(const basic_string& __str, size_type __pos,
197*e4b17023SJohn Marino 		 size_type __n, const _Alloc& __a)
198*e4b17023SJohn Marino     : _M_dataplus(_S_construct(__str._M_data()
199*e4b17023SJohn Marino 			       + __str._M_check(__pos,
200*e4b17023SJohn Marino 						"basic_string::basic_string"),
201*e4b17023SJohn Marino 			       __str._M_data() + __str._M_limit(__pos, __n)
202*e4b17023SJohn Marino 			       + __pos, __a), __a)
203*e4b17023SJohn Marino     { }
204*e4b17023SJohn Marino 
205*e4b17023SJohn Marino   // TBD: DPG annotate
206*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
207*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
basic_string(const _CharT * __s,size_type __n,const _Alloc & __a)208*e4b17023SJohn Marino     basic_string(const _CharT* __s, size_type __n, const _Alloc& __a)
209*e4b17023SJohn Marino     : _M_dataplus(_S_construct(__s, __s + __n, __a), __a)
210*e4b17023SJohn Marino     { }
211*e4b17023SJohn Marino 
212*e4b17023SJohn Marino   // TBD: DPG annotate
213*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
214*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
basic_string(const _CharT * __s,const _Alloc & __a)215*e4b17023SJohn Marino     basic_string(const _CharT* __s, const _Alloc& __a)
216*e4b17023SJohn Marino     : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) :
217*e4b17023SJohn Marino 			       __s + npos, __a), __a)
218*e4b17023SJohn Marino     { }
219*e4b17023SJohn Marino 
220*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
221*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
basic_string(size_type __n,_CharT __c,const _Alloc & __a)222*e4b17023SJohn Marino     basic_string(size_type __n, _CharT __c, const _Alloc& __a)
223*e4b17023SJohn Marino     : _M_dataplus(_S_construct(__n, __c, __a), __a)
224*e4b17023SJohn Marino     { }
225*e4b17023SJohn Marino 
226*e4b17023SJohn Marino   // TBD: DPG annotate
227*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
228*e4b17023SJohn Marino     template<typename _InputIterator>
229*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
basic_string(_InputIterator __beg,_InputIterator __end,const _Alloc & __a)230*e4b17023SJohn Marino     basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a)
231*e4b17023SJohn Marino     : _M_dataplus(_S_construct(__beg, __end, __a), __a)
232*e4b17023SJohn Marino     { }
233*e4b17023SJohn Marino 
234*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__
235*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
236*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
basic_string(initializer_list<_CharT> __l,const _Alloc & __a)237*e4b17023SJohn Marino     basic_string(initializer_list<_CharT> __l, const _Alloc& __a)
238*e4b17023SJohn Marino     : _M_dataplus(_S_construct(__l.begin(), __l.end(), __a), __a)
239*e4b17023SJohn Marino     { }
240*e4b17023SJohn Marino #endif
241*e4b17023SJohn Marino 
242*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
243*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>&
244*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
assign(const basic_string & __str)245*e4b17023SJohn Marino     assign(const basic_string& __str)
246*e4b17023SJohn Marino     {
247*e4b17023SJohn Marino       if (_M_rep() != __str._M_rep())
248*e4b17023SJohn Marino 	{
249*e4b17023SJohn Marino 	  // XXX MT
250*e4b17023SJohn Marino 	  const allocator_type __a = this->get_allocator();
251*e4b17023SJohn Marino 	  _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator());
252*e4b17023SJohn Marino 	  _M_rep()->_M_dispose(__a);
253*e4b17023SJohn Marino 	  _M_data(__tmp);
254*e4b17023SJohn Marino 	}
255*e4b17023SJohn Marino       return *this;
256*e4b17023SJohn Marino     }
257*e4b17023SJohn Marino 
258*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
259*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>&
260*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
assign(const _CharT * __s,size_type __n)261*e4b17023SJohn Marino     assign(const _CharT* __s, size_type __n)
262*e4b17023SJohn Marino     {
263*e4b17023SJohn Marino       __glibcxx_requires_string_len(__s, __n);
264*e4b17023SJohn Marino       _M_check_length(this->size(), __n, "basic_string::assign");
265*e4b17023SJohn Marino       if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
266*e4b17023SJohn Marino 	return _M_replace_safe(size_type(0), this->size(), __s, __n);
267*e4b17023SJohn Marino       else
268*e4b17023SJohn Marino 	{
269*e4b17023SJohn Marino 	  // Work in-place.
270*e4b17023SJohn Marino 	  const size_type __pos = __s - _M_data();
271*e4b17023SJohn Marino 	  if (__pos >= __n)
272*e4b17023SJohn Marino 	    _M_copy(_M_data(), __s, __n);
273*e4b17023SJohn Marino 	  else if (__pos)
274*e4b17023SJohn Marino 	    _M_move(_M_data(), __s, __n);
275*e4b17023SJohn Marino 	  _M_rep()->_M_set_length_and_sharable(__n);
276*e4b17023SJohn Marino 	  return *this;
277*e4b17023SJohn Marino 	}
278*e4b17023SJohn Marino      }
279*e4b17023SJohn Marino 
280*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
281*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>&
282*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
append(size_type __n,_CharT __c)283*e4b17023SJohn Marino     append(size_type __n, _CharT __c)
284*e4b17023SJohn Marino     {
285*e4b17023SJohn Marino       if (__n)
286*e4b17023SJohn Marino 	{
287*e4b17023SJohn Marino 	  _M_check_length(size_type(0), __n, "basic_string::append");
288*e4b17023SJohn Marino 	  const size_type __len = __n + this->size();
289*e4b17023SJohn Marino 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
290*e4b17023SJohn Marino 	    this->reserve(__len);
291*e4b17023SJohn Marino 	  _M_assign(_M_data() + this->size(), __n, __c);
292*e4b17023SJohn Marino 	  _M_rep()->_M_set_length_and_sharable(__len);
293*e4b17023SJohn Marino 	}
294*e4b17023SJohn Marino       return *this;
295*e4b17023SJohn Marino     }
296*e4b17023SJohn Marino 
297*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
298*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>&
299*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
append(const _CharT * __s,size_type __n)300*e4b17023SJohn Marino     append(const _CharT* __s, size_type __n)
301*e4b17023SJohn Marino     {
302*e4b17023SJohn Marino       __glibcxx_requires_string_len(__s, __n);
303*e4b17023SJohn Marino       if (__n)
304*e4b17023SJohn Marino 	{
305*e4b17023SJohn Marino 	  _M_check_length(size_type(0), __n, "basic_string::append");
306*e4b17023SJohn Marino 	  const size_type __len = __n + this->size();
307*e4b17023SJohn Marino 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
308*e4b17023SJohn Marino 	    {
309*e4b17023SJohn Marino 	      if (_M_disjunct(__s))
310*e4b17023SJohn Marino 		this->reserve(__len);
311*e4b17023SJohn Marino 	      else
312*e4b17023SJohn Marino 		{
313*e4b17023SJohn Marino 		  const size_type __off = __s - _M_data();
314*e4b17023SJohn Marino 		  this->reserve(__len);
315*e4b17023SJohn Marino 		  __s = _M_data() + __off;
316*e4b17023SJohn Marino 		}
317*e4b17023SJohn Marino 	    }
318*e4b17023SJohn Marino 	  _M_copy(_M_data() + this->size(), __s, __n);
319*e4b17023SJohn Marino 	  _M_rep()->_M_set_length_and_sharable(__len);
320*e4b17023SJohn Marino 	}
321*e4b17023SJohn Marino       return *this;
322*e4b17023SJohn Marino     }
323*e4b17023SJohn Marino 
324*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
325*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>&
326*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
append(const basic_string & __str)327*e4b17023SJohn Marino     append(const basic_string& __str)
328*e4b17023SJohn Marino     {
329*e4b17023SJohn Marino       const size_type __size = __str.size();
330*e4b17023SJohn Marino       if (__size)
331*e4b17023SJohn Marino 	{
332*e4b17023SJohn Marino 	  const size_type __len = __size + this->size();
333*e4b17023SJohn Marino 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
334*e4b17023SJohn Marino 	    this->reserve(__len);
335*e4b17023SJohn Marino 	  _M_copy(_M_data() + this->size(), __str._M_data(), __size);
336*e4b17023SJohn Marino 	  _M_rep()->_M_set_length_and_sharable(__len);
337*e4b17023SJohn Marino 	}
338*e4b17023SJohn Marino       return *this;
339*e4b17023SJohn Marino     }
340*e4b17023SJohn Marino 
341*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
342*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>&
343*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
append(const basic_string & __str,size_type __pos,size_type __n)344*e4b17023SJohn Marino     append(const basic_string& __str, size_type __pos, size_type __n)
345*e4b17023SJohn Marino     {
346*e4b17023SJohn Marino       __str._M_check(__pos, "basic_string::append");
347*e4b17023SJohn Marino       __n = __str._M_limit(__pos, __n);
348*e4b17023SJohn Marino       if (__n)
349*e4b17023SJohn Marino 	{
350*e4b17023SJohn Marino 	  const size_type __len = __n + this->size();
351*e4b17023SJohn Marino 	  if (__len > this->capacity() || _M_rep()->_M_is_shared())
352*e4b17023SJohn Marino 	    this->reserve(__len);
353*e4b17023SJohn Marino 	  _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n);
354*e4b17023SJohn Marino 	  _M_rep()->_M_set_length_and_sharable(__len);
355*e4b17023SJohn Marino 	}
356*e4b17023SJohn Marino       return *this;
357*e4b17023SJohn Marino     }
358*e4b17023SJohn Marino 
359*e4b17023SJohn Marino    template<typename _CharT, typename _Traits, typename _Alloc>
360*e4b17023SJohn Marino      basic_string<_CharT, _Traits, _Alloc>&
361*e4b17023SJohn Marino      basic_string<_CharT, _Traits, _Alloc>::
insert(size_type __pos,const _CharT * __s,size_type __n)362*e4b17023SJohn Marino      insert(size_type __pos, const _CharT* __s, size_type __n)
363*e4b17023SJohn Marino      {
364*e4b17023SJohn Marino        __glibcxx_requires_string_len(__s, __n);
365*e4b17023SJohn Marino        _M_check(__pos, "basic_string::insert");
366*e4b17023SJohn Marino        _M_check_length(size_type(0), __n, "basic_string::insert");
367*e4b17023SJohn Marino        if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
368*e4b17023SJohn Marino          return _M_replace_safe(__pos, size_type(0), __s, __n);
369*e4b17023SJohn Marino        else
370*e4b17023SJohn Marino          {
371*e4b17023SJohn Marino            // Work in-place.
372*e4b17023SJohn Marino            const size_type __off = __s - _M_data();
373*e4b17023SJohn Marino            _M_mutate(__pos, 0, __n);
374*e4b17023SJohn Marino            __s = _M_data() + __off;
375*e4b17023SJohn Marino            _CharT* __p = _M_data() + __pos;
376*e4b17023SJohn Marino            if (__s  + __n <= __p)
377*e4b17023SJohn Marino              _M_copy(__p, __s, __n);
378*e4b17023SJohn Marino            else if (__s >= __p)
379*e4b17023SJohn Marino              _M_copy(__p, __s + __n, __n);
380*e4b17023SJohn Marino            else
381*e4b17023SJohn Marino              {
382*e4b17023SJohn Marino 	       const size_type __nleft = __p - __s;
383*e4b17023SJohn Marino                _M_copy(__p, __s, __nleft);
384*e4b17023SJohn Marino                _M_copy(__p + __nleft, __p + __n, __n - __nleft);
385*e4b17023SJohn Marino              }
386*e4b17023SJohn Marino            return *this;
387*e4b17023SJohn Marino          }
388*e4b17023SJohn Marino      }
389*e4b17023SJohn Marino 
390*e4b17023SJohn Marino    template<typename _CharT, typename _Traits, typename _Alloc>
391*e4b17023SJohn Marino      typename basic_string<_CharT, _Traits, _Alloc>::iterator
392*e4b17023SJohn Marino      basic_string<_CharT, _Traits, _Alloc>::
erase(iterator __first,iterator __last)393*e4b17023SJohn Marino      erase(iterator __first, iterator __last)
394*e4b17023SJohn Marino      {
395*e4b17023SJohn Marino        _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
396*e4b17023SJohn Marino 				&& __last <= _M_iend());
397*e4b17023SJohn Marino 
398*e4b17023SJohn Marino        // NB: This isn't just an optimization (bail out early when
399*e4b17023SJohn Marino        // there is nothing to do, really), it's also a correctness
400*e4b17023SJohn Marino        // issue vs MT, see libstdc++/40518.
401*e4b17023SJohn Marino        const size_type __size = __last - __first;
402*e4b17023SJohn Marino        if (__size)
403*e4b17023SJohn Marino 	 {
404*e4b17023SJohn Marino 	   const size_type __pos = __first - _M_ibegin();
405*e4b17023SJohn Marino 	   _M_mutate(__pos, __size, size_type(0));
406*e4b17023SJohn Marino 	   _M_rep()->_M_set_leaked();
407*e4b17023SJohn Marino 	   return iterator(_M_data() + __pos);
408*e4b17023SJohn Marino 	 }
409*e4b17023SJohn Marino        else
410*e4b17023SJohn Marino 	 return __first;
411*e4b17023SJohn Marino      }
412*e4b17023SJohn Marino 
413*e4b17023SJohn Marino    template<typename _CharT, typename _Traits, typename _Alloc>
414*e4b17023SJohn Marino      basic_string<_CharT, _Traits, _Alloc>&
415*e4b17023SJohn Marino      basic_string<_CharT, _Traits, _Alloc>::
replace(size_type __pos,size_type __n1,const _CharT * __s,size_type __n2)416*e4b17023SJohn Marino      replace(size_type __pos, size_type __n1, const _CharT* __s,
417*e4b17023SJohn Marino 	     size_type __n2)
418*e4b17023SJohn Marino      {
419*e4b17023SJohn Marino        __glibcxx_requires_string_len(__s, __n2);
420*e4b17023SJohn Marino        _M_check(__pos, "basic_string::replace");
421*e4b17023SJohn Marino        __n1 = _M_limit(__pos, __n1);
422*e4b17023SJohn Marino        _M_check_length(__n1, __n2, "basic_string::replace");
423*e4b17023SJohn Marino        bool __left;
424*e4b17023SJohn Marino        if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
425*e4b17023SJohn Marino          return _M_replace_safe(__pos, __n1, __s, __n2);
426*e4b17023SJohn Marino        else if ((__left = __s + __n2 <= _M_data() + __pos)
427*e4b17023SJohn Marino 		|| _M_data() + __pos + __n1 <= __s)
428*e4b17023SJohn Marino 	 {
429*e4b17023SJohn Marino 	   // Work in-place: non-overlapping case.
430*e4b17023SJohn Marino 	   size_type __off = __s - _M_data();
431*e4b17023SJohn Marino 	   __left ? __off : (__off += __n2 - __n1);
432*e4b17023SJohn Marino 	   _M_mutate(__pos, __n1, __n2);
433*e4b17023SJohn Marino 	   _M_copy(_M_data() + __pos, _M_data() + __off, __n2);
434*e4b17023SJohn Marino 	   return *this;
435*e4b17023SJohn Marino 	 }
436*e4b17023SJohn Marino        else
437*e4b17023SJohn Marino 	 {
438*e4b17023SJohn Marino 	   // Todo: overlapping case.
439*e4b17023SJohn Marino 	   const basic_string __tmp(__s, __n2);
440*e4b17023SJohn Marino 	   return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
441*e4b17023SJohn Marino 	 }
442*e4b17023SJohn Marino      }
443*e4b17023SJohn Marino 
444*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
445*e4b17023SJohn Marino     void
446*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::_Rep::
_M_destroy(const _Alloc & __a)447*e4b17023SJohn Marino     _M_destroy(const _Alloc& __a) throw ()
448*e4b17023SJohn Marino     {
449*e4b17023SJohn Marino       const size_type __size = sizeof(_Rep_base) +
450*e4b17023SJohn Marino 	                       (this->_M_capacity + 1) * sizeof(_CharT);
451*e4b17023SJohn Marino       _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);
452*e4b17023SJohn Marino     }
453*e4b17023SJohn Marino 
454*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
455*e4b17023SJohn Marino     void
456*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
_M_leak_hard()457*e4b17023SJohn Marino     _M_leak_hard()
458*e4b17023SJohn Marino     {
459*e4b17023SJohn Marino #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
460*e4b17023SJohn Marino       if (_M_rep() == &_S_empty_rep())
461*e4b17023SJohn Marino 	return;
462*e4b17023SJohn Marino #endif
463*e4b17023SJohn Marino       if (_M_rep()->_M_is_shared())
464*e4b17023SJohn Marino 	_M_mutate(0, 0, 0);
465*e4b17023SJohn Marino       _M_rep()->_M_set_leaked();
466*e4b17023SJohn Marino     }
467*e4b17023SJohn Marino 
468*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
469*e4b17023SJohn Marino     void
470*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
_M_mutate(size_type __pos,size_type __len1,size_type __len2)471*e4b17023SJohn Marino     _M_mutate(size_type __pos, size_type __len1, size_type __len2)
472*e4b17023SJohn Marino     {
473*e4b17023SJohn Marino       const size_type __old_size = this->size();
474*e4b17023SJohn Marino       const size_type __new_size = __old_size + __len2 - __len1;
475*e4b17023SJohn Marino       const size_type __how_much = __old_size - __pos - __len1;
476*e4b17023SJohn Marino 
477*e4b17023SJohn Marino       if (__new_size > this->capacity() || _M_rep()->_M_is_shared())
478*e4b17023SJohn Marino 	{
479*e4b17023SJohn Marino 	  // Must reallocate.
480*e4b17023SJohn Marino 	  const allocator_type __a = get_allocator();
481*e4b17023SJohn Marino 	  _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a);
482*e4b17023SJohn Marino 
483*e4b17023SJohn Marino 	  if (__pos)
484*e4b17023SJohn Marino 	    _M_copy(__r->_M_refdata(), _M_data(), __pos);
485*e4b17023SJohn Marino 	  if (__how_much)
486*e4b17023SJohn Marino 	    _M_copy(__r->_M_refdata() + __pos + __len2,
487*e4b17023SJohn Marino 		    _M_data() + __pos + __len1, __how_much);
488*e4b17023SJohn Marino 
489*e4b17023SJohn Marino 	  _M_rep()->_M_dispose(__a);
490*e4b17023SJohn Marino 	  _M_data(__r->_M_refdata());
491*e4b17023SJohn Marino 	}
492*e4b17023SJohn Marino       else if (__how_much && __len1 != __len2)
493*e4b17023SJohn Marino 	{
494*e4b17023SJohn Marino 	  // Work in-place.
495*e4b17023SJohn Marino 	  _M_move(_M_data() + __pos + __len2,
496*e4b17023SJohn Marino 		  _M_data() + __pos + __len1, __how_much);
497*e4b17023SJohn Marino 	}
498*e4b17023SJohn Marino       _M_rep()->_M_set_length_and_sharable(__new_size);
499*e4b17023SJohn Marino     }
500*e4b17023SJohn Marino 
501*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
502*e4b17023SJohn Marino     void
503*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
reserve(size_type __res)504*e4b17023SJohn Marino     reserve(size_type __res)
505*e4b17023SJohn Marino     {
506*e4b17023SJohn Marino       if (__res != this->capacity() || _M_rep()->_M_is_shared())
507*e4b17023SJohn Marino         {
508*e4b17023SJohn Marino 	  // Make sure we don't shrink below the current size
509*e4b17023SJohn Marino 	  if (__res < this->size())
510*e4b17023SJohn Marino 	    __res = this->size();
511*e4b17023SJohn Marino 	  const allocator_type __a = get_allocator();
512*e4b17023SJohn Marino 	  _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size());
513*e4b17023SJohn Marino 	  _M_rep()->_M_dispose(__a);
514*e4b17023SJohn Marino 	  _M_data(__tmp);
515*e4b17023SJohn Marino         }
516*e4b17023SJohn Marino     }
517*e4b17023SJohn Marino 
518*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
519*e4b17023SJohn Marino     void
520*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
swap(basic_string & __s)521*e4b17023SJohn Marino     swap(basic_string& __s)
522*e4b17023SJohn Marino     {
523*e4b17023SJohn Marino       if (_M_rep()->_M_is_leaked())
524*e4b17023SJohn Marino 	_M_rep()->_M_set_sharable();
525*e4b17023SJohn Marino       if (__s._M_rep()->_M_is_leaked())
526*e4b17023SJohn Marino 	__s._M_rep()->_M_set_sharable();
527*e4b17023SJohn Marino       if (this->get_allocator() == __s.get_allocator())
528*e4b17023SJohn Marino 	{
529*e4b17023SJohn Marino 	  _CharT* __tmp = _M_data();
530*e4b17023SJohn Marino 	  _M_data(__s._M_data());
531*e4b17023SJohn Marino 	  __s._M_data(__tmp);
532*e4b17023SJohn Marino 	}
533*e4b17023SJohn Marino       // The code below can usually be optimized away.
534*e4b17023SJohn Marino       else
535*e4b17023SJohn Marino 	{
536*e4b17023SJohn Marino 	  const basic_string __tmp1(_M_ibegin(), _M_iend(),
537*e4b17023SJohn Marino 				    __s.get_allocator());
538*e4b17023SJohn Marino 	  const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(),
539*e4b17023SJohn Marino 				    this->get_allocator());
540*e4b17023SJohn Marino 	  *this = __tmp2;
541*e4b17023SJohn Marino 	  __s = __tmp1;
542*e4b17023SJohn Marino 	}
543*e4b17023SJohn Marino     }
544*e4b17023SJohn Marino 
545*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
546*e4b17023SJohn Marino     typename basic_string<_CharT, _Traits, _Alloc>::_Rep*
547*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::_Rep::
_S_create(size_type __capacity,size_type __old_capacity,const _Alloc & __alloc)548*e4b17023SJohn Marino     _S_create(size_type __capacity, size_type __old_capacity,
549*e4b17023SJohn Marino 	      const _Alloc& __alloc)
550*e4b17023SJohn Marino     {
551*e4b17023SJohn Marino       // _GLIBCXX_RESOLVE_LIB_DEFECTS
552*e4b17023SJohn Marino       // 83.  String::npos vs. string::max_size()
553*e4b17023SJohn Marino       if (__capacity > _S_max_size)
554*e4b17023SJohn Marino 	__throw_length_error(__N("basic_string::_S_create"));
555*e4b17023SJohn Marino 
556*e4b17023SJohn Marino       // The standard places no restriction on allocating more memory
557*e4b17023SJohn Marino       // than is strictly needed within this layer at the moment or as
558*e4b17023SJohn Marino       // requested by an explicit application call to reserve().
559*e4b17023SJohn Marino 
560*e4b17023SJohn Marino       // Many malloc implementations perform quite poorly when an
561*e4b17023SJohn Marino       // application attempts to allocate memory in a stepwise fashion
562*e4b17023SJohn Marino       // growing each allocation size by only 1 char.  Additionally,
563*e4b17023SJohn Marino       // it makes little sense to allocate less linear memory than the
564*e4b17023SJohn Marino       // natural blocking size of the malloc implementation.
565*e4b17023SJohn Marino       // Unfortunately, we would need a somewhat low-level calculation
566*e4b17023SJohn Marino       // with tuned parameters to get this perfect for any particular
567*e4b17023SJohn Marino       // malloc implementation.  Fortunately, generalizations about
568*e4b17023SJohn Marino       // common features seen among implementations seems to suffice.
569*e4b17023SJohn Marino 
570*e4b17023SJohn Marino       // __pagesize need not match the actual VM page size for good
571*e4b17023SJohn Marino       // results in practice, thus we pick a common value on the low
572*e4b17023SJohn Marino       // side.  __malloc_header_size is an estimate of the amount of
573*e4b17023SJohn Marino       // overhead per memory allocation (in practice seen N * sizeof
574*e4b17023SJohn Marino       // (void*) where N is 0, 2 or 4).  According to folklore,
575*e4b17023SJohn Marino       // picking this value on the high side is better than
576*e4b17023SJohn Marino       // low-balling it (especially when this algorithm is used with
577*e4b17023SJohn Marino       // malloc implementations that allocate memory blocks rounded up
578*e4b17023SJohn Marino       // to a size which is a power of 2).
579*e4b17023SJohn Marino       const size_type __pagesize = 4096;
580*e4b17023SJohn Marino       const size_type __malloc_header_size = 4 * sizeof(void*);
581*e4b17023SJohn Marino 
582*e4b17023SJohn Marino       // The below implements an exponential growth policy, necessary to
583*e4b17023SJohn Marino       // meet amortized linear time requirements of the library: see
584*e4b17023SJohn Marino       // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
585*e4b17023SJohn Marino       // It's active for allocations requiring an amount of memory above
586*e4b17023SJohn Marino       // system pagesize. This is consistent with the requirements of the
587*e4b17023SJohn Marino       // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html
588*e4b17023SJohn Marino       if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
589*e4b17023SJohn Marino 	__capacity = 2 * __old_capacity;
590*e4b17023SJohn Marino 
591*e4b17023SJohn Marino       // NB: Need an array of char_type[__capacity], plus a terminating
592*e4b17023SJohn Marino       // null char_type() element, plus enough for the _Rep data structure.
593*e4b17023SJohn Marino       // Whew. Seemingly so needy, yet so elemental.
594*e4b17023SJohn Marino       size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
595*e4b17023SJohn Marino 
596*e4b17023SJohn Marino       const size_type __adj_size = __size + __malloc_header_size;
597*e4b17023SJohn Marino       if (__adj_size > __pagesize && __capacity > __old_capacity)
598*e4b17023SJohn Marino 	{
599*e4b17023SJohn Marino 	  const size_type __extra = __pagesize - __adj_size % __pagesize;
600*e4b17023SJohn Marino 	  __capacity += __extra / sizeof(_CharT);
601*e4b17023SJohn Marino 	  // Never allocate a string bigger than _S_max_size.
602*e4b17023SJohn Marino 	  if (__capacity > _S_max_size)
603*e4b17023SJohn Marino 	    __capacity = _S_max_size;
604*e4b17023SJohn Marino 	  __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
605*e4b17023SJohn Marino 	}
606*e4b17023SJohn Marino 
607*e4b17023SJohn Marino       // NB: Might throw, but no worries about a leak, mate: _Rep()
608*e4b17023SJohn Marino       // does not throw.
609*e4b17023SJohn Marino       void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
610*e4b17023SJohn Marino       _Rep *__p = new (__place) _Rep;
611*e4b17023SJohn Marino       __p->_M_capacity = __capacity;
612*e4b17023SJohn Marino       // ABI compatibility - 3.4.x set in _S_create both
613*e4b17023SJohn Marino       // _M_refcount and _M_length.  All callers of _S_create
614*e4b17023SJohn Marino       // in basic_string.tcc then set just _M_length.
615*e4b17023SJohn Marino       // In 4.0.x and later both _M_refcount and _M_length
616*e4b17023SJohn Marino       // are initialized in the callers, unfortunately we can
617*e4b17023SJohn Marino       // have 3.4.x compiled code with _S_create callers inlined
618*e4b17023SJohn Marino       // calling 4.0.x+ _S_create.
619*e4b17023SJohn Marino       __p->_M_set_sharable();
620*e4b17023SJohn Marino       return __p;
621*e4b17023SJohn Marino     }
622*e4b17023SJohn Marino 
623*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
624*e4b17023SJohn Marino     _CharT*
625*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::_Rep::
_M_clone(const _Alloc & __alloc,size_type __res)626*e4b17023SJohn Marino     _M_clone(const _Alloc& __alloc, size_type __res)
627*e4b17023SJohn Marino     {
628*e4b17023SJohn Marino       // Requested capacity of the clone.
629*e4b17023SJohn Marino       const size_type __requested_cap = this->_M_length + __res;
630*e4b17023SJohn Marino       _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity,
631*e4b17023SJohn Marino 				  __alloc);
632*e4b17023SJohn Marino       if (this->_M_length)
633*e4b17023SJohn Marino 	_M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length);
634*e4b17023SJohn Marino 
635*e4b17023SJohn Marino       __r->_M_set_length_and_sharable(this->_M_length);
636*e4b17023SJohn Marino       return __r->_M_refdata();
637*e4b17023SJohn Marino     }
638*e4b17023SJohn Marino 
639*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
640*e4b17023SJohn Marino     void
641*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
resize(size_type __n,_CharT __c)642*e4b17023SJohn Marino     resize(size_type __n, _CharT __c)
643*e4b17023SJohn Marino     {
644*e4b17023SJohn Marino       const size_type __size = this->size();
645*e4b17023SJohn Marino       _M_check_length(__size, __n, "basic_string::resize");
646*e4b17023SJohn Marino       if (__size < __n)
647*e4b17023SJohn Marino 	this->append(__n - __size, __c);
648*e4b17023SJohn Marino       else if (__n < __size)
649*e4b17023SJohn Marino 	this->erase(__n);
650*e4b17023SJohn Marino       // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
651*e4b17023SJohn Marino     }
652*e4b17023SJohn Marino 
653*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
654*e4b17023SJohn Marino     template<typename _InputIterator>
655*e4b17023SJohn Marino       basic_string<_CharT, _Traits, _Alloc>&
656*e4b17023SJohn Marino       basic_string<_CharT, _Traits, _Alloc>::
_M_replace_dispatch(iterator __i1,iterator __i2,_InputIterator __k1,_InputIterator __k2,__false_type)657*e4b17023SJohn Marino       _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
658*e4b17023SJohn Marino 			  _InputIterator __k2, __false_type)
659*e4b17023SJohn Marino       {
660*e4b17023SJohn Marino 	const basic_string __s(__k1, __k2);
661*e4b17023SJohn Marino 	const size_type __n1 = __i2 - __i1;
662*e4b17023SJohn Marino 	_M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch");
663*e4b17023SJohn Marino 	return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(),
664*e4b17023SJohn Marino 			       __s.size());
665*e4b17023SJohn Marino       }
666*e4b17023SJohn Marino 
667*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
668*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>&
669*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
_M_replace_aux(size_type __pos1,size_type __n1,size_type __n2,_CharT __c)670*e4b17023SJohn Marino     _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
671*e4b17023SJohn Marino 		   _CharT __c)
672*e4b17023SJohn Marino     {
673*e4b17023SJohn Marino       _M_check_length(__n1, __n2, "basic_string::_M_replace_aux");
674*e4b17023SJohn Marino       _M_mutate(__pos1, __n1, __n2);
675*e4b17023SJohn Marino       if (__n2)
676*e4b17023SJohn Marino 	_M_assign(_M_data() + __pos1, __n2, __c);
677*e4b17023SJohn Marino       return *this;
678*e4b17023SJohn Marino     }
679*e4b17023SJohn Marino 
680*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
681*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>&
682*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
_M_replace_safe(size_type __pos1,size_type __n1,const _CharT * __s,size_type __n2)683*e4b17023SJohn Marino     _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
684*e4b17023SJohn Marino 		    size_type __n2)
685*e4b17023SJohn Marino     {
686*e4b17023SJohn Marino       _M_mutate(__pos1, __n1, __n2);
687*e4b17023SJohn Marino       if (__n2)
688*e4b17023SJohn Marino 	_M_copy(_M_data() + __pos1, __s, __n2);
689*e4b17023SJohn Marino       return *this;
690*e4b17023SJohn Marino     }
691*e4b17023SJohn Marino 
692*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
693*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>
operator +(const _CharT * __lhs,const basic_string<_CharT,_Traits,_Alloc> & __rhs)694*e4b17023SJohn Marino     operator+(const _CharT* __lhs,
695*e4b17023SJohn Marino 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)
696*e4b17023SJohn Marino     {
697*e4b17023SJohn Marino       __glibcxx_requires_string(__lhs);
698*e4b17023SJohn Marino       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
699*e4b17023SJohn Marino       typedef typename __string_type::size_type	  __size_type;
700*e4b17023SJohn Marino       const __size_type __len = _Traits::length(__lhs);
701*e4b17023SJohn Marino       __string_type __str;
702*e4b17023SJohn Marino       __str.reserve(__len + __rhs.size());
703*e4b17023SJohn Marino       __str.append(__lhs, __len);
704*e4b17023SJohn Marino       __str.append(__rhs);
705*e4b17023SJohn Marino       return __str;
706*e4b17023SJohn Marino     }
707*e4b17023SJohn Marino 
708*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
709*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>
operator +(_CharT __lhs,const basic_string<_CharT,_Traits,_Alloc> & __rhs)710*e4b17023SJohn Marino     operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs)
711*e4b17023SJohn Marino     {
712*e4b17023SJohn Marino       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
713*e4b17023SJohn Marino       typedef typename __string_type::size_type	  __size_type;
714*e4b17023SJohn Marino       __string_type __str;
715*e4b17023SJohn Marino       const __size_type __len = __rhs.size();
716*e4b17023SJohn Marino       __str.reserve(__len + 1);
717*e4b17023SJohn Marino       __str.append(__size_type(1), __lhs);
718*e4b17023SJohn Marino       __str.append(__rhs);
719*e4b17023SJohn Marino       return __str;
720*e4b17023SJohn Marino     }
721*e4b17023SJohn Marino 
722*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
723*e4b17023SJohn Marino     typename basic_string<_CharT, _Traits, _Alloc>::size_type
724*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
copy(_CharT * __s,size_type __n,size_type __pos) const725*e4b17023SJohn Marino     copy(_CharT* __s, size_type __n, size_type __pos) const
726*e4b17023SJohn Marino     {
727*e4b17023SJohn Marino       _M_check(__pos, "basic_string::copy");
728*e4b17023SJohn Marino       __n = _M_limit(__pos, __n);
729*e4b17023SJohn Marino       __glibcxx_requires_string_len(__s, __n);
730*e4b17023SJohn Marino       if (__n)
731*e4b17023SJohn Marino 	_M_copy(__s, _M_data() + __pos, __n);
732*e4b17023SJohn Marino       // 21.3.5.7 par 3: do not append null.  (good.)
733*e4b17023SJohn Marino       return __n;
734*e4b17023SJohn Marino     }
735*e4b17023SJohn Marino 
736*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
737*e4b17023SJohn Marino     typename basic_string<_CharT, _Traits, _Alloc>::size_type
738*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
find(const _CharT * __s,size_type __pos,size_type __n) const739*e4b17023SJohn Marino     find(const _CharT* __s, size_type __pos, size_type __n) const
740*e4b17023SJohn Marino     {
741*e4b17023SJohn Marino       __glibcxx_requires_string_len(__s, __n);
742*e4b17023SJohn Marino       const size_type __size = this->size();
743*e4b17023SJohn Marino       const _CharT* __data = _M_data();
744*e4b17023SJohn Marino 
745*e4b17023SJohn Marino       if (__n == 0)
746*e4b17023SJohn Marino 	return __pos <= __size ? __pos : npos;
747*e4b17023SJohn Marino 
748*e4b17023SJohn Marino       if (__n <= __size)
749*e4b17023SJohn Marino 	{
750*e4b17023SJohn Marino 	  for (; __pos <= __size - __n; ++__pos)
751*e4b17023SJohn Marino 	    if (traits_type::eq(__data[__pos], __s[0])
752*e4b17023SJohn Marino 		&& traits_type::compare(__data + __pos + 1,
753*e4b17023SJohn Marino 					__s + 1, __n - 1) == 0)
754*e4b17023SJohn Marino 	      return __pos;
755*e4b17023SJohn Marino 	}
756*e4b17023SJohn Marino       return npos;
757*e4b17023SJohn Marino     }
758*e4b17023SJohn Marino 
759*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
760*e4b17023SJohn Marino     typename basic_string<_CharT, _Traits, _Alloc>::size_type
761*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
find(_CharT __c,size_type __pos) const762*e4b17023SJohn Marino     find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
763*e4b17023SJohn Marino     {
764*e4b17023SJohn Marino       size_type __ret = npos;
765*e4b17023SJohn Marino       const size_type __size = this->size();
766*e4b17023SJohn Marino       if (__pos < __size)
767*e4b17023SJohn Marino 	{
768*e4b17023SJohn Marino 	  const _CharT* __data = _M_data();
769*e4b17023SJohn Marino 	  const size_type __n = __size - __pos;
770*e4b17023SJohn Marino 	  const _CharT* __p = traits_type::find(__data + __pos, __n, __c);
771*e4b17023SJohn Marino 	  if (__p)
772*e4b17023SJohn Marino 	    __ret = __p - __data;
773*e4b17023SJohn Marino 	}
774*e4b17023SJohn Marino       return __ret;
775*e4b17023SJohn Marino     }
776*e4b17023SJohn Marino 
777*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
778*e4b17023SJohn Marino     typename basic_string<_CharT, _Traits, _Alloc>::size_type
779*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
rfind(const _CharT * __s,size_type __pos,size_type __n) const780*e4b17023SJohn Marino     rfind(const _CharT* __s, size_type __pos, size_type __n) const
781*e4b17023SJohn Marino     {
782*e4b17023SJohn Marino       __glibcxx_requires_string_len(__s, __n);
783*e4b17023SJohn Marino       const size_type __size = this->size();
784*e4b17023SJohn Marino       if (__n <= __size)
785*e4b17023SJohn Marino 	{
786*e4b17023SJohn Marino 	  __pos = std::min(size_type(__size - __n), __pos);
787*e4b17023SJohn Marino 	  const _CharT* __data = _M_data();
788*e4b17023SJohn Marino 	  do
789*e4b17023SJohn Marino 	    {
790*e4b17023SJohn Marino 	      if (traits_type::compare(__data + __pos, __s, __n) == 0)
791*e4b17023SJohn Marino 		return __pos;
792*e4b17023SJohn Marino 	    }
793*e4b17023SJohn Marino 	  while (__pos-- > 0);
794*e4b17023SJohn Marino 	}
795*e4b17023SJohn Marino       return npos;
796*e4b17023SJohn Marino     }
797*e4b17023SJohn Marino 
798*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
799*e4b17023SJohn Marino     typename basic_string<_CharT, _Traits, _Alloc>::size_type
800*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
rfind(_CharT __c,size_type __pos) const801*e4b17023SJohn Marino     rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
802*e4b17023SJohn Marino     {
803*e4b17023SJohn Marino       size_type __size = this->size();
804*e4b17023SJohn Marino       if (__size)
805*e4b17023SJohn Marino 	{
806*e4b17023SJohn Marino 	  if (--__size > __pos)
807*e4b17023SJohn Marino 	    __size = __pos;
808*e4b17023SJohn Marino 	  for (++__size; __size-- > 0; )
809*e4b17023SJohn Marino 	    if (traits_type::eq(_M_data()[__size], __c))
810*e4b17023SJohn Marino 	      return __size;
811*e4b17023SJohn Marino 	}
812*e4b17023SJohn Marino       return npos;
813*e4b17023SJohn Marino     }
814*e4b17023SJohn Marino 
815*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
816*e4b17023SJohn Marino     typename basic_string<_CharT, _Traits, _Alloc>::size_type
817*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
find_first_of(const _CharT * __s,size_type __pos,size_type __n) const818*e4b17023SJohn Marino     find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
819*e4b17023SJohn Marino     {
820*e4b17023SJohn Marino       __glibcxx_requires_string_len(__s, __n);
821*e4b17023SJohn Marino       for (; __n && __pos < this->size(); ++__pos)
822*e4b17023SJohn Marino 	{
823*e4b17023SJohn Marino 	  const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]);
824*e4b17023SJohn Marino 	  if (__p)
825*e4b17023SJohn Marino 	    return __pos;
826*e4b17023SJohn Marino 	}
827*e4b17023SJohn Marino       return npos;
828*e4b17023SJohn Marino     }
829*e4b17023SJohn Marino 
830*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
831*e4b17023SJohn Marino     typename basic_string<_CharT, _Traits, _Alloc>::size_type
832*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
find_last_of(const _CharT * __s,size_type __pos,size_type __n) const833*e4b17023SJohn Marino     find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
834*e4b17023SJohn Marino     {
835*e4b17023SJohn Marino       __glibcxx_requires_string_len(__s, __n);
836*e4b17023SJohn Marino       size_type __size = this->size();
837*e4b17023SJohn Marino       if (__size && __n)
838*e4b17023SJohn Marino 	{
839*e4b17023SJohn Marino 	  if (--__size > __pos)
840*e4b17023SJohn Marino 	    __size = __pos;
841*e4b17023SJohn Marino 	  do
842*e4b17023SJohn Marino 	    {
843*e4b17023SJohn Marino 	      if (traits_type::find(__s, __n, _M_data()[__size]))
844*e4b17023SJohn Marino 		return __size;
845*e4b17023SJohn Marino 	    }
846*e4b17023SJohn Marino 	  while (__size-- != 0);
847*e4b17023SJohn Marino 	}
848*e4b17023SJohn Marino       return npos;
849*e4b17023SJohn Marino     }
850*e4b17023SJohn Marino 
851*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
852*e4b17023SJohn Marino     typename basic_string<_CharT, _Traits, _Alloc>::size_type
853*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
find_first_not_of(const _CharT * __s,size_type __pos,size_type __n) const854*e4b17023SJohn Marino     find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
855*e4b17023SJohn Marino     {
856*e4b17023SJohn Marino       __glibcxx_requires_string_len(__s, __n);
857*e4b17023SJohn Marino       for (; __pos < this->size(); ++__pos)
858*e4b17023SJohn Marino 	if (!traits_type::find(__s, __n, _M_data()[__pos]))
859*e4b17023SJohn Marino 	  return __pos;
860*e4b17023SJohn Marino       return npos;
861*e4b17023SJohn Marino     }
862*e4b17023SJohn Marino 
863*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
864*e4b17023SJohn Marino     typename basic_string<_CharT, _Traits, _Alloc>::size_type
865*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
find_first_not_of(_CharT __c,size_type __pos) const866*e4b17023SJohn Marino     find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
867*e4b17023SJohn Marino     {
868*e4b17023SJohn Marino       for (; __pos < this->size(); ++__pos)
869*e4b17023SJohn Marino 	if (!traits_type::eq(_M_data()[__pos], __c))
870*e4b17023SJohn Marino 	  return __pos;
871*e4b17023SJohn Marino       return npos;
872*e4b17023SJohn Marino     }
873*e4b17023SJohn Marino 
874*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
875*e4b17023SJohn Marino     typename basic_string<_CharT, _Traits, _Alloc>::size_type
876*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
find_last_not_of(const _CharT * __s,size_type __pos,size_type __n) const877*e4b17023SJohn Marino     find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
878*e4b17023SJohn Marino     {
879*e4b17023SJohn Marino       __glibcxx_requires_string_len(__s, __n);
880*e4b17023SJohn Marino       size_type __size = this->size();
881*e4b17023SJohn Marino       if (__size)
882*e4b17023SJohn Marino 	{
883*e4b17023SJohn Marino 	  if (--__size > __pos)
884*e4b17023SJohn Marino 	    __size = __pos;
885*e4b17023SJohn Marino 	  do
886*e4b17023SJohn Marino 	    {
887*e4b17023SJohn Marino 	      if (!traits_type::find(__s, __n, _M_data()[__size]))
888*e4b17023SJohn Marino 		return __size;
889*e4b17023SJohn Marino 	    }
890*e4b17023SJohn Marino 	  while (__size--);
891*e4b17023SJohn Marino 	}
892*e4b17023SJohn Marino       return npos;
893*e4b17023SJohn Marino     }
894*e4b17023SJohn Marino 
895*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
896*e4b17023SJohn Marino     typename basic_string<_CharT, _Traits, _Alloc>::size_type
897*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
find_last_not_of(_CharT __c,size_type __pos) const898*e4b17023SJohn Marino     find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT
899*e4b17023SJohn Marino     {
900*e4b17023SJohn Marino       size_type __size = this->size();
901*e4b17023SJohn Marino       if (__size)
902*e4b17023SJohn Marino 	{
903*e4b17023SJohn Marino 	  if (--__size > __pos)
904*e4b17023SJohn Marino 	    __size = __pos;
905*e4b17023SJohn Marino 	  do
906*e4b17023SJohn Marino 	    {
907*e4b17023SJohn Marino 	      if (!traits_type::eq(_M_data()[__size], __c))
908*e4b17023SJohn Marino 		return __size;
909*e4b17023SJohn Marino 	    }
910*e4b17023SJohn Marino 	  while (__size--);
911*e4b17023SJohn Marino 	}
912*e4b17023SJohn Marino       return npos;
913*e4b17023SJohn Marino     }
914*e4b17023SJohn Marino 
915*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
916*e4b17023SJohn Marino     int
917*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
compare(size_type __pos,size_type __n,const basic_string & __str) const918*e4b17023SJohn Marino     compare(size_type __pos, size_type __n, const basic_string& __str) const
919*e4b17023SJohn Marino     {
920*e4b17023SJohn Marino       _M_check(__pos, "basic_string::compare");
921*e4b17023SJohn Marino       __n = _M_limit(__pos, __n);
922*e4b17023SJohn Marino       const size_type __osize = __str.size();
923*e4b17023SJohn Marino       const size_type __len = std::min(__n, __osize);
924*e4b17023SJohn Marino       int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
925*e4b17023SJohn Marino       if (!__r)
926*e4b17023SJohn Marino 	__r = _S_compare(__n, __osize);
927*e4b17023SJohn Marino       return __r;
928*e4b17023SJohn Marino     }
929*e4b17023SJohn Marino 
930*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
931*e4b17023SJohn Marino     int
932*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
compare(size_type __pos1,size_type __n1,const basic_string & __str,size_type __pos2,size_type __n2) const933*e4b17023SJohn Marino     compare(size_type __pos1, size_type __n1, const basic_string& __str,
934*e4b17023SJohn Marino 	    size_type __pos2, size_type __n2) const
935*e4b17023SJohn Marino     {
936*e4b17023SJohn Marino       _M_check(__pos1, "basic_string::compare");
937*e4b17023SJohn Marino       __str._M_check(__pos2, "basic_string::compare");
938*e4b17023SJohn Marino       __n1 = _M_limit(__pos1, __n1);
939*e4b17023SJohn Marino       __n2 = __str._M_limit(__pos2, __n2);
940*e4b17023SJohn Marino       const size_type __len = std::min(__n1, __n2);
941*e4b17023SJohn Marino       int __r = traits_type::compare(_M_data() + __pos1,
942*e4b17023SJohn Marino 				     __str.data() + __pos2, __len);
943*e4b17023SJohn Marino       if (!__r)
944*e4b17023SJohn Marino 	__r = _S_compare(__n1, __n2);
945*e4b17023SJohn Marino       return __r;
946*e4b17023SJohn Marino     }
947*e4b17023SJohn Marino 
948*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
949*e4b17023SJohn Marino     int
950*e4b17023SJohn Marino     basic_string<_CharT, _Traits, _Alloc>::
compare(const _CharT * __s) const951*e4b17023SJohn Marino     compare(const _CharT* __s) const
952*e4b17023SJohn Marino     {
953*e4b17023SJohn Marino       __glibcxx_requires_string(__s);
954*e4b17023SJohn Marino       const size_type __size = this->size();
955*e4b17023SJohn Marino       const size_type __osize = traits_type::length(__s);
956*e4b17023SJohn Marino       const size_type __len = std::min(__size, __osize);
957*e4b17023SJohn Marino       int __r = traits_type::compare(_M_data(), __s, __len);
958*e4b17023SJohn Marino       if (!__r)
959*e4b17023SJohn Marino 	__r = _S_compare(__size, __osize);
960*e4b17023SJohn Marino       return __r;
961*e4b17023SJohn Marino     }
962*e4b17023SJohn Marino 
963*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
964*e4b17023SJohn Marino     int
965*e4b17023SJohn Marino     basic_string <_CharT, _Traits, _Alloc>::
compare(size_type __pos,size_type __n1,const _CharT * __s) const966*e4b17023SJohn Marino     compare(size_type __pos, size_type __n1, const _CharT* __s) const
967*e4b17023SJohn Marino     {
968*e4b17023SJohn Marino       __glibcxx_requires_string(__s);
969*e4b17023SJohn Marino       _M_check(__pos, "basic_string::compare");
970*e4b17023SJohn Marino       __n1 = _M_limit(__pos, __n1);
971*e4b17023SJohn Marino       const size_type __osize = traits_type::length(__s);
972*e4b17023SJohn Marino       const size_type __len = std::min(__n1, __osize);
973*e4b17023SJohn Marino       int __r = traits_type::compare(_M_data() + __pos, __s, __len);
974*e4b17023SJohn Marino       if (!__r)
975*e4b17023SJohn Marino 	__r = _S_compare(__n1, __osize);
976*e4b17023SJohn Marino       return __r;
977*e4b17023SJohn Marino     }
978*e4b17023SJohn Marino 
979*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
980*e4b17023SJohn Marino     int
981*e4b17023SJohn Marino     basic_string <_CharT, _Traits, _Alloc>::
compare(size_type __pos,size_type __n1,const _CharT * __s,size_type __n2) const982*e4b17023SJohn Marino     compare(size_type __pos, size_type __n1, const _CharT* __s,
983*e4b17023SJohn Marino 	    size_type __n2) const
984*e4b17023SJohn Marino     {
985*e4b17023SJohn Marino       __glibcxx_requires_string_len(__s, __n2);
986*e4b17023SJohn Marino       _M_check(__pos, "basic_string::compare");
987*e4b17023SJohn Marino       __n1 = _M_limit(__pos, __n1);
988*e4b17023SJohn Marino       const size_type __len = std::min(__n1, __n2);
989*e4b17023SJohn Marino       int __r = traits_type::compare(_M_data() + __pos, __s, __len);
990*e4b17023SJohn Marino       if (!__r)
991*e4b17023SJohn Marino 	__r = _S_compare(__n1, __n2);
992*e4b17023SJohn Marino       return __r;
993*e4b17023SJohn Marino     }
994*e4b17023SJohn Marino 
995*e4b17023SJohn Marino   // 21.3.7.9 basic_string::getline and operators
996*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
997*e4b17023SJohn Marino     basic_istream<_CharT, _Traits>&
operator >>(basic_istream<_CharT,_Traits> & __in,basic_string<_CharT,_Traits,_Alloc> & __str)998*e4b17023SJohn Marino     operator>>(basic_istream<_CharT, _Traits>& __in,
999*e4b17023SJohn Marino 	       basic_string<_CharT, _Traits, _Alloc>& __str)
1000*e4b17023SJohn Marino     {
1001*e4b17023SJohn Marino       typedef basic_istream<_CharT, _Traits>		__istream_type;
1002*e4b17023SJohn Marino       typedef basic_string<_CharT, _Traits, _Alloc>	__string_type;
1003*e4b17023SJohn Marino       typedef typename __istream_type::ios_base         __ios_base;
1004*e4b17023SJohn Marino       typedef typename __istream_type::int_type		__int_type;
1005*e4b17023SJohn Marino       typedef typename __string_type::size_type		__size_type;
1006*e4b17023SJohn Marino       typedef ctype<_CharT>				__ctype_type;
1007*e4b17023SJohn Marino       typedef typename __ctype_type::ctype_base         __ctype_base;
1008*e4b17023SJohn Marino 
1009*e4b17023SJohn Marino       __size_type __extracted = 0;
1010*e4b17023SJohn Marino       typename __ios_base::iostate __err = __ios_base::goodbit;
1011*e4b17023SJohn Marino       typename __istream_type::sentry __cerb(__in, false);
1012*e4b17023SJohn Marino       if (__cerb)
1013*e4b17023SJohn Marino 	{
1014*e4b17023SJohn Marino 	  __try
1015*e4b17023SJohn Marino 	    {
1016*e4b17023SJohn Marino 	      // Avoid reallocation for common case.
1017*e4b17023SJohn Marino 	      __str.erase();
1018*e4b17023SJohn Marino 	      _CharT __buf[128];
1019*e4b17023SJohn Marino 	      __size_type __len = 0;
1020*e4b17023SJohn Marino 	      const streamsize __w = __in.width();
1021*e4b17023SJohn Marino 	      const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
1022*e4b17023SJohn Marino 		                              : __str.max_size();
1023*e4b17023SJohn Marino 	      const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
1024*e4b17023SJohn Marino 	      const __int_type __eof = _Traits::eof();
1025*e4b17023SJohn Marino 	      __int_type __c = __in.rdbuf()->sgetc();
1026*e4b17023SJohn Marino 
1027*e4b17023SJohn Marino 	      while (__extracted < __n
1028*e4b17023SJohn Marino 		     && !_Traits::eq_int_type(__c, __eof)
1029*e4b17023SJohn Marino 		     && !__ct.is(__ctype_base::space,
1030*e4b17023SJohn Marino 				 _Traits::to_char_type(__c)))
1031*e4b17023SJohn Marino 		{
1032*e4b17023SJohn Marino 		  if (__len == sizeof(__buf) / sizeof(_CharT))
1033*e4b17023SJohn Marino 		    {
1034*e4b17023SJohn Marino 		      __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
1035*e4b17023SJohn Marino 		      __len = 0;
1036*e4b17023SJohn Marino 		    }
1037*e4b17023SJohn Marino 		  __buf[__len++] = _Traits::to_char_type(__c);
1038*e4b17023SJohn Marino 		  ++__extracted;
1039*e4b17023SJohn Marino 		  __c = __in.rdbuf()->snextc();
1040*e4b17023SJohn Marino 		}
1041*e4b17023SJohn Marino 	      __str.append(__buf, __len);
1042*e4b17023SJohn Marino 
1043*e4b17023SJohn Marino 	      if (_Traits::eq_int_type(__c, __eof))
1044*e4b17023SJohn Marino 		__err |= __ios_base::eofbit;
1045*e4b17023SJohn Marino 	      __in.width(0);
1046*e4b17023SJohn Marino 	    }
1047*e4b17023SJohn Marino 	  __catch(__cxxabiv1::__forced_unwind&)
1048*e4b17023SJohn Marino 	    {
1049*e4b17023SJohn Marino 	      __in._M_setstate(__ios_base::badbit);
1050*e4b17023SJohn Marino 	      __throw_exception_again;
1051*e4b17023SJohn Marino 	    }
1052*e4b17023SJohn Marino 	  __catch(...)
1053*e4b17023SJohn Marino 	    {
1054*e4b17023SJohn Marino 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1055*e4b17023SJohn Marino 	      // 91. Description of operator>> and getline() for string<>
1056*e4b17023SJohn Marino 	      // might cause endless loop
1057*e4b17023SJohn Marino 	      __in._M_setstate(__ios_base::badbit);
1058*e4b17023SJohn Marino 	    }
1059*e4b17023SJohn Marino 	}
1060*e4b17023SJohn Marino       // 211.  operator>>(istream&, string&) doesn't set failbit
1061*e4b17023SJohn Marino       if (!__extracted)
1062*e4b17023SJohn Marino 	__err |= __ios_base::failbit;
1063*e4b17023SJohn Marino       if (__err)
1064*e4b17023SJohn Marino 	__in.setstate(__err);
1065*e4b17023SJohn Marino       return __in;
1066*e4b17023SJohn Marino     }
1067*e4b17023SJohn Marino 
1068*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
1069*e4b17023SJohn Marino     basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT,_Traits> & __in,basic_string<_CharT,_Traits,_Alloc> & __str,_CharT __delim)1070*e4b17023SJohn Marino     getline(basic_istream<_CharT, _Traits>& __in,
1071*e4b17023SJohn Marino 	    basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
1072*e4b17023SJohn Marino     {
1073*e4b17023SJohn Marino       typedef basic_istream<_CharT, _Traits>		__istream_type;
1074*e4b17023SJohn Marino       typedef basic_string<_CharT, _Traits, _Alloc>	__string_type;
1075*e4b17023SJohn Marino       typedef typename __istream_type::ios_base         __ios_base;
1076*e4b17023SJohn Marino       typedef typename __istream_type::int_type		__int_type;
1077*e4b17023SJohn Marino       typedef typename __string_type::size_type		__size_type;
1078*e4b17023SJohn Marino 
1079*e4b17023SJohn Marino       __size_type __extracted = 0;
1080*e4b17023SJohn Marino       const __size_type __n = __str.max_size();
1081*e4b17023SJohn Marino       typename __ios_base::iostate __err = __ios_base::goodbit;
1082*e4b17023SJohn Marino       typename __istream_type::sentry __cerb(__in, true);
1083*e4b17023SJohn Marino       if (__cerb)
1084*e4b17023SJohn Marino 	{
1085*e4b17023SJohn Marino 	  __try
1086*e4b17023SJohn Marino 	    {
1087*e4b17023SJohn Marino 	      __str.erase();
1088*e4b17023SJohn Marino 	      const __int_type __idelim = _Traits::to_int_type(__delim);
1089*e4b17023SJohn Marino 	      const __int_type __eof = _Traits::eof();
1090*e4b17023SJohn Marino 	      __int_type __c = __in.rdbuf()->sgetc();
1091*e4b17023SJohn Marino 
1092*e4b17023SJohn Marino 	      while (__extracted < __n
1093*e4b17023SJohn Marino 		     && !_Traits::eq_int_type(__c, __eof)
1094*e4b17023SJohn Marino 		     && !_Traits::eq_int_type(__c, __idelim))
1095*e4b17023SJohn Marino 		{
1096*e4b17023SJohn Marino 		  __str += _Traits::to_char_type(__c);
1097*e4b17023SJohn Marino 		  ++__extracted;
1098*e4b17023SJohn Marino 		  __c = __in.rdbuf()->snextc();
1099*e4b17023SJohn Marino 		}
1100*e4b17023SJohn Marino 
1101*e4b17023SJohn Marino 	      if (_Traits::eq_int_type(__c, __eof))
1102*e4b17023SJohn Marino 		__err |= __ios_base::eofbit;
1103*e4b17023SJohn Marino 	      else if (_Traits::eq_int_type(__c, __idelim))
1104*e4b17023SJohn Marino 		{
1105*e4b17023SJohn Marino 		  ++__extracted;
1106*e4b17023SJohn Marino 		  __in.rdbuf()->sbumpc();
1107*e4b17023SJohn Marino 		}
1108*e4b17023SJohn Marino 	      else
1109*e4b17023SJohn Marino 		__err |= __ios_base::failbit;
1110*e4b17023SJohn Marino 	    }
1111*e4b17023SJohn Marino 	  __catch(__cxxabiv1::__forced_unwind&)
1112*e4b17023SJohn Marino 	    {
1113*e4b17023SJohn Marino 	      __in._M_setstate(__ios_base::badbit);
1114*e4b17023SJohn Marino 	      __throw_exception_again;
1115*e4b17023SJohn Marino 	    }
1116*e4b17023SJohn Marino 	  __catch(...)
1117*e4b17023SJohn Marino 	    {
1118*e4b17023SJohn Marino 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
1119*e4b17023SJohn Marino 	      // 91. Description of operator>> and getline() for string<>
1120*e4b17023SJohn Marino 	      // might cause endless loop
1121*e4b17023SJohn Marino 	      __in._M_setstate(__ios_base::badbit);
1122*e4b17023SJohn Marino 	    }
1123*e4b17023SJohn Marino 	}
1124*e4b17023SJohn Marino       if (!__extracted)
1125*e4b17023SJohn Marino 	__err |= __ios_base::failbit;
1126*e4b17023SJohn Marino       if (__err)
1127*e4b17023SJohn Marino 	__in.setstate(__err);
1128*e4b17023SJohn Marino       return __in;
1129*e4b17023SJohn Marino     }
1130*e4b17023SJohn Marino 
1131*e4b17023SJohn Marino   // Inhibit implicit instantiations for required instantiations,
1132*e4b17023SJohn Marino   // which are defined via explicit instantiations elsewhere.
1133*e4b17023SJohn Marino #if _GLIBCXX_EXTERN_TEMPLATE > 0
1134*e4b17023SJohn Marino   extern template class basic_string<char>;
1135*e4b17023SJohn Marino   extern template
1136*e4b17023SJohn Marino     basic_istream<char>&
1137*e4b17023SJohn Marino     operator>>(basic_istream<char>&, string&);
1138*e4b17023SJohn Marino   extern template
1139*e4b17023SJohn Marino     basic_ostream<char>&
1140*e4b17023SJohn Marino     operator<<(basic_ostream<char>&, const string&);
1141*e4b17023SJohn Marino   extern template
1142*e4b17023SJohn Marino     basic_istream<char>&
1143*e4b17023SJohn Marino     getline(basic_istream<char>&, string&, char);
1144*e4b17023SJohn Marino   extern template
1145*e4b17023SJohn Marino     basic_istream<char>&
1146*e4b17023SJohn Marino     getline(basic_istream<char>&, string&);
1147*e4b17023SJohn Marino 
1148*e4b17023SJohn Marino #ifdef _GLIBCXX_USE_WCHAR_T
1149*e4b17023SJohn Marino   extern template class basic_string<wchar_t>;
1150*e4b17023SJohn Marino   extern template
1151*e4b17023SJohn Marino     basic_istream<wchar_t>&
1152*e4b17023SJohn Marino     operator>>(basic_istream<wchar_t>&, wstring&);
1153*e4b17023SJohn Marino   extern template
1154*e4b17023SJohn Marino     basic_ostream<wchar_t>&
1155*e4b17023SJohn Marino     operator<<(basic_ostream<wchar_t>&, const wstring&);
1156*e4b17023SJohn Marino   extern template
1157*e4b17023SJohn Marino     basic_istream<wchar_t>&
1158*e4b17023SJohn Marino     getline(basic_istream<wchar_t>&, wstring&, wchar_t);
1159*e4b17023SJohn Marino   extern template
1160*e4b17023SJohn Marino     basic_istream<wchar_t>&
1161*e4b17023SJohn Marino     getline(basic_istream<wchar_t>&, wstring&);
1162*e4b17023SJohn Marino #endif
1163*e4b17023SJohn Marino #endif
1164*e4b17023SJohn Marino 
1165*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION
1166*e4b17023SJohn Marino } // namespace std
1167*e4b17023SJohn Marino 
1168*e4b17023SJohn Marino #endif
1169