Alien-boost-mini
view release on metacpan or search on metacpan
include/boost/container/string.hpp view on Meta::CPAN
const Allocator &alloc() const
{ return members_; }
Allocator &alloc()
{ return members_; }
static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type);
private:
static const size_type MinAllocation = InternalBufferChars*2;
protected:
bool is_short() const
{
//Access and copy (to avoid UB) the first byte of the union to know if the
//active representation is short or long
short_header hdr;
BOOST_STATIC_ASSERT((sizeof(short_header) == 1));
*(unsigned char*)&hdr = *(unsigned char*)&this->members_.m_repr;
return hdr.is_short != 0;
}
void is_short(bool yes)
{
const bool was_short = this->is_short();
if(yes && !was_short){
allocator_traits_type::destroy
( this->alloc()
, static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))
);
this->members_.m_repr.s.h.is_short = true;
}
else if(!yes && was_short){
allocator_traits_type::construct
( this->alloc()
, static_cast<long_t*>(static_cast<void*>(&this->members_.m_repr.r))
);
this->members_.m_repr.s.h.is_short = false;
}
}
private:
void init()
{
this->members_.m_repr.s.h.is_short = 1;
this->members_.m_repr.s.h.length = 0;
}
protected:
typedef dtl::integral_constant<unsigned,
boost::container::dtl::version<Allocator>::value> alloc_version;
pointer allocation_command(allocation_type command,
size_type limit_size,
size_type &prefer_in_recvd_out_size,
pointer &reuse)
{
if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){
reuse = 0;
command &= ~(expand_fwd | expand_bwd);
}
return dtl::allocator_version_traits<Allocator>::allocation_command
(this->alloc(), command, limit_size, prefer_in_recvd_out_size, reuse);
}
size_type next_capacity(size_type additional_objects) const
{
return growth_factor_100()
( this->priv_storage(), additional_objects, allocator_traits_type::max_size(this->alloc()));
}
void deallocate(pointer p, size_type n)
{
if (p && (n > InternalBufferChars))
this->alloc().deallocate(p, n);
}
void construct(pointer p, const value_type &value = value_type())
{
allocator_traits_type::construct
( this->alloc()
, boost::movelib::to_raw_pointer(p)
, value
);
}
void destroy(pointer p, size_type n)
{
value_type *raw_p = boost::movelib::to_raw_pointer(p);
for(; n--; ++raw_p){
allocator_traits_type::destroy( this->alloc(), raw_p);
}
}
void destroy(pointer p)
{
allocator_traits_type::destroy
( this->alloc()
, boost::movelib::to_raw_pointer(p)
);
}
void allocate_initial_block(size_type n)
{
if (n <= this->max_size()) {
if(n > InternalBufferChars){
size_type new_cap = this->next_capacity(n);
pointer reuse = 0;
pointer p = this->allocation_command(allocate_new, n, new_cap, reuse);
this->is_short(false);
this->priv_long_addr(p);
this->priv_long_size(0);
this->priv_storage(new_cap);
}
}
else{
throw_length_error("basic_string::allocate_initial_block max_size() exceeded");
}
}
include/boost/container/string.hpp view on Meta::CPAN
return this->priv_addr() + new_offset;
}
//! <b>Requires</b>: p is a valid iterator on *this.
//!
//! <b>Effects</b>: Inserts n copies of c before the character referred to by p.
//!
//! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
iterator insert(const_iterator p, size_type n, CharT c)
{ return this->insert(p, cvalue_iterator(c, n), cvalue_iterator()); }
//! <b>Requires</b>: p is a valid iterator on *this. [first,last) is a valid range.
//!
//! <b>Effects</b>: Equivalent to insert(p - begin(), basic_string(first, last)).
//!
//! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
template <class InputIter>
iterator insert(const_iterator p, InputIter first, InputIter last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename dtl::disable_if_or
< void
, dtl::is_convertible<InputIter, size_type>
, dtl::is_not_input_iterator<InputIter>
>::type * = 0
#endif
)
{
const size_type n_pos = p - this->cbegin();
for ( ; first != last; ++first, ++p) {
p = this->insert(p, *first);
}
return this->begin() + n_pos;
}
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template <class ForwardIter>
iterator insert(const_iterator p, ForwardIter first, ForwardIter last
, typename dtl::disable_if_or
< void
, dtl::is_convertible<ForwardIter, size_type>
, dtl::is_input_iterator<ForwardIter>
>::type * = 0
)
{
const size_type n_pos = p - this->cbegin();
if (first != last) {
const size_type n = boost::container::iterator_distance(first, last);
const size_type old_size = this->priv_size();
const size_type remaining = this->capacity() - old_size;
const pointer old_start = this->priv_addr();
bool enough_capacity = false;
size_type new_cap = 0;
//Check if we have enough capacity
pointer hint = pointer();
pointer allocation_ret = pointer();
if (remaining >= n){
enough_capacity = true;
}
else {
//Otherwise expand current buffer or allocate new storage
new_cap = this->next_capacity(n);
hint = old_start;
allocation_ret = this->allocation_command
(allocate_new | expand_fwd | expand_bwd, old_size + n + 1, new_cap, hint);
//Check forward expansion
if(old_start == allocation_ret){
enough_capacity = true;
this->priv_storage(new_cap);
}
}
//Reuse same buffer
if(enough_capacity){
const size_type elems_after = old_size - (p - old_start);
const size_type old_length = old_size;
if (elems_after >= n) {
const pointer pointer_past_last = old_start + old_size + 1;
priv_uninitialized_copy(old_start + (old_size - n + 1),
pointer_past_last, pointer_past_last);
this->priv_size(old_size+n);
Traits::move(const_cast<CharT*>(boost::movelib::to_raw_pointer(p + n)),
boost::movelib::to_raw_pointer(p),
(elems_after - n) + 1);
this->priv_copy(first, last, const_cast<CharT*>(boost::movelib::to_raw_pointer(p)));
}
else {
ForwardIter mid = first;
boost::container::iterator_advance(mid, elems_after + 1);
priv_uninitialized_copy(mid, last, old_start + old_size + 1);
const size_type newer_size = old_size + (n - elems_after);
this->priv_size(newer_size);
priv_uninitialized_copy
(p, const_iterator(old_start + old_length + 1),
old_start + newer_size);
this->priv_size(newer_size + elems_after);
this->priv_copy(first, mid, const_cast<CharT*>(boost::movelib::to_raw_pointer(p)));
}
}
else{
pointer new_start = allocation_ret;
if(!hint){
//Copy data to new buffer
size_type new_length = 0;
//This can't throw, since characters are POD
new_length += priv_uninitialized_copy
(const_iterator(old_start), p, new_start);
new_length += priv_uninitialized_copy
(first, last, new_start + new_length);
new_length += priv_uninitialized_copy
(p, const_iterator(old_start + old_size),
new_start + new_length);
this->priv_construct_null(new_start + new_length);
this->deallocate_block();
this->is_short(false);
this->priv_long_addr(new_start);
this->priv_long_size(new_length);
this->priv_long_storage(new_cap);
}
else{
//value_type is POD, so backwards expansion is much easier
( run in 1.324 second using v1.01-cache-2.11-cpan-5b529ec07f3 )