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