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