Remove buffer_move_or_copy usage and reformat devector.

This commit is contained in:
Ion Gaztañaga
2026-01-02 18:30:02 +01:00
parent 84d9a29107
commit 0a0ea3e694

View File

@@ -279,8 +279,9 @@ class devector
explicit devector(size_type n, const allocator_type& allocator = allocator_type())
: m_(reserve_uninitialized_t(), allocator, n)
{
allocation_guard buffer_guard(m_.buffer, m_.capacity, get_allocator_ref());
boost::container::uninitialized_value_init_alloc_n(get_allocator_ref(), n, this->priv_raw_begin());
allocator_type &al = this->get_allocator_ref();
allocation_guard buffer_guard(m_.buffer, m_.capacity, al);
boost::container::uninitialized_value_init_alloc_n(al, n, this->priv_raw_begin());
buffer_guard.release();
BOOST_ASSERT(invariants_ok());
}
@@ -299,8 +300,9 @@ class devector
explicit devector(size_type n, default_init_t, const allocator_type& allocator = allocator_type())
: m_(reserve_uninitialized_t(), allocator, n)
{
allocation_guard buffer_guard(m_.buffer, m_.capacity, get_allocator_ref());
boost::container::uninitialized_default_init_alloc_n(get_allocator_ref(), n, this->priv_raw_begin());
allocator_type &al = this->get_allocator_ref();
allocation_guard buffer_guard(m_.buffer, m_.capacity, al);
boost::container::uninitialized_default_init_alloc_n(al, n, this->priv_raw_begin());
buffer_guard.release();
BOOST_ASSERT(invariants_ok());
}
@@ -544,10 +546,10 @@ class devector
size_type n = x.size();
if (m_.capacity >= n) {
this->overwrite_buffer(x.begin(), x.end());
this->overwrite_buffer(x.begin(), x.end());
}
else {
this->allocate_and_copy_range(x.begin(), x.end());
this->allocate_and_copy_range(x.begin(), x.end());
}
BOOST_ASSERT(invariants_ok());
@@ -1758,11 +1760,12 @@ class devector
else{
iterator nonconst_pos = unconst_iterator(position);
prefer_move_back = should_move_back(position);
allocator_type &al = this->get_allocator_ref();
if(prefer_move_back){
if(back_free_capacity()){
boost::container::expand_forward_and_insert_nonempty_middle_alloc
( get_allocator_ref()
( al
, boost::movelib::to_raw_pointer(nonconst_pos)
, this->priv_raw_end()
, 1, proxy_t(::boost::forward<Args>(args)...));
@@ -1773,7 +1776,7 @@ class devector
else{
if (front_free_capacity()){
boost::container::expand_backward_and_insert_nonempty_middle_alloc
(get_allocator_ref()
(al
, this->priv_raw_begin()
, boost::movelib::to_raw_pointer(nonconst_pos)
, 1, proxy_t(::boost::forward<Args>(args)...));
@@ -1818,11 +1821,12 @@ class devector
else{\
iterator nonconst_pos = unconst_iterator(position);\
prefer_move_back = should_move_back(position);\
allocator_type &al = this->get_allocator_ref();\
\
if(prefer_move_back){\
if(back_free_capacity()){\
boost::container::expand_forward_and_insert_nonempty_middle_alloc\
( get_allocator_ref()\
( al\
, boost::movelib::to_raw_pointer(nonconst_pos)\
, this->priv_raw_end()\
, 1, proxy_t(BOOST_MOVE_FWD##N));\
@@ -1833,7 +1837,7 @@ class devector
else{\
if (front_free_capacity()){\
boost::container::expand_backward_and_insert_nonempty_middle_alloc\
(get_allocator_ref()\
(al\
, this->priv_raw_begin()\
, boost::movelib::to_raw_pointer(nonconst_pos)\
, 1, proxy_t(BOOST_MOVE_FWD##N));\
@@ -2076,13 +2080,11 @@ class devector
size_type back_distance = size_type(end() - first);
size_type n = boost::container::iterator_udistance(first, last);
if (front_distance < back_distance)
{
if (front_distance < back_distance) {
// move n to the right
boost::container::move_backward(begin(), first, last);
for (iterator i = begin(); i != begin() + n; ++i)
{
for (iterator i = begin(); i != begin() + n; ++i) {
allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(i));
}
//n is always less than max stored_size_type
@@ -2406,31 +2408,6 @@ class devector
return growth_factor_type()( size_type(m_.capacity), min_additional_cap, max);
}
void buffer_move_or_copy(pointer dst)
{
detail::construction_guard<allocator_type> guard(dst, get_allocator_ref());
buffer_move_or_copy(dst, guard);
guard.release();
}
void buffer_move_or_copy(pointer dst, detail::construction_guard<allocator_type>& guard)
{
opt_move_or_copy(begin(), end(), dst, guard);
destroy_elements(data(), data() + size());
deallocate_buffer();
}
template <typename Guard>
void opt_move_or_copy(pointer b, pointer e, pointer dst, Guard& guard)
{
// if trivial copy and default allocator, memcpy
boost::container::uninitialized_move_alloc(get_allocator_ref(), b, e, dst);
guard.extend();
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template <typename... Args>
@@ -2497,18 +2474,25 @@ class devector
template <typename... Args>
void resize_front_slow_path(size_type sz, size_type n, Args&&... args)
{
const size_type new_capacity = calculate_new_capacity(sz + back_free_capacity());
const size_type back_free_cap = back_free_capacity();
const size_type new_capacity = calculate_new_capacity(sz + back_free_cap);
pointer new_buffer = allocate(new_capacity);
allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());
const size_type old_sz = this->size();
const size_type new_old_elem_index = new_capacity - old_sz;
allocator_type &al = this->get_allocator_ref();
allocation_guard new_buffer_guard(new_buffer, new_capacity, al);
const size_type new_old_elem_index = new_capacity - this->size() - back_free_cap;
const size_type new_elem_index = new_old_elem_index - n;
detail::construction_guard<allocator_type> guard(new_buffer + new_elem_index, get_allocator_ref());
detail::construction_guard<allocator_type> guard(new_buffer + new_elem_index, al);
guarded_construct_n(new_buffer + new_elem_index, n, guard, boost::forward<Args>(args)...);
buffer_move_or_copy(new_buffer + new_old_elem_index, guard);
//This might throw
boost::container::uninitialized_move_alloc(al, begin(), end(), new_buffer + new_old_elem_index);
//This can't throw
this->destroy_elements(data(), data() + size());
this->deallocate_buffer();
guard.release();
new_buffer_guard.release();
@@ -2516,7 +2500,7 @@ class devector
m_.buffer = new_buffer;
m_.set_capacity(new_capacity);
m_.set_front_idx(new_elem_index);
m_.set_back_idx(new_elem_index + old_sz + n);
m_.set_back_idx(new_elem_index + sz);
}
template <typename... Args>
@@ -2551,12 +2535,19 @@ class devector
{
const size_type new_capacity = calculate_new_capacity(sz + front_free_capacity());
pointer new_buffer = allocate(new_capacity);
allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());
detail::construction_guard<allocator_type> guard(new_buffer + m_.back_idx, get_allocator_ref());
allocator_type &al = this->get_allocator_ref();
allocation_guard new_buffer_guard(new_buffer, new_capacity, al);
detail::construction_guard<allocator_type> guard(new_buffer + m_.back_idx, al);
guarded_construct_n(new_buffer + m_.back_idx, n, guard, boost::forward<Args>(args)...);
buffer_move_or_copy(new_buffer + m_.front_idx);
//This might throw
boost::container::uninitialized_move_alloc(al, begin(), end(), new_buffer + m_.front_idx);
//This can't throw
this->destroy_elements(data(), data() + size());
this->deallocate_buffer();
guard.release();
new_buffer_guard.release();
@@ -2595,24 +2586,30 @@ class devector
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
void resize_front_slow_path(size_type sz, size_type n BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
const size_type new_capacity = calculate_new_capacity(sz + back_free_capacity());\
const size_type back_free_cap = back_free_capacity();\
const size_type new_capacity = calculate_new_capacity(sz + back_free_cap);\
pointer new_buffer = allocate(new_capacity);\
allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());\
\
const size_type new_old_elem_index = new_capacity - size();\
allocator_type &al = this->get_allocator_ref();\
allocation_guard new_buffer_guard(new_buffer, new_capacity, al);\
\
const size_type new_old_elem_index = new_capacity - size() - back_free_cap;\
const size_type new_elem_index = new_old_elem_index - n;\
\
detail::construction_guard<allocator_type> guard(new_buffer + new_elem_index, get_allocator_ref());\
\
detail::construction_guard<allocator_type> guard(new_buffer + new_elem_index, al);\
guarded_construct_n(new_buffer + new_elem_index, n, guard BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
\
buffer_move_or_copy(new_buffer + new_old_elem_index, guard);\
\
\
boost::container::uninitialized_move_alloc(al, begin(), end(), new_buffer + new_old_elem_index);\
\
guard.release();\
new_buffer_guard.release();\
\
this->destroy_elements(data(), data() + size());\
this->deallocate_buffer();\
\
m_.buffer = new_buffer;\
m_.set_capacity(new_capacity);\
m_.set_back_idx(new_old_elem_index + m_.back_idx - m_.front_idx);\
m_.set_front_idx(new_elem_index);\
m_.set_back_idx(new_elem_index + sz);\
}\
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
@@ -2646,12 +2643,16 @@ class devector
{\
const size_type new_capacity = calculate_new_capacity(sz + front_free_capacity());\
pointer new_buffer = allocate(new_capacity);\
allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());\
allocator_type &al = this->get_allocator_ref();\
allocation_guard new_buffer_guard(new_buffer, new_capacity, al);\
\
detail::construction_guard<allocator_type> guard(new_buffer + m_.back_idx, get_allocator_ref());\
detail::construction_guard<allocator_type> guard(new_buffer + m_.back_idx, al);\
guarded_construct_n(new_buffer + m_.back_idx, n, guard BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
\
buffer_move_or_copy(new_buffer + m_.front_idx);\
boost::container::uninitialized_move_alloc(al, begin(), end(), new_buffer + m_.front_idx);\
\
this->destroy_elements(data(), data() + size());\
this->deallocate_buffer();\
\
guard.release();\
new_buffer_guard.release();\
@@ -2671,8 +2672,9 @@ class devector
{
pointer new_buffer = allocate(new_capacity);
{
allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());
boost::container::uninitialized_move_alloc(get_allocator_ref(), this->begin(), this->end(), new_buffer + buffer_offset);
allocator_type &al = this->get_allocator_ref();
allocation_guard new_buffer_guard(new_buffer, new_capacity, al);
boost::container::uninitialized_move_alloc(al, this->begin(), this->end(), new_buffer + buffer_offset);
new_buffer_guard.release();
}
this->destroy_elements(m_.buffer + m_.front_idx, m_.buffer + m_.back_idx);
@@ -2696,6 +2698,8 @@ class devector
size_type const n = boost::container::iterator_udistance(first, last);
bool prefer_move_back;
allocator_type &al = this->get_allocator_ref();
if (BOOST_UNLIKELY(!n)) {
return begin() + size_type(position - cbegin());
}
@@ -2703,7 +2707,7 @@ class devector
if(back_free_capacity() >= n) // fast path
{
iterator r(this->end());
boost::container::uninitialized_copy_alloc(get_allocator_ref(), first, last, this->priv_raw_end());
boost::container::uninitialized_copy_alloc(al, first, last, this->priv_raw_end());
m_.set_back_idx(m_.back_idx + n);
return r;
}
@@ -2711,7 +2715,7 @@ class devector
}
else if (position == begin()) {
if(front_free_capacity() >= n) {// secondary fast path
boost::container::uninitialized_copy_alloc(get_allocator_ref(), first, last, this->priv_raw_begin() - n);
boost::container::uninitialized_copy_alloc(al, first, last, this->priv_raw_begin() - n);
m_.set_front_idx(m_.front_idx - n);
return begin();
}
@@ -2724,7 +2728,7 @@ class devector
if(prefer_move_back){
if(back_free_capacity() >= n){
boost::container::expand_forward_and_insert_nonempty_middle_alloc
( get_allocator_ref()
( al
, boost::movelib::to_raw_pointer(nonconst_pos)
, this->priv_raw_end()
, n, proxy_t(first));
@@ -2735,7 +2739,7 @@ class devector
else{
if (front_free_capacity() >= n){
boost::container::expand_backward_and_insert_nonempty_middle_alloc
( get_allocator_ref()
( al
, this->priv_raw_begin()
, boost::movelib::to_raw_pointer(nonconst_pos)
, n, proxy_t(first));
@@ -2757,6 +2761,8 @@ class devector
size_type const index = size_type(p - cbegin());
size_type const cap = m_.capacity;
allocator_type &al = this->get_allocator_ref();
//Test if enough free memory would be left
if (free_cap >= n && (free_cap - n) >= cap/devector_min_free_fraction) {
size_type const old_size = this->size();
@@ -2769,7 +2775,7 @@ class devector
m_.back_idx = 0u;
m_.front_idx = 0u;
boost::container::expand_backward_forward_and_insert_alloc
(raw_beg, old_size, new_raw_beg, raw_pos, n, proxy, get_allocator_ref());
(raw_beg, old_size, new_raw_beg, raw_pos, n, proxy, al);
m_.set_front_idx(new_front_idx);
m_.set_back_idx(new_front_idx + new_size);
}
@@ -2779,7 +2785,7 @@ class devector
pointer new_buffer = allocate(new_capacity);
// guard allocation
allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());
allocation_guard new_buffer_guard(new_buffer, new_capacity, al);
size_type const old_size = this->size();
const size_type new_front_index = (new_capacity - old_size - n) / 2u;
@@ -2788,7 +2794,7 @@ class devector
T* const raw_new_start = const_cast<T*>(boost::movelib::to_raw_pointer(new_buffer)) + new_front_index;
boost::container::uninitialized_move_and_insert_alloc
(get_allocator_ref(), this->priv_raw_begin(), raw_pos, this->priv_raw_end(), raw_new_start, n, proxy);
(al, this->priv_raw_begin(), raw_pos, this->priv_raw_end(), raw_new_start, n, proxy);
new_buffer_guard.release();
// cleanup
@@ -2819,8 +2825,9 @@ class devector
size_type n = boost::container::iterator_udistance(first, last);
pointer new_buffer = n ? allocate(n) : pointer();
allocation_guard new_buffer_guard(new_buffer, n, get_allocator_ref());
boost::container::uninitialized_copy_alloc(get_allocator_ref(), first, last, new_buffer);
allocator_type &al = this->get_allocator_ref();
allocation_guard new_buffer_guard(new_buffer, n, al);
boost::container::uninitialized_copy_alloc(al, first, last, new_buffer);
this->destroy_elements(begin(), end());
this->deallocate_buffer();
@@ -2855,7 +2862,8 @@ class devector
InputIterator overwrite_buffer_impl(InputIterator first, InputIterator last, dtl::false_)
{
pointer pos = m_.buffer;
detail::construction_guard<allocator_type> front_guard(pos, get_allocator_ref());
allocator_type &al = this->get_allocator_ref();
detail::construction_guard<allocator_type> front_guard(pos, al);
while (first != last && pos != begin()) {
this->alloc_construct(pos++, *first++);
@@ -2866,7 +2874,7 @@ class devector
*pos++ = *first++;
}
detail::construction_guard<allocator_type> back_guard(pos, get_allocator_ref());
detail::construction_guard<allocator_type> back_guard(pos, al);
iterator capacity_end = m_.buffer + m_.capacity;
while (first != last && pos != capacity_end) {