00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef _SSO_STRING_BASE_H
00032 #define _SSO_STRING_BASE_H 1
00033
00034 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
00035
00036 template<typename _CharT, typename _Traits, typename _Alloc>
00037 class __sso_string_base
00038 : protected __vstring_utility<_CharT, _Traits, _Alloc>
00039 {
00040 public:
00041 typedef _Traits traits_type;
00042 typedef typename _Traits::char_type value_type;
00043
00044 typedef __vstring_utility<_CharT, _Traits, _Alloc> _Util_Base;
00045 typedef typename _Util_Base::_CharT_alloc_type _CharT_alloc_type;
00046 typedef typename _CharT_alloc_type::size_type size_type;
00047
00048 private:
00049
00050 typename _Util_Base::template _Alloc_hider<_CharT_alloc_type>
00051 _M_dataplus;
00052 size_type _M_string_length;
00053
00054 enum { _S_local_capacity = 15 };
00055
00056 union
00057 {
00058 _CharT _M_local_data[_S_local_capacity + 1];
00059 size_type _M_allocated_capacity;
00060 };
00061
00062 void
00063 _M_data(_CharT* __p)
00064 { _M_dataplus._M_p = __p; }
00065
00066 void
00067 _M_length(size_type __length)
00068 { _M_string_length = __length; }
00069
00070 void
00071 _M_capacity(size_type __capacity)
00072 { _M_allocated_capacity = __capacity; }
00073
00074 bool
00075 _M_is_local() const
00076 { return _M_data() == _M_local_data; }
00077
00078
00079 _CharT*
00080 _M_create(size_type&, size_type);
00081
00082 void
00083 _M_dispose()
00084 {
00085 if (!_M_is_local())
00086 _M_destroy(_M_allocated_capacity);
00087 }
00088
00089 void
00090 _M_destroy(size_type __size) throw()
00091 { _M_get_allocator().deallocate(_M_data(), __size + 1); }
00092
00093
00094
00095 template<typename _InIterator>
00096 void
00097 _M_construct_aux(_InIterator __beg, _InIterator __end,
00098 std::__false_type)
00099 {
00100 typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
00101 _M_construct(__beg, __end, _Tag());
00102 }
00103
00104
00105
00106 template<typename _Integer>
00107 void
00108 _M_construct_aux(_Integer __beg, _Integer __end, std::__true_type)
00109 { _M_construct_aux_2(static_cast<size_type>(__beg), __end); }
00110
00111 void
00112 _M_construct_aux_2(size_type __req, _CharT __c)
00113 { _M_construct(__req, __c); }
00114
00115 template<typename _InIterator>
00116 void
00117 _M_construct(_InIterator __beg, _InIterator __end)
00118 {
00119 typedef typename std::__is_integer<_InIterator>::__type _Integral;
00120 _M_construct_aux(__beg, __end, _Integral());
00121 }
00122
00123
00124 template<typename _InIterator>
00125 void
00126 _M_construct(_InIterator __beg, _InIterator __end,
00127 std::input_iterator_tag);
00128
00129
00130
00131 template<typename _FwdIterator>
00132 void
00133 _M_construct(_FwdIterator __beg, _FwdIterator __end,
00134 std::forward_iterator_tag);
00135
00136 void
00137 _M_construct(size_type __req, _CharT __c);
00138
00139 public:
00140 size_type
00141 _M_max_size() const
00142 { return (_M_get_allocator().max_size() - 1) / 2; }
00143
00144 _CharT*
00145 _M_data() const
00146 { return _M_dataplus._M_p; }
00147
00148 size_type
00149 _M_length() const
00150 { return _M_string_length; }
00151
00152 size_type
00153 _M_capacity() const
00154 {
00155 return _M_is_local() ? size_type(_S_local_capacity)
00156 : _M_allocated_capacity;
00157 }
00158
00159 bool
00160 _M_is_shared() const
00161 { return false; }
00162
00163 void
00164 _M_set_leaked() { }
00165
00166 void
00167 _M_leak() { }
00168
00169 void
00170 _M_set_length(size_type __n)
00171 {
00172 _M_length(__n);
00173 traits_type::assign(_M_data()[__n], _CharT());
00174 }
00175
00176 __sso_string_base()
00177 : _M_dataplus(_M_local_data)
00178 { _M_set_length(0); }
00179
00180 __sso_string_base(const _Alloc& __a);
00181
00182 __sso_string_base(const __sso_string_base& __rcs);
00183
00184 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00185 __sso_string_base(__sso_string_base&& __rcs);
00186 #endif
00187
00188 __sso_string_base(size_type __n, _CharT __c, const _Alloc& __a);
00189
00190 template<typename _InputIterator>
00191 __sso_string_base(_InputIterator __beg, _InputIterator __end,
00192 const _Alloc& __a);
00193
00194 ~__sso_string_base()
00195 { _M_dispose(); }
00196
00197 _CharT_alloc_type&
00198 _M_get_allocator()
00199 { return _M_dataplus; }
00200
00201 const _CharT_alloc_type&
00202 _M_get_allocator() const
00203 { return _M_dataplus; }
00204
00205 void
00206 _M_swap(__sso_string_base& __rcs);
00207
00208 void
00209 _M_assign(const __sso_string_base& __rcs);
00210
00211 void
00212 _M_reserve(size_type __res);
00213
00214 void
00215 _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
00216 size_type __len2);
00217
00218 void
00219 _M_erase(size_type __pos, size_type __n);
00220
00221 void
00222 _M_clear()
00223 { _M_set_length(0); }
00224
00225 bool
00226 _M_compare(const __sso_string_base&) const
00227 { return false; }
00228 };
00229
00230 template<typename _CharT, typename _Traits, typename _Alloc>
00231 void
00232 __sso_string_base<_CharT, _Traits, _Alloc>::
00233 _M_swap(__sso_string_base& __rcs)
00234 {
00235
00236
00237 std::__alloc_swap<_CharT_alloc_type>::_S_do_it(_M_get_allocator(),
00238 __rcs._M_get_allocator());
00239
00240 if (_M_is_local())
00241 if (__rcs._M_is_local())
00242 {
00243 if (_M_length() && __rcs._M_length())
00244 {
00245 _CharT __tmp_data[_S_local_capacity + 1];
00246 traits_type::copy(__tmp_data, __rcs._M_local_data,
00247 _S_local_capacity + 1);
00248 traits_type::copy(__rcs._M_local_data, _M_local_data,
00249 _S_local_capacity + 1);
00250 traits_type::copy(_M_local_data, __tmp_data,
00251 _S_local_capacity + 1);
00252 }
00253 else if (__rcs._M_length())
00254 {
00255 traits_type::copy(_M_local_data, __rcs._M_local_data,
00256 _S_local_capacity + 1);
00257 _M_length(__rcs._M_length());
00258 __rcs._M_set_length(0);
00259 return;
00260 }
00261 else if (_M_length())
00262 {
00263 traits_type::copy(__rcs._M_local_data, _M_local_data,
00264 _S_local_capacity + 1);
00265 __rcs._M_length(_M_length());
00266 _M_set_length(0);
00267 return;
00268 }
00269 }
00270 else
00271 {
00272 const size_type __tmp_capacity = __rcs._M_allocated_capacity;
00273 traits_type::copy(__rcs._M_local_data, _M_local_data,
00274 _S_local_capacity + 1);
00275 _M_data(__rcs._M_data());
00276 __rcs._M_data(__rcs._M_local_data);
00277 _M_capacity(__tmp_capacity);
00278 }
00279 else
00280 {
00281 const size_type __tmp_capacity = _M_allocated_capacity;
00282 if (__rcs._M_is_local())
00283 {
00284 traits_type::copy(_M_local_data, __rcs._M_local_data,
00285 _S_local_capacity + 1);
00286 __rcs._M_data(_M_data());
00287 _M_data(_M_local_data);
00288 }
00289 else
00290 {
00291 _CharT* __tmp_ptr = _M_data();
00292 _M_data(__rcs._M_data());
00293 __rcs._M_data(__tmp_ptr);
00294 _M_capacity(__rcs._M_allocated_capacity);
00295 }
00296 __rcs._M_capacity(__tmp_capacity);
00297 }
00298
00299 const size_type __tmp_length = _M_length();
00300 _M_length(__rcs._M_length());
00301 __rcs._M_length(__tmp_length);
00302 }
00303
00304 template<typename _CharT, typename _Traits, typename _Alloc>
00305 _CharT*
00306 __sso_string_base<_CharT, _Traits, _Alloc>::
00307 _M_create(size_type& __capacity, size_type __old_capacity)
00308 {
00309
00310
00311 if (__capacity > _M_max_size())
00312 std::__throw_length_error(__N("__sso_string_base::_M_create"));
00313
00314
00315
00316
00317 if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
00318 {
00319 __capacity = 2 * __old_capacity;
00320
00321 if (__capacity > _M_max_size())
00322 __capacity = _M_max_size();
00323 }
00324
00325
00326
00327 return _M_get_allocator().allocate(__capacity + 1);
00328 }
00329
00330 template<typename _CharT, typename _Traits, typename _Alloc>
00331 __sso_string_base<_CharT, _Traits, _Alloc>::
00332 __sso_string_base(const _Alloc& __a)
00333 : _M_dataplus(__a, _M_local_data)
00334 { _M_set_length(0); }
00335
00336 template<typename _CharT, typename _Traits, typename _Alloc>
00337 __sso_string_base<_CharT, _Traits, _Alloc>::
00338 __sso_string_base(const __sso_string_base& __rcs)
00339 : _M_dataplus(__rcs._M_get_allocator(), _M_local_data)
00340 { _M_construct(__rcs._M_data(), __rcs._M_data() + __rcs._M_length()); }
00341
00342 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00343 template<typename _CharT, typename _Traits, typename _Alloc>
00344 __sso_string_base<_CharT, _Traits, _Alloc>::
00345 __sso_string_base(__sso_string_base&& __rcs)
00346 : _M_dataplus(__rcs._M_get_allocator(), _M_local_data)
00347 {
00348 if (__rcs._M_is_local())
00349 {
00350 if (__rcs._M_length())
00351 traits_type::copy(_M_local_data, __rcs._M_local_data,
00352 _S_local_capacity + 1);
00353 }
00354 else
00355 {
00356 _M_data(__rcs._M_data());
00357 _M_capacity(__rcs._M_allocated_capacity);
00358 }
00359
00360 _M_length(__rcs._M_length());
00361 __rcs._M_length(0);
00362 __rcs._M_data(__rcs._M_local_data);
00363 }
00364 #endif
00365
00366 template<typename _CharT, typename _Traits, typename _Alloc>
00367 __sso_string_base<_CharT, _Traits, _Alloc>::
00368 __sso_string_base(size_type __n, _CharT __c, const _Alloc& __a)
00369 : _M_dataplus(__a, _M_local_data)
00370 { _M_construct(__n, __c); }
00371
00372 template<typename _CharT, typename _Traits, typename _Alloc>
00373 template<typename _InputIterator>
00374 __sso_string_base<_CharT, _Traits, _Alloc>::
00375 __sso_string_base(_InputIterator __beg, _InputIterator __end,
00376 const _Alloc& __a)
00377 : _M_dataplus(__a, _M_local_data)
00378 { _M_construct(__beg, __end); }
00379
00380
00381
00382
00383
00384 template<typename _CharT, typename _Traits, typename _Alloc>
00385 template<typename _InIterator>
00386 void
00387 __sso_string_base<_CharT, _Traits, _Alloc>::
00388 _M_construct(_InIterator __beg, _InIterator __end,
00389 std::input_iterator_tag)
00390 {
00391 size_type __len = 0;
00392 size_type __capacity = size_type(_S_local_capacity);
00393
00394 while (__beg != __end && __len < __capacity)
00395 {
00396 _M_data()[__len++] = *__beg;
00397 ++__beg;
00398 }
00399
00400 __try
00401 {
00402 while (__beg != __end)
00403 {
00404 if (__len == __capacity)
00405 {
00406
00407 __capacity = __len + 1;
00408 _CharT* __another = _M_create(__capacity, __len);
00409 _S_copy(__another, _M_data(), __len);
00410 _M_dispose();
00411 _M_data(__another);
00412 _M_capacity(__capacity);
00413 }
00414 _M_data()[__len++] = *__beg;
00415 ++__beg;
00416 }
00417 }
00418 __catch(...)
00419 {
00420 _M_dispose();
00421 __throw_exception_again;
00422 }
00423
00424 _M_set_length(__len);
00425 }
00426
00427 template<typename _CharT, typename _Traits, typename _Alloc>
00428 template<typename _InIterator>
00429 void
00430 __sso_string_base<_CharT, _Traits, _Alloc>::
00431 _M_construct(_InIterator __beg, _InIterator __end,
00432 std::forward_iterator_tag)
00433 {
00434
00435 if (__is_null_pointer(__beg) && __beg != __end)
00436 std::__throw_logic_error(__N("__sso_string_base::"
00437 "_M_construct NULL not valid"));
00438
00439 size_type __dnew = static_cast<size_type>(std::distance(__beg, __end));
00440
00441 if (__dnew > size_type(_S_local_capacity))
00442 {
00443 _M_data(_M_create(__dnew, size_type(0)));
00444 _M_capacity(__dnew);
00445 }
00446
00447
00448 __try
00449 { _S_copy_chars(_M_data(), __beg, __end); }
00450 __catch(...)
00451 {
00452 _M_dispose();
00453 __throw_exception_again;
00454 }
00455
00456 _M_set_length(__dnew);
00457 }
00458
00459 template<typename _CharT, typename _Traits, typename _Alloc>
00460 void
00461 __sso_string_base<_CharT, _Traits, _Alloc>::
00462 _M_construct(size_type __n, _CharT __c)
00463 {
00464 if (__n > size_type(_S_local_capacity))
00465 {
00466 _M_data(_M_create(__n, size_type(0)));
00467 _M_capacity(__n);
00468 }
00469
00470 if (__n)
00471 _S_assign(_M_data(), __n, __c);
00472
00473 _M_set_length(__n);
00474 }
00475
00476 template<typename _CharT, typename _Traits, typename _Alloc>
00477 void
00478 __sso_string_base<_CharT, _Traits, _Alloc>::
00479 _M_assign(const __sso_string_base& __rcs)
00480 {
00481 if (this != &__rcs)
00482 {
00483 const size_type __rsize = __rcs._M_length();
00484 const size_type __capacity = _M_capacity();
00485
00486 if (__rsize > __capacity)
00487 {
00488 size_type __new_capacity = __rsize;
00489 _CharT* __tmp = _M_create(__new_capacity, __capacity);
00490 _M_dispose();
00491 _M_data(__tmp);
00492 _M_capacity(__new_capacity);
00493 }
00494
00495 if (__rsize)
00496 _S_copy(_M_data(), __rcs._M_data(), __rsize);
00497
00498 _M_set_length(__rsize);
00499 }
00500 }
00501
00502 template<typename _CharT, typename _Traits, typename _Alloc>
00503 void
00504 __sso_string_base<_CharT, _Traits, _Alloc>::
00505 _M_reserve(size_type __res)
00506 {
00507
00508 if (__res < _M_length())
00509 __res = _M_length();
00510
00511 const size_type __capacity = _M_capacity();
00512 if (__res != __capacity)
00513 {
00514 if (__res > __capacity
00515 || __res > size_type(_S_local_capacity))
00516 {
00517 _CharT* __tmp = _M_create(__res, __capacity);
00518 _S_copy(__tmp, _M_data(), _M_length() + 1);
00519 _M_dispose();
00520 _M_data(__tmp);
00521 _M_capacity(__res);
00522 }
00523 else if (!_M_is_local())
00524 {
00525 _S_copy(_M_local_data, _M_data(), _M_length() + 1);
00526 _M_destroy(__capacity);
00527 _M_data(_M_local_data);
00528 }
00529 }
00530 }
00531
00532 template<typename _CharT, typename _Traits, typename _Alloc>
00533 void
00534 __sso_string_base<_CharT, _Traits, _Alloc>::
00535 _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
00536 size_type __len2)
00537 {
00538 const size_type __how_much = _M_length() - __pos - __len1;
00539
00540 size_type __new_capacity = _M_length() + __len2 - __len1;
00541 _CharT* __r = _M_create(__new_capacity, _M_capacity());
00542
00543 if (__pos)
00544 _S_copy(__r, _M_data(), __pos);
00545 if (__s && __len2)
00546 _S_copy(__r + __pos, __s, __len2);
00547 if (__how_much)
00548 _S_copy(__r + __pos + __len2,
00549 _M_data() + __pos + __len1, __how_much);
00550
00551 _M_dispose();
00552 _M_data(__r);
00553 _M_capacity(__new_capacity);
00554 }
00555
00556 template<typename _CharT, typename _Traits, typename _Alloc>
00557 void
00558 __sso_string_base<_CharT, _Traits, _Alloc>::
00559 _M_erase(size_type __pos, size_type __n)
00560 {
00561 const size_type __how_much = _M_length() - __pos - __n;
00562
00563 if (__how_much && __n)
00564 _S_move(_M_data() + __pos, _M_data() + __pos + __n,
00565 __how_much);
00566
00567 _M_set_length(_M_length() - __n);
00568 }
00569
00570 _GLIBCXX_END_NAMESPACE
00571
00572 #endif