30 #ifndef _RC_STRING_BASE_H 
   31 #define _RC_STRING_BASE_H 1 
   36 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 
   38 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   81  template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
   83     : 
protected __vstring_utility<_CharT, _Traits, _Alloc>
 
   86       typedef _Traits                       traits_type;
 
   87       typedef typename _Traits::char_type           value_type;
 
   88       typedef _Alloc                        allocator_type;
 
   90       typedef __vstring_utility<_CharT, _Traits, _Alloc>    _Util_Base;
 
   91       typedef typename _Util_Base::_CharT_alloc_type        _CharT_alloc_type;
 
   92       typedef typename _CharT_alloc_type::size_type     size_type;
 
  115         size_type       _M_capacity;
 
  116         _Atomic_word    _M_refcount;
 
  123     typedef typename _Alloc::template rebind<_Rep>::other _Rep_alloc_type;
 
  127     { 
return reinterpret_cast<_CharT*
>(
this + 1); }
 
  132       __atomic_add_dispatch(&_M_info._M_refcount, 1);
 
  137     _M_set_length(size_type __n)
 
  139       _M_info._M_refcount = 0;  
 
  140       _M_info._M_length = __n;
 
  143       traits_type::assign(_M_refdata()[__n], _CharT());
 
  148     _S_create(size_type, size_type, 
const _Alloc&);
 
  151     _M_destroy(
const _Alloc&) 
throw();
 
  154     _M_clone(
const _Alloc&, size_type __res = 0);
 
  163       static _Rep_empty     _S_empty_rep;
 
  178       enum { _S_max_size = (((
static_cast<size_type
>(-1) - 2 * 
sizeof(_Rep)
 
  179                   + 1) / 
sizeof(_CharT)) - 1) / 2 };
 
  182       mutable typename _Util_Base::template _Alloc_hider<_Alloc>  _M_dataplus;
 
  186       { _M_dataplus._M_p = __p; }
 
  190       { 
return &((
reinterpret_cast<_Rep*
>(_M_data()))[-1]); }
 
  193       _M_grab(
const _Alloc& __alloc)
 const 
  195     return (!_M_is_leaked() && _M_get_allocator() == __alloc)
 
  196         ? _M_rep()->_M_refcopy() : _M_rep()->_M_clone(__alloc);
 
  203     _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_rep()->_M_info.
 
  205     if (__exchange_and_add_dispatch(&_M_rep()->_M_info._M_refcount,
 
  208         _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_rep()->_M_info.
 
  210         _M_rep()->_M_destroy(_M_get_allocator());
 
  216       { 
return _M_rep()->_M_info._M_refcount < 0; }
 
  220       { _M_rep()->_M_info._M_refcount = 0; }
 
  227       template<
typename _InIterator>
 
  229     _S_construct_aux(_InIterator __beg, _InIterator __end,
 
  230              const _Alloc& __a, std::__false_type)
 
  232       typedef typename iterator_traits<_InIterator>::iterator_category _Tag;
 
  233       return _S_construct(__beg, __end, __a, _Tag());
 
  238       template<
typename _Integer>
 
  240     _S_construct_aux(_Integer __beg, _Integer __end,
 
  241              const _Alloc& __a, std::__true_type)
 
  242     { 
return _S_construct_aux_2(static_cast<size_type>(__beg),
 
  246       _S_construct_aux_2(size_type __req, _CharT __c, 
const _Alloc& __a)
 
  247       { 
return _S_construct(__req, __c, __a); }
 
  249       template<
typename _InIterator>
 
  251     _S_construct(_InIterator __beg, _InIterator __end, 
const _Alloc& __a)
 
  253       typedef typename std::__is_integer<_InIterator>::__type _Integral;
 
  254       return _S_construct_aux(__beg, __end, __a, _Integral());
 
  258       template<
typename _InIterator>
 
  260      _S_construct(_InIterator __beg, _InIterator __end, 
const _Alloc& __a,
 
  265       template<
typename _FwdIterator>
 
  267     _S_construct(_FwdIterator __beg, _FwdIterator __end, 
const _Alloc& __a,
 
  271       _S_construct(size_type __req, _CharT __c, 
const _Alloc& __a);
 
  276       { 
return size_type(_S_max_size); }
 
  280       { 
return _M_dataplus._M_p; }
 
  284       { 
return _M_rep()->_M_info._M_length; }
 
  288       { 
return _M_rep()->_M_info._M_capacity; }
 
  292       { 
return _M_rep()->_M_info._M_refcount > 0; }
 
  296       { _M_rep()->_M_info._M_refcount = -1; }
 
  306       _M_set_length(size_type __n)
 
  307       { _M_rep()->_M_set_length(__n); }
 
  310       : _M_dataplus(_S_empty_rep._M_refcopy()) { }
 
  316 #if __cplusplus >= 201103L 
  318       : _M_dataplus(__rcs._M_dataplus)
 
  319       { __rcs._M_data(_S_empty_rep._M_refcopy()); }
 
  324       template<
typename _InputIterator>
 
  333       { 
return _M_dataplus; }
 
  335       const allocator_type&
 
  336       _M_get_allocator()
 const 
  337       { 
return _M_dataplus; }
 
  346       _M_reserve(size_type __res);
 
  349       _M_mutate(size_type __pos, size_type __len1, 
const _CharT* __s,
 
  353       _M_erase(size_type __pos, size_type __n);
 
  357       { _M_erase(size_type(0), _M_length()); }
 
  364   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  368   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  371     _S_create(size_type __capacity, size_type __old_capacity,
 
  372           const _Alloc& __alloc)
 
  376       if (__capacity > size_type(_S_max_size))
 
  377     std::__throw_length_error(__N(
"__rc_string_base::_Rep::_S_create"));
 
  402       const size_type __pagesize = 4096;
 
  403       const size_type __malloc_header_size = 4 * 
sizeof(
void*);
 
  408       if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
 
  410       __capacity = 2 * __old_capacity;
 
  412       if (__capacity > size_type(_S_max_size))
 
  413         __capacity = size_type(_S_max_size);
 
  421       size_type __size = ((__capacity + 1) * 
sizeof(_CharT)
 
  422               + 2 * 
sizeof(_Rep) - 1);
 
  424       const size_type __adj_size = __size + __malloc_header_size;
 
  425       if (__adj_size > __pagesize && __capacity > __old_capacity)
 
  427       const size_type __extra = __pagesize - __adj_size % __pagesize;
 
  428       __capacity += __extra / 
sizeof(_CharT);
 
  429       if (__capacity > size_type(_S_max_size))
 
  430         __capacity = size_type(_S_max_size);
 
  431       __size = (__capacity + 1) * 
sizeof(_CharT) + 2 * 
sizeof(_Rep) - 1;
 
  436       _Rep* __place = _Rep_alloc_type(__alloc).allocate(__size / 
sizeof(_Rep));
 
  437       _Rep* __p = 
new (__place) _Rep;
 
  438       __p->_M_info._M_capacity = __capacity;
 
  442   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  444     __rc_string_base<_CharT, _Traits, _Alloc>::_Rep::
 
  445     _M_destroy(
const _Alloc& __a) 
throw ()
 
  447       const size_type __size = ((_M_info._M_capacity + 1) * 
sizeof(_CharT)
 
  448                 + 2 * 
sizeof(_Rep) - 1);
 
  449       _Rep_alloc_type(__a).deallocate(
this, __size / 
sizeof(_Rep));
 
  452   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  454     __rc_string_base<_CharT, _Traits, _Alloc>::_Rep::
 
  455     _M_clone(
const _Alloc& __alloc, size_type __res)
 
  458       const size_type __requested_cap = _M_info._M_length + __res;
 
  459       _Rep* __r = _Rep::_S_create(__requested_cap, _M_info._M_capacity,
 
  462       if (_M_info._M_length)
 
  463     __rc_string_base::_S_copy(__r->_M_refdata(), _M_refdata(), _M_info._M_length);
 
  465       __r->_M_set_length(_M_info._M_length);
 
  466       return __r->_M_refdata();
 
  469   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  470     __rc_string_base<_CharT, _Traits, _Alloc>::
 
  471     __rc_string_base(
const _Alloc& __a)
 
  472     : _M_dataplus(__a, _S_construct(size_type(), _CharT(), __a)) { }
 
  474   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  475     __rc_string_base<_CharT, _Traits, _Alloc>::
 
  476     __rc_string_base(
const __rc_string_base& __rcs)
 
  477     : _M_dataplus(__rcs._M_get_allocator(),
 
  478           __rcs._M_grab(__rcs._M_get_allocator())) { }
 
  480   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  481     __rc_string_base<_CharT, _Traits, _Alloc>::
 
  482     __rc_string_base(size_type __n, _CharT __c, 
const _Alloc& __a)
 
  483     : _M_dataplus(__a, _S_construct(__n, __c, __a)) { }
 
  485   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  486     template<
typename _InputIterator>
 
  487     __rc_string_base<_CharT, _Traits, _Alloc>::
 
  488     __rc_string_base(_InputIterator __beg, _InputIterator __end,
 
  490     : _M_dataplus(__a, _S_construct(__beg, __end, __a)) { }
 
  492   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  494     __rc_string_base<_CharT, _Traits, _Alloc>::
 
  506   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  507     template<
typename _InIterator>
 
  509       __rc_string_base<_CharT, _Traits, _Alloc>::
 
  510       _S_construct(_InIterator __beg, _InIterator __end, 
const _Alloc& __a,
 
  513     if (__beg == __end && __a == _Alloc())
 
  514       return _S_empty_rep._M_refcopy();
 
  519     while (__beg != __end && __len < 
sizeof(__buf) / 
sizeof(_CharT))
 
  521         __buf[__len++] = *__beg;
 
  524     _Rep* __r = _Rep::_S_create(__len, size_type(0), __a);
 
  525     _S_copy(__r->_M_refdata(), __buf, __len);
 
  528         while (__beg != __end)
 
  530         if (__len == __r->_M_info._M_capacity)
 
  533             _Rep* __another = _Rep::_S_create(__len + 1, __len, __a);
 
  534             _S_copy(__another->_M_refdata(), __r->_M_refdata(), __len);
 
  535             __r->_M_destroy(__a);
 
  538         __r->_M_refdata()[__len++] = *__beg;
 
  544         __r->_M_destroy(__a);
 
  545         __throw_exception_again;
 
  547     __r->_M_set_length(__len);
 
  548     return __r->_M_refdata();
 
  551   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  552     template<
typename _InIterator>
 
  554       __rc_string_base<_CharT, _Traits, _Alloc>::
 
  555       _S_construct(_InIterator __beg, _InIterator __end, 
const _Alloc& __a,
 
  558     if (__beg == __end && __a == _Alloc())
 
  559       return _S_empty_rep._M_refcopy();
 
  562     if (__is_null_pointer(__beg) && __beg != __end)
 
  563       std::__throw_logic_error(__N(
"__rc_string_base::" 
  564                        "_S_construct null not valid"));
 
  566     const size_type __dnew = 
static_cast<size_type
>(
std::distance(__beg,
 
  569     _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a);
 
  571       { __rc_string_base::_S_copy_chars(__r->_M_refdata(), __beg, __end); }
 
  574         __r->_M_destroy(__a);
 
  575         __throw_exception_again;
 
  577     __r->_M_set_length(__dnew);
 
  578     return __r->_M_refdata();
 
  581   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  583     __rc_string_base<_CharT, _Traits, _Alloc>::
 
  584     _S_construct(size_type __n, _CharT __c, 
const _Alloc& __a)
 
  586       if (__n == 0 && __a == _Alloc())
 
  587     return _S_empty_rep._M_refcopy();
 
  590       _Rep* __r = _Rep::_S_create(__n, size_type(0), __a);
 
  592     __rc_string_base::_S_assign(__r->_M_refdata(), __n, __c);
 
  594       __r->_M_set_length(__n);
 
  595       return __r->_M_refdata();
 
  598   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  600     __rc_string_base<_CharT, _Traits, _Alloc>::
 
  601     _M_swap(__rc_string_base& __rcs)
 
  605       if (__rcs._M_is_leaked())
 
  606     __rcs._M_set_sharable();
 
  608       _CharT* __tmp = _M_data();
 
  609       _M_data(__rcs._M_data());
 
  610       __rcs._M_data(__tmp);
 
  614       std::__alloc_swap<allocator_type>::_S_do_it(_M_get_allocator(),
 
  615                           __rcs._M_get_allocator());
 
  618   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  620     __rc_string_base<_CharT, _Traits, _Alloc>::
 
  621     _M_assign(
const __rc_string_base& __rcs)
 
  623       if (_M_rep() != __rcs._M_rep())
 
  625       _CharT* __tmp = __rcs._M_grab(_M_get_allocator());
 
  631   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  633     __rc_string_base<_CharT, _Traits, _Alloc>::
 
  634     _M_reserve(size_type __res)
 
  637       if (__res < _M_length())
 
  640       if (__res != _M_capacity() || _M_is_shared())
 
  642       _CharT* __tmp = _M_rep()->_M_clone(_M_get_allocator(),
 
  643                          __res - _M_length());
 
  649   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  651     __rc_string_base<_CharT, _Traits, _Alloc>::
 
  652     _M_mutate(size_type __pos, size_type __len1, 
const _CharT* __s,
 
  655       const size_type __how_much = _M_length() - __pos - __len1;
 
  657       _Rep* __r = _Rep::_S_create(_M_length() + __len2 - __len1,
 
  658                   _M_capacity(), _M_get_allocator());
 
  661     this->_S_copy(__r->_M_refdata(), _M_data(), __pos);
 
  663     this->_S_copy(__r->_M_refdata() + __pos, __s, __len2);
 
  665     this->_S_copy(__r->_M_refdata() + __pos + __len2,
 
  666         _M_data() + __pos + __len1, __how_much);
 
  669       _M_data(__r->_M_refdata());
 
  672   template<
typename _CharT, 
typename _Traits, 
typename _Alloc>
 
  674     __rc_string_base<_CharT, _Traits, _Alloc>::
 
  675     _M_erase(size_type __pos, size_type __n)
 
  677       const size_type __new_size = _M_length() - __n;
 
  678       const size_type __how_much = _M_length() - __pos - __n;
 
  683       _Rep* __r = _Rep::_S_create(__new_size, _M_capacity(),
 
  687         this->_S_copy(__r->_M_refdata(), _M_data(), __pos);
 
  689         this->_S_copy(__r->_M_refdata() + __pos,
 
  690             _M_data() + __pos + __n, __how_much);
 
  693       _M_data(__r->_M_refdata());
 
  695       else if (__how_much && __n)
 
  698       this->_S_move(_M_data() + __pos,
 
  699           _M_data() + __pos + __n, __how_much);
 
  702       _M_rep()->_M_set_length(__new_size);
 
  707     __rc_string_base<char, std::char_traits<char>,
 
  709     _M_compare(
const __rc_string_base& __rcs)
 const 
  711       if (_M_rep() == __rcs._M_rep())
 
  716 #ifdef _GLIBCXX_USE_WCHAR_T 
  719     __rc_string_base<wchar_t, std::char_traits<wchar_t>,
 
  721     _M_compare(
const __rc_string_base& __rcs)
 const 
  723       if (_M_rep() == __rcs._M_rep())
 
  729 _GLIBCXX_END_NAMESPACE_VERSION
 
GNU extensions for public use. 
Forward iterators support a superset of input iterator operations. 
iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic. 
The standard allocator, as per [20.4].