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 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