xref: /openbsd-src/gnu/gcc/libstdc++-v3/include/ext/sso_string_base.h (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
1*404b540aSrobert // Short-string-optimized versatile string base -*- C++ -*-
2*404b540aSrobert 
3*404b540aSrobert // Copyright (C) 2005, 2006 Free Software Foundation, Inc.
4*404b540aSrobert //
5*404b540aSrobert // This file is part of the GNU ISO C++ Library.  This library is free
6*404b540aSrobert // software; you can redistribute it and/or modify it under the
7*404b540aSrobert // terms of the GNU General Public License as published by the
8*404b540aSrobert // Free Software Foundation; either version 2, or (at your option)
9*404b540aSrobert // any later version.
10*404b540aSrobert 
11*404b540aSrobert // This library is distributed in the hope that it will be useful,
12*404b540aSrobert // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*404b540aSrobert // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*404b540aSrobert // GNU General Public License for more details.
15*404b540aSrobert 
16*404b540aSrobert // You should have received a copy of the GNU General Public License along
17*404b540aSrobert // with this library; see the file COPYING.  If not, write to the Free
18*404b540aSrobert // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19*404b540aSrobert // USA.
20*404b540aSrobert 
21*404b540aSrobert // As a special exception, you may use this file as part of a free software
22*404b540aSrobert // library without restriction.  Specifically, if other files instantiate
23*404b540aSrobert // templates or use macros or inline functions from this file, or you compile
24*404b540aSrobert // this file and link it with other files to produce an executable, this
25*404b540aSrobert // file does not by itself cause the resulting executable to be covered by
26*404b540aSrobert // the GNU General Public License.  This exception does not however
27*404b540aSrobert // invalidate any other reasons why the executable file might be covered by
28*404b540aSrobert // the GNU General Public License.
29*404b540aSrobert 
30*404b540aSrobert /** @file ext/sso_string_base.h
31*404b540aSrobert  *  This file is a GNU extension to the Standard C++ Library.
32*404b540aSrobert  *  This is an internal header file, included by other library headers.
33*404b540aSrobert  *  You should not attempt to use it directly.
34*404b540aSrobert  */
35*404b540aSrobert 
36*404b540aSrobert #ifndef _SSO_STRING_BASE_H
37*404b540aSrobert #define _SSO_STRING_BASE_H 1
38*404b540aSrobert 
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)39*404b540aSrobert _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
40*404b540aSrobert 
41*404b540aSrobert   template<typename _CharT, typename _Traits, typename _Alloc>
42*404b540aSrobert     class __sso_string_base
43*404b540aSrobert     : protected __vstring_utility<_CharT, _Traits, _Alloc>
44*404b540aSrobert     {
45*404b540aSrobert     public:
46*404b540aSrobert       typedef _Traits					    traits_type;
47*404b540aSrobert       typedef typename _Traits::char_type		    value_type;
48*404b540aSrobert 
49*404b540aSrobert       typedef __vstring_utility<_CharT, _Traits, _Alloc>    _Util_Base;
50*404b540aSrobert       typedef typename _Util_Base::_CharT_alloc_type        _CharT_alloc_type;
51*404b540aSrobert       typedef typename _CharT_alloc_type::size_type	    size_type;
52*404b540aSrobert 
53*404b540aSrobert     private:
54*404b540aSrobert       // Data Members:
55*404b540aSrobert       typename _Util_Base::template _Alloc_hider<_CharT_alloc_type>
56*404b540aSrobert                                                             _M_dataplus;
57*404b540aSrobert       size_type                                             _M_string_length;
58*404b540aSrobert 
59*404b540aSrobert       enum { _S_local_capacity = 15 };
60*404b540aSrobert 
61*404b540aSrobert       union
62*404b540aSrobert       {
63*404b540aSrobert 	_CharT           _M_local_data[_S_local_capacity + 1];
64*404b540aSrobert 	size_type        _M_allocated_capacity;
65*404b540aSrobert       };
66*404b540aSrobert 
67*404b540aSrobert       void
68*404b540aSrobert       _M_data(_CharT* __p)
69*404b540aSrobert       { _M_dataplus._M_p = __p; }
70*404b540aSrobert 
71*404b540aSrobert       void
72*404b540aSrobert       _M_length(size_type __length)
73*404b540aSrobert       { _M_string_length = __length; }
74*404b540aSrobert 
75*404b540aSrobert       void
76*404b540aSrobert       _M_capacity(size_type __capacity)
77*404b540aSrobert       { _M_allocated_capacity = __capacity; }
78*404b540aSrobert 
79*404b540aSrobert       bool
80*404b540aSrobert       _M_is_local() const
81*404b540aSrobert       { return _M_data() == _M_local_data; }
82*404b540aSrobert 
83*404b540aSrobert       // Create & Destroy
84*404b540aSrobert       _CharT*
85*404b540aSrobert       _M_create(size_type&, size_type);
86*404b540aSrobert 
87*404b540aSrobert       void
88*404b540aSrobert       _M_dispose()
89*404b540aSrobert       {
90*404b540aSrobert 	if (!_M_is_local())
91*404b540aSrobert 	  _M_destroy(_M_allocated_capacity);
92*404b540aSrobert       }
93*404b540aSrobert 
94*404b540aSrobert       void
95*404b540aSrobert       _M_destroy(size_type __size) throw()
96*404b540aSrobert       { _M_get_allocator().deallocate(_M_data(), __size + 1); }
97*404b540aSrobert 
98*404b540aSrobert       // _M_construct_aux is used to implement the 21.3.1 para 15 which
99*404b540aSrobert       // requires special behaviour if _InIterator is an integral type
100*404b540aSrobert       template<typename _InIterator>
101*404b540aSrobert         void
102*404b540aSrobert         _M_construct_aux(_InIterator __beg, _InIterator __end,
103*404b540aSrobert 			 std::__false_type)
104*404b540aSrobert 	{
105*404b540aSrobert           typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
106*404b540aSrobert           _M_construct(__beg, __end, _Tag());
107*404b540aSrobert 	}
108*404b540aSrobert 
109*404b540aSrobert       template<typename _InIterator>
110*404b540aSrobert         void
111*404b540aSrobert         _M_construct_aux(_InIterator __beg, _InIterator __end,
112*404b540aSrobert 			 std::__true_type)
113*404b540aSrobert 	{ _M_construct(static_cast<size_type>(__beg),
114*404b540aSrobert 		       static_cast<value_type>(__end)); }
115*404b540aSrobert 
116*404b540aSrobert       template<typename _InIterator>
117*404b540aSrobert         void
118*404b540aSrobert         _M_construct(_InIterator __beg, _InIterator __end)
119*404b540aSrobert 	{
120*404b540aSrobert 	  typedef typename std::__is_integer<_InIterator>::__type _Integral;
121*404b540aSrobert 	  _M_construct_aux(__beg, __end, _Integral());
122*404b540aSrobert         }
123*404b540aSrobert 
124*404b540aSrobert       // For Input Iterators, used in istreambuf_iterators, etc.
125*404b540aSrobert       template<typename _InIterator>
126*404b540aSrobert         void
127*404b540aSrobert         _M_construct(_InIterator __beg, _InIterator __end,
128*404b540aSrobert 		     std::input_iterator_tag);
129*404b540aSrobert 
130*404b540aSrobert       // For forward_iterators up to random_access_iterators, used for
131*404b540aSrobert       // string::iterator, _CharT*, etc.
132*404b540aSrobert       template<typename _FwdIterator>
133*404b540aSrobert         void
134*404b540aSrobert         _M_construct(_FwdIterator __beg, _FwdIterator __end,
135*404b540aSrobert 		     std::forward_iterator_tag);
136*404b540aSrobert 
137*404b540aSrobert       void
138*404b540aSrobert       _M_construct(size_type __req, _CharT __c);
139*404b540aSrobert 
140*404b540aSrobert     public:
141*404b540aSrobert       size_type
142*404b540aSrobert       _M_max_size() const
143*404b540aSrobert       { return (_M_get_allocator().max_size() - 1) / 2; }
144*404b540aSrobert 
145*404b540aSrobert       _CharT*
146*404b540aSrobert       _M_data() const
147*404b540aSrobert       { return _M_dataplus._M_p; }
148*404b540aSrobert 
149*404b540aSrobert       size_type
150*404b540aSrobert       _M_length() const
151*404b540aSrobert       { return _M_string_length; }
152*404b540aSrobert 
153*404b540aSrobert       size_type
154*404b540aSrobert       _M_capacity() const
155*404b540aSrobert       {
156*404b540aSrobert 	return _M_is_local() ? size_type(_S_local_capacity)
157*404b540aSrobert 	                     : _M_allocated_capacity;
158*404b540aSrobert       }
159*404b540aSrobert 
160*404b540aSrobert       bool
161*404b540aSrobert       _M_is_shared() const
162*404b540aSrobert       { return false; }
163*404b540aSrobert 
164*404b540aSrobert       void
165*404b540aSrobert       _M_set_leaked() { }
166*404b540aSrobert 
167*404b540aSrobert       void
168*404b540aSrobert       _M_leak() { }
169*404b540aSrobert 
170*404b540aSrobert       void
171*404b540aSrobert       _M_set_length(size_type __n)
172*404b540aSrobert       {
173*404b540aSrobert 	_M_length(__n);
174*404b540aSrobert 	traits_type::assign(_M_data()[__n], _CharT());
175*404b540aSrobert       }
176*404b540aSrobert 
177*404b540aSrobert       __sso_string_base()
178*404b540aSrobert       : _M_dataplus(_Alloc(), _M_local_data)
179*404b540aSrobert       { _M_set_length(0); }
180*404b540aSrobert 
181*404b540aSrobert       __sso_string_base(const _Alloc& __a);
182*404b540aSrobert 
183*404b540aSrobert       __sso_string_base(const __sso_string_base& __rcs);
184*404b540aSrobert 
185*404b540aSrobert       __sso_string_base(size_type __n, _CharT __c, const _Alloc& __a);
186*404b540aSrobert 
187*404b540aSrobert       template<typename _InputIterator>
188*404b540aSrobert         __sso_string_base(_InputIterator __beg, _InputIterator __end,
189*404b540aSrobert 			  const _Alloc& __a);
190*404b540aSrobert 
191*404b540aSrobert       ~__sso_string_base()
192*404b540aSrobert       { _M_dispose(); }
193*404b540aSrobert 
194*404b540aSrobert       _CharT_alloc_type&
195*404b540aSrobert       _M_get_allocator()
196*404b540aSrobert       { return _M_dataplus; }
197*404b540aSrobert 
198*404b540aSrobert       const _CharT_alloc_type&
199*404b540aSrobert       _M_get_allocator() const
200*404b540aSrobert       { return _M_dataplus; }
201*404b540aSrobert 
202*404b540aSrobert       void
203*404b540aSrobert       _M_swap(__sso_string_base& __rcs);
204*404b540aSrobert 
205*404b540aSrobert       void
206*404b540aSrobert       _M_assign(const __sso_string_base& __rcs);
207*404b540aSrobert 
208*404b540aSrobert       void
209*404b540aSrobert       _M_reserve(size_type __res);
210*404b540aSrobert 
211*404b540aSrobert       void
212*404b540aSrobert       _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
213*404b540aSrobert 		size_type __len2);
214*404b540aSrobert 
215*404b540aSrobert       void
216*404b540aSrobert       _M_erase(size_type __pos, size_type __n);
217*404b540aSrobert 
218*404b540aSrobert       void
219*404b540aSrobert       _M_clear()
220*404b540aSrobert       { _M_set_length(0); }
221*404b540aSrobert 
222*404b540aSrobert       bool
223*404b540aSrobert       _M_compare(const __sso_string_base&) const
224*404b540aSrobert       { return false; }
225*404b540aSrobert     };
226*404b540aSrobert 
227*404b540aSrobert   template<typename _CharT, typename _Traits, typename _Alloc>
228*404b540aSrobert     void
229*404b540aSrobert     __sso_string_base<_CharT, _Traits, _Alloc>::
_M_swap(__sso_string_base & __rcs)230*404b540aSrobert     _M_swap(__sso_string_base& __rcs)
231*404b540aSrobert     {
232*404b540aSrobert       // _GLIBCXX_RESOLVE_LIB_DEFECTS
233*404b540aSrobert       // 431. Swapping containers with unequal allocators.
234*404b540aSrobert       std::__alloc_swap<_CharT_alloc_type>::_S_do_it(_M_get_allocator(),
235*404b540aSrobert 						     __rcs._M_get_allocator());
236*404b540aSrobert 
237*404b540aSrobert       if (_M_is_local())
238*404b540aSrobert 	if (__rcs._M_is_local())
239*404b540aSrobert 	  {
240*404b540aSrobert 	    if (_M_length() && __rcs._M_length())
241*404b540aSrobert 	      {
242*404b540aSrobert 		_CharT __tmp_data[_S_local_capacity + 1];
243*404b540aSrobert 		traits_type::copy(__tmp_data, __rcs._M_local_data,
244*404b540aSrobert 				  _S_local_capacity + 1);
245*404b540aSrobert 		traits_type::copy(__rcs._M_local_data, _M_local_data,
246*404b540aSrobert 				  _S_local_capacity + 1);
247*404b540aSrobert 		traits_type::copy(_M_local_data, __tmp_data,
248*404b540aSrobert 				  _S_local_capacity + 1);
249*404b540aSrobert 	      }
250*404b540aSrobert 	    else if (__rcs._M_length())
251*404b540aSrobert 	      {
252*404b540aSrobert 		traits_type::copy(_M_local_data, __rcs._M_local_data,
253*404b540aSrobert 				  _S_local_capacity + 1);
254*404b540aSrobert 		_M_length(__rcs._M_length());
255*404b540aSrobert 		__rcs._M_set_length(0);
256*404b540aSrobert 		return;
257*404b540aSrobert 	      }
258*404b540aSrobert 	    else if (_M_length())
259*404b540aSrobert 	      {
260*404b540aSrobert 		traits_type::copy(__rcs._M_local_data, _M_local_data,
261*404b540aSrobert 				  _S_local_capacity + 1);
262*404b540aSrobert 		__rcs._M_length(_M_length());
263*404b540aSrobert 		_M_set_length(0);
264*404b540aSrobert 		return;
265*404b540aSrobert 	      }
266*404b540aSrobert 	  }
267*404b540aSrobert 	else
268*404b540aSrobert 	  {
269*404b540aSrobert 	    const size_type __tmp_capacity = __rcs._M_allocated_capacity;
270*404b540aSrobert 	    traits_type::copy(__rcs._M_local_data, _M_local_data,
271*404b540aSrobert 			      _S_local_capacity + 1);
272*404b540aSrobert 	    _M_data(__rcs._M_data());
273*404b540aSrobert 	    __rcs._M_data(__rcs._M_local_data);
274*404b540aSrobert 	    _M_capacity(__tmp_capacity);
275*404b540aSrobert 	  }
276*404b540aSrobert       else
277*404b540aSrobert 	{
278*404b540aSrobert 	  const size_type __tmp_capacity = _M_allocated_capacity;
279*404b540aSrobert 	  if (__rcs._M_is_local())
280*404b540aSrobert 	    {
281*404b540aSrobert 	      traits_type::copy(_M_local_data, __rcs._M_local_data,
282*404b540aSrobert 				_S_local_capacity + 1);
283*404b540aSrobert 	      __rcs._M_data(_M_data());
284*404b540aSrobert 	      _M_data(_M_local_data);
285*404b540aSrobert 	    }
286*404b540aSrobert 	  else
287*404b540aSrobert 	    {
288*404b540aSrobert 	      _CharT* __tmp_ptr = _M_data();
289*404b540aSrobert 	      _M_data(__rcs._M_data());
290*404b540aSrobert 	      __rcs._M_data(__tmp_ptr);
291*404b540aSrobert 	      _M_capacity(__rcs._M_allocated_capacity);
292*404b540aSrobert 	    }
293*404b540aSrobert 	  __rcs._M_capacity(__tmp_capacity);
294*404b540aSrobert 	}
295*404b540aSrobert 
296*404b540aSrobert       const size_type __tmp_length = _M_length();
297*404b540aSrobert       _M_length(__rcs._M_length());
298*404b540aSrobert       __rcs._M_length(__tmp_length);
299*404b540aSrobert     }
300*404b540aSrobert 
301*404b540aSrobert   template<typename _CharT, typename _Traits, typename _Alloc>
302*404b540aSrobert     _CharT*
303*404b540aSrobert     __sso_string_base<_CharT, _Traits, _Alloc>::
_M_create(size_type & __capacity,size_type __old_capacity)304*404b540aSrobert     _M_create(size_type& __capacity, size_type __old_capacity)
305*404b540aSrobert     {
306*404b540aSrobert       // _GLIBCXX_RESOLVE_LIB_DEFECTS
307*404b540aSrobert       // 83.  String::npos vs. string::max_size()
308*404b540aSrobert       if (__capacity > _M_max_size())
309*404b540aSrobert 	std::__throw_length_error(__N("__sso_string_base::_M_create"));
310*404b540aSrobert 
311*404b540aSrobert       // The below implements an exponential growth policy, necessary to
312*404b540aSrobert       // meet amortized linear time requirements of the library: see
313*404b540aSrobert       // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
314*404b540aSrobert       if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
315*404b540aSrobert 	{
316*404b540aSrobert 	  __capacity = 2 * __old_capacity;
317*404b540aSrobert 	  // Never allocate a string bigger than max_size.
318*404b540aSrobert 	  if (__capacity > _M_max_size())
319*404b540aSrobert 	    __capacity = _M_max_size();
320*404b540aSrobert 	}
321*404b540aSrobert 
322*404b540aSrobert       // NB: Need an array of char_type[__capacity], plus a terminating
323*404b540aSrobert       // null char_type() element.
324*404b540aSrobert       return _M_get_allocator().allocate(__capacity + 1);
325*404b540aSrobert     }
326*404b540aSrobert 
327*404b540aSrobert   template<typename _CharT, typename _Traits, typename _Alloc>
328*404b540aSrobert     __sso_string_base<_CharT, _Traits, _Alloc>::
__sso_string_base(const _Alloc & __a)329*404b540aSrobert     __sso_string_base(const _Alloc& __a)
330*404b540aSrobert     : _M_dataplus(__a, _M_local_data)
331*404b540aSrobert     { _M_set_length(0); }
332*404b540aSrobert 
333*404b540aSrobert   template<typename _CharT, typename _Traits, typename _Alloc>
334*404b540aSrobert     __sso_string_base<_CharT, _Traits, _Alloc>::
__sso_string_base(const __sso_string_base & __rcs)335*404b540aSrobert     __sso_string_base(const __sso_string_base& __rcs)
336*404b540aSrobert     : _M_dataplus(__rcs._M_get_allocator(), _M_local_data)
337*404b540aSrobert     { _M_construct(__rcs._M_data(), __rcs._M_data() + __rcs._M_length()); }
338*404b540aSrobert 
339*404b540aSrobert   template<typename _CharT, typename _Traits, typename _Alloc>
340*404b540aSrobert     __sso_string_base<_CharT, _Traits, _Alloc>::
__sso_string_base(size_type __n,_CharT __c,const _Alloc & __a)341*404b540aSrobert     __sso_string_base(size_type __n, _CharT __c, const _Alloc& __a)
342*404b540aSrobert     : _M_dataplus(__a, _M_local_data)
343*404b540aSrobert     { _M_construct(__n, __c); }
344*404b540aSrobert 
345*404b540aSrobert   template<typename _CharT, typename _Traits, typename _Alloc>
346*404b540aSrobert     template<typename _InputIterator>
347*404b540aSrobert     __sso_string_base<_CharT, _Traits, _Alloc>::
__sso_string_base(_InputIterator __beg,_InputIterator __end,const _Alloc & __a)348*404b540aSrobert     __sso_string_base(_InputIterator __beg, _InputIterator __end,
349*404b540aSrobert 		      const _Alloc& __a)
350*404b540aSrobert     : _M_dataplus(__a, _M_local_data)
351*404b540aSrobert     { _M_construct(__beg, __end); }
352*404b540aSrobert 
353*404b540aSrobert   // NB: This is the special case for Input Iterators, used in
354*404b540aSrobert   // istreambuf_iterators, etc.
355*404b540aSrobert   // Input Iterators have a cost structure very different from
356*404b540aSrobert   // pointers, calling for a different coding style.
357*404b540aSrobert   template<typename _CharT, typename _Traits, typename _Alloc>
358*404b540aSrobert     template<typename _InIterator>
359*404b540aSrobert       void
360*404b540aSrobert       __sso_string_base<_CharT, _Traits, _Alloc>::
_M_construct(_InIterator __beg,_InIterator __end,std::input_iterator_tag)361*404b540aSrobert       _M_construct(_InIterator __beg, _InIterator __end,
362*404b540aSrobert 		   std::input_iterator_tag)
363*404b540aSrobert       {
364*404b540aSrobert 	size_type __len = 0;
365*404b540aSrobert 	size_type __capacity = size_type(_S_local_capacity);
366*404b540aSrobert 
367*404b540aSrobert 	while (__beg != __end && __len < __capacity)
368*404b540aSrobert 	  {
369*404b540aSrobert 	    _M_data()[__len++] = *__beg;
370*404b540aSrobert 	    ++__beg;
371*404b540aSrobert 	  }
372*404b540aSrobert 
373*404b540aSrobert 	try
374*404b540aSrobert 	  {
375*404b540aSrobert 	    while (__beg != __end)
376*404b540aSrobert 	      {
377*404b540aSrobert 		if (__len == __capacity)
378*404b540aSrobert 		  {
379*404b540aSrobert 		    // Allocate more space.
380*404b540aSrobert 		    __capacity = __len + 1;
381*404b540aSrobert 		    _CharT* __another = _M_create(__capacity, __len);
382*404b540aSrobert 		    _S_copy(__another, _M_data(), __len);
383*404b540aSrobert 		    _M_dispose();
384*404b540aSrobert 		    _M_data(__another);
385*404b540aSrobert 		    _M_capacity(__capacity);
386*404b540aSrobert 		  }
387*404b540aSrobert 		_M_data()[__len++] = *__beg;
388*404b540aSrobert 		++__beg;
389*404b540aSrobert 	      }
390*404b540aSrobert 	  }
391*404b540aSrobert 	catch(...)
392*404b540aSrobert 	  {
393*404b540aSrobert 	    _M_dispose();
394*404b540aSrobert 	    __throw_exception_again;
395*404b540aSrobert 	  }
396*404b540aSrobert 
397*404b540aSrobert 	_M_set_length(__len);
398*404b540aSrobert       }
399*404b540aSrobert 
400*404b540aSrobert   template<typename _CharT, typename _Traits, typename _Alloc>
401*404b540aSrobert     template<typename _InIterator>
402*404b540aSrobert       void
403*404b540aSrobert       __sso_string_base<_CharT, _Traits, _Alloc>::
_M_construct(_InIterator __beg,_InIterator __end,std::forward_iterator_tag)404*404b540aSrobert       _M_construct(_InIterator __beg, _InIterator __end,
405*404b540aSrobert 		   std::forward_iterator_tag)
406*404b540aSrobert       {
407*404b540aSrobert 	// NB: Not required, but considered best practice.
408*404b540aSrobert 	if (__builtin_expect(_S_is_null_pointer(__beg) && __beg != __end, 0))
409*404b540aSrobert 	  std::__throw_logic_error(__N("__sso_string_base::"
410*404b540aSrobert 				       "_M_construct NULL not valid"));
411*404b540aSrobert 
412*404b540aSrobert 	size_type __dnew = static_cast<size_type>(std::distance(__beg, __end));
413*404b540aSrobert 
414*404b540aSrobert 	if (__dnew > size_type(_S_local_capacity))
415*404b540aSrobert 	  {
416*404b540aSrobert 	    _M_data(_M_create(__dnew, size_type(0)));
417*404b540aSrobert 	    _M_capacity(__dnew);
418*404b540aSrobert 	  }
419*404b540aSrobert 
420*404b540aSrobert 	// Check for out_of_range and length_error exceptions.
421*404b540aSrobert 	try
422*404b540aSrobert 	  { _S_copy_chars(_M_data(), __beg, __end); }
423*404b540aSrobert 	catch(...)
424*404b540aSrobert 	  {
425*404b540aSrobert 	    _M_dispose();
426*404b540aSrobert 	    __throw_exception_again;
427*404b540aSrobert 	  }
428*404b540aSrobert 
429*404b540aSrobert 	_M_set_length(__dnew);
430*404b540aSrobert       }
431*404b540aSrobert 
432*404b540aSrobert   template<typename _CharT, typename _Traits, typename _Alloc>
433*404b540aSrobert     void
434*404b540aSrobert     __sso_string_base<_CharT, _Traits, _Alloc>::
_M_construct(size_type __n,_CharT __c)435*404b540aSrobert     _M_construct(size_type __n, _CharT __c)
436*404b540aSrobert     {
437*404b540aSrobert       if (__n > size_type(_S_local_capacity))
438*404b540aSrobert 	{
439*404b540aSrobert 	  _M_data(_M_create(__n, size_type(0)));
440*404b540aSrobert 	  _M_capacity(__n);
441*404b540aSrobert 	}
442*404b540aSrobert 
443*404b540aSrobert       if (__n)
444*404b540aSrobert 	_S_assign(_M_data(), __n, __c);
445*404b540aSrobert 
446*404b540aSrobert       _M_set_length(__n);
447*404b540aSrobert     }
448*404b540aSrobert 
449*404b540aSrobert   template<typename _CharT, typename _Traits, typename _Alloc>
450*404b540aSrobert     void
451*404b540aSrobert     __sso_string_base<_CharT, _Traits, _Alloc>::
_M_assign(const __sso_string_base & __rcs)452*404b540aSrobert     _M_assign(const __sso_string_base& __rcs)
453*404b540aSrobert     {
454*404b540aSrobert       if (this != &__rcs)
455*404b540aSrobert 	{
456*404b540aSrobert 	  const size_type __rsize = __rcs._M_length();
457*404b540aSrobert 	  const size_type __capacity = _M_capacity();
458*404b540aSrobert 
459*404b540aSrobert 	  if (__rsize > __capacity)
460*404b540aSrobert 	    {
461*404b540aSrobert 	      size_type __new_capacity = __rsize;
462*404b540aSrobert 	      _CharT* __tmp = _M_create(__new_capacity, __capacity);
463*404b540aSrobert 	      _M_dispose();
464*404b540aSrobert 	      _M_data(__tmp);
465*404b540aSrobert 	      _M_capacity(__new_capacity);
466*404b540aSrobert 	    }
467*404b540aSrobert 
468*404b540aSrobert 	  if (__rsize)
469*404b540aSrobert 	    _S_copy(_M_data(), __rcs._M_data(), __rsize);
470*404b540aSrobert 
471*404b540aSrobert 	  _M_set_length(__rsize);
472*404b540aSrobert 	}
473*404b540aSrobert     }
474*404b540aSrobert 
475*404b540aSrobert   template<typename _CharT, typename _Traits, typename _Alloc>
476*404b540aSrobert     void
477*404b540aSrobert     __sso_string_base<_CharT, _Traits, _Alloc>::
_M_reserve(size_type __res)478*404b540aSrobert     _M_reserve(size_type __res)
479*404b540aSrobert     {
480*404b540aSrobert       // Make sure we don't shrink below the current size.
481*404b540aSrobert       if (__res < _M_length())
482*404b540aSrobert 	__res = _M_length();
483*404b540aSrobert 
484*404b540aSrobert       const size_type __capacity = _M_capacity();
485*404b540aSrobert       if (__res != __capacity)
486*404b540aSrobert 	{
487*404b540aSrobert 	  if (__res > __capacity
488*404b540aSrobert 	      || __res > size_type(_S_local_capacity))
489*404b540aSrobert 	    {
490*404b540aSrobert 	      _CharT* __tmp = _M_create(__res, __capacity);
491*404b540aSrobert 	      _S_copy(__tmp, _M_data(), _M_length() + 1);
492*404b540aSrobert 	      _M_dispose();
493*404b540aSrobert 	      _M_data(__tmp);
494*404b540aSrobert 	      _M_capacity(__res);
495*404b540aSrobert 	    }
496*404b540aSrobert 	  else if (!_M_is_local())
497*404b540aSrobert 	    {
498*404b540aSrobert 	      _S_copy(_M_local_data, _M_data(), _M_length() + 1);
499*404b540aSrobert 	      _M_destroy(__capacity);
500*404b540aSrobert 	      _M_data(_M_local_data);
501*404b540aSrobert 	    }
502*404b540aSrobert 	}
503*404b540aSrobert     }
504*404b540aSrobert 
505*404b540aSrobert   template<typename _CharT, typename _Traits, typename _Alloc>
506*404b540aSrobert     void
507*404b540aSrobert     __sso_string_base<_CharT, _Traits, _Alloc>::
_M_mutate(size_type __pos,size_type __len1,const _CharT * __s,const size_type __len2)508*404b540aSrobert     _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
509*404b540aSrobert 	      const size_type __len2)
510*404b540aSrobert     {
511*404b540aSrobert       const size_type __how_much = _M_length() - __pos - __len1;
512*404b540aSrobert 
513*404b540aSrobert       size_type __new_capacity = _M_length() + __len2 - __len1;
514*404b540aSrobert       _CharT* __r = _M_create(__new_capacity, _M_capacity());
515*404b540aSrobert 
516*404b540aSrobert       if (__pos)
517*404b540aSrobert 	_S_copy(__r, _M_data(), __pos);
518*404b540aSrobert       if (__s && __len2)
519*404b540aSrobert 	_S_copy(__r + __pos, __s, __len2);
520*404b540aSrobert       if (__how_much)
521*404b540aSrobert 	_S_copy(__r + __pos + __len2,
522*404b540aSrobert 		_M_data() + __pos + __len1, __how_much);
523*404b540aSrobert 
524*404b540aSrobert       _M_dispose();
525*404b540aSrobert       _M_data(__r);
526*404b540aSrobert       _M_capacity(__new_capacity);
527*404b540aSrobert     }
528*404b540aSrobert 
529*404b540aSrobert   template<typename _CharT, typename _Traits, typename _Alloc>
530*404b540aSrobert     void
531*404b540aSrobert     __sso_string_base<_CharT, _Traits, _Alloc>::
_M_erase(size_type __pos,size_type __n)532*404b540aSrobert     _M_erase(size_type __pos, size_type __n)
533*404b540aSrobert     {
534*404b540aSrobert       const size_type __how_much = _M_length() - __pos - __n;
535*404b540aSrobert 
536*404b540aSrobert       if (__how_much && __n)
537*404b540aSrobert 	_S_move(_M_data() + __pos, _M_data() + __pos + __n,
538*404b540aSrobert 		__how_much);
539*404b540aSrobert 
540*404b540aSrobert       _M_set_length(_M_length() - __n);
541*404b540aSrobert     }
542*404b540aSrobert 
543*404b540aSrobert   template<>
544*404b540aSrobert     inline bool
545*404b540aSrobert     __sso_string_base<char, std::char_traits<char>,
546*404b540aSrobert 		      std::allocator<char> >::
_M_compare(const __sso_string_base & __rcs)547*404b540aSrobert     _M_compare(const __sso_string_base& __rcs) const
548*404b540aSrobert     {
549*404b540aSrobert       if (this == &__rcs)
550*404b540aSrobert 	return true;
551*404b540aSrobert       return false;
552*404b540aSrobert     }
553*404b540aSrobert 
554*404b540aSrobert #ifdef _GLIBCXX_USE_WCHAR_T
555*404b540aSrobert   template<>
556*404b540aSrobert     inline bool
557*404b540aSrobert     __sso_string_base<wchar_t, std::char_traits<wchar_t>,
558*404b540aSrobert 		      std::allocator<wchar_t> >::
_M_compare(const __sso_string_base & __rcs)559*404b540aSrobert     _M_compare(const __sso_string_base& __rcs) const
560*404b540aSrobert     {
561*404b540aSrobert       if (this == &__rcs)
562*404b540aSrobert 	return true;
563*404b540aSrobert       return false;
564*404b540aSrobert     }
565*404b540aSrobert #endif
566*404b540aSrobert 
567*404b540aSrobert _GLIBCXX_END_NAMESPACE
568*404b540aSrobert 
569*404b540aSrobert #endif /* _SSO_STRING_BASE_H */
570