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