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