Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 37 additions & 21 deletions include/fast_io_dsal/impl/deque.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ struct deque_iterator
decltype(curr_ptr) beginptr;
if (pos < 0)
{
size_type diff{static_cast<size_type>(this->itercontent.end_ptr - curr_ptr)};
size_type diff{static_cast<size_type>(this->itercontent.end_ptr - curr_ptr) - 1u};
constexpr size_type zero{};
size_type abspos{static_cast<size_type>(zero - unsignedpos)};
diff += abspos;
Expand Down Expand Up @@ -183,7 +183,7 @@ struct deque_iterator
}
else
{
size_type diff{static_cast<size_type>(this->itercontent.end_ptr - curr_ptr)};
size_type diff{static_cast<size_type>(this->itercontent.end_ptr - curr_ptr) - 1u};
diff += unsignedpos;
this->itercontent.curr_ptr = (beginptr = *(controllerptr -= diff / blocksize)) + (blocksizem1 - diff % blocksize);
}
Expand Down Expand Up @@ -246,7 +246,7 @@ inline constexpr ::std::ptrdiff_t deque_iter_difference_common(::fast_io::contai
{
::std::ptrdiff_t controllerdiff{a.controller_ptr - b.controller_ptr};
constexpr ::std::ptrdiff_t blocksizedf{static_cast<::std::ptrdiff_t>(::fast_io::containers::details::deque_block_size<sizeof(T)>)};
return controllerdiff * blocksizedf + (a.curr_ptr - b.begin_ptr) + (b.begin_ptr - b.curr_ptr);
return controllerdiff * blocksizedf + (a.curr_ptr - a.begin_ptr) - (b.curr_ptr - b.begin_ptr);
}

template <typename T, bool isconst1, bool isconst2>
Expand Down Expand Up @@ -282,10 +282,11 @@ inline constexpr void deque_destroy_controller(controllerblocktype *controllerpt
}
else
{
::std::size_t n{static_cast<::std::size_t>(controller.controller_after_ptr - controller.controller_start_ptr) * sizeof(void *)};
// `controller_after_ptr` points at the extra sentinel slot (allocated). Include it in sized deallocation.
::std::size_t n{(static_cast<::std::size_t>(controller.controller_after_ptr - controller.controller_start_ptr) + 1u) * sizeof(void *)};
allocator::deallocate_n(controller.controller_start_ptr, n);
}

controller.controller_start_ptr = nullptr;
}

Expand Down Expand Up @@ -357,13 +358,17 @@ inline constexpr void deque_init_grow_common_controllerallocate_impl(dequecontro
template <typename allocator, typename dequecontroltype>
inline constexpr void deque_init_grow_common_noalign_impl(dequecontroltype &controller, ::std::size_t total_block_size, ::std::size_t mid) noexcept
{
::fast_io::containers::details::deque_init_grow_common_controllerallocate_impl<allocator>(controller, total_block_size, mid, static_cast<typename dequecontroltype::replacetype *>(allocator::allocate_zero(total_block_size)));
using replacetype = typename dequecontroltype::replacetype;
constexpr ::std::size_t bytes_per_unit{sizeof(replacetype)};
::fast_io::containers::details::deque_init_grow_common_controllerallocate_impl<allocator>(controller, total_block_size, mid, static_cast<replacetype *>(allocator::allocate_zero(total_block_size * bytes_per_unit)));
}

template <typename allocator, typename dequecontroltype>
inline constexpr void deque_init_grow_common_align_impl(dequecontroltype &controller, ::std::size_t align, ::std::size_t total_block_size, ::std::size_t mid) noexcept
{
::fast_io::containers::details::deque_init_grow_common_controllerallocate_impl<allocator>(controller, total_block_size, mid, static_cast<typename dequecontroltype::replacetype *>(allocator::allocate_zero_aligned(align, total_block_size)));
using replacetype = typename dequecontroltype::replacetype;
constexpr ::std::size_t bytes_per_unit{sizeof(replacetype)};
::fast_io::containers::details::deque_init_grow_common_controllerallocate_impl<allocator>(controller, total_block_size, mid, static_cast<replacetype *>(allocator::allocate_aligned_zero(align, total_block_size * bytes_per_unit)));
}

template <typename allocator, ::std::size_t align, ::std::size_t block_size, ::std::size_t mid, typename dequecontroltype>
Expand Down Expand Up @@ -397,7 +402,8 @@ inline constexpr void deque_reallocate_controller_block_common_impl(dequecontrol
::std::size_t front_block_index{static_cast<::std::size_t>(controller.front_block.controller_ptr - controller.controller_block.controller_start_ptr)};
::std::size_t back_block_index{static_cast<::std::size_t>(controller.back_block.controller_ptr - controller.controller_block.controller_start_ptr)};

auto block_temp{allocator::reallocate_n(controller.controller_block.controller_start_ptr, old_size * sizeof(void *), (new_size + 1u) * sizeof(void *))};
// `controller_after_ptr` points at the extra sentinel slot (allocated). Include it in sized reallocation.
auto block_temp{allocator::reallocate_n(controller.controller_block.controller_start_ptr, (old_size + 1u) * sizeof(void *), (new_size + 1u) * sizeof(void *))};

controller.controller_block.controller_start_ptr = static_cast<decltype(controller.controller_block.controller_start_ptr)>(block_temp);

Expand All @@ -419,14 +425,14 @@ inline constexpr T **make_blocks_balance(T **begin, T **end, T **b, T **e) noexc
if (begin == b)
{
T *t = end[-1];
::std::copy(b, e, begin + 1);
::fast_io::freestanding::overlapped_copy(b, e, begin + 1);
*begin = t;
return begin + 1u;
}
else
{
T *t = *begin;
::std::copy(b, e, begin);
::fast_io::freestanding::overlapped_copy(b, e, begin);
end[-1] = t;
return begin;
}
Expand Down Expand Up @@ -525,13 +531,14 @@ inline constexpr void deque_grow_front_common_impl(dequecontroltype &controller)

void *block_temp{};

constexpr ::std::size_t bytes_to_allocate{block_size * sizeof(typename dequecontroltype::replacetype)};
if constexpr (align <= allocator::default_alignment)
{
block_temp = allocator::allocate(block_size);
block_temp = allocator::allocate(bytes_to_allocate);
}
else
{
block_temp = allocator::allocate_zero_aligned(align, block_size);
block_temp = allocator::allocate_aligned_zero(align, bytes_to_allocate);
}

*--controller.controller_block.controller_start_reserved_ptr = reinterpret_cast<decltype(*controller.controller_block.controller_start_reserved_ptr)>(block_temp);
Expand Down Expand Up @@ -578,13 +585,14 @@ inline constexpr void deque_grow_back_common_impl(dequecontroltype &controller)

void *block_temp{};

constexpr ::std::size_t bytes_to_allocate{block_size * sizeof(typename dequecontroltype::replacetype)};
if constexpr (align <= allocator::default_alignment)
{
block_temp = allocator::allocate(block_size);
block_temp = allocator::allocate(bytes_to_allocate);
}
else
{
block_temp = allocator::allocate_zero_aligned(align, block_size);
block_temp = allocator::allocate_aligned_zero(align, bytes_to_allocate);
}

*controller.controller_block.controller_after_reserved_ptr = reinterpret_cast<decltype(*controller.controller_block.controller_after_reserved_ptr)>(block_temp);
Expand Down Expand Up @@ -751,11 +759,22 @@ class deque FAST_IO_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE
grow_back();
}
auto currptr{controller.back_block.curr_ptr};
if constexpr (!::std::is_trivially_constructible_v<value_type>)
::std::construct_at(currptr, ::std::forward<Args>(args)...);
if (++controller.back_block.curr_ptr == controller.back_block.end_ptr) [[unlikely]]
{
::std::construct_at(currptr, ::std::forward<Args>(args)...);
if (controller.back_block.curr_ptr != controller.back_block.end_ptr)
{
return;
}
auto ctrl{controller.back_block.controller_ptr};
if (ctrl && ctrl[1] != nullptr)
{
return;
}
// Allocate/attach a block after `back_block`, then restore `back_block` to the full block.
grow_back();
back_backspace();
}
++controller.back_block.curr_ptr;
return *currptr;
}

Expand Down Expand Up @@ -829,10 +848,7 @@ class deque FAST_IO_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE
{
grow_front();
}
if constexpr (!::std::is_trivially_constructible_v<value_type>)
{
::std::construct_at(--controller.front_block.curr_ptr, ::std::forward<Args>(args)...);
}
::std::construct_at(--controller.front_block.curr_ptr, ::std::forward<Args>(args)...);
return *controller.front_block.curr_ptr;
}

Expand Down
Loading