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