Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
312c376
overhual implementation of deque
trcrsired Dec 28, 2025
d8ff772
first commit to move the implementation to another machine
trcrsired Jan 1, 2026
7fbe6e0
[skip ci] add partial implementation of deque.h
trcrsired Jan 1, 2026
56ee798
[skip ci] implement deque emplace_back when we have zero blocks
trcrsired Jan 1, 2026
0ee5154
[skip CI] simplify logic of destruction of deque
trcrsired Jan 1, 2026
82af040
[skip CI]add logic for double the blocks
trcrsired Jan 1, 2026
7e8f455
[skip CI] add some implementation for deque
trcrsired Jan 2, 2026
1dd1e5e
[skip CI] implement deque's emplace_back
trcrsired Jan 2, 2026
e7b0502
[skip CI] implement a draft of grow_front which is very wrong
trcrsired Jan 2, 2026
e1d034c
[skip CI] add borrow logic and write better comments
trcrsired Jan 2, 2026
493b637
[skip CI] add check after rebalancing for push_back
trcrsired Jan 4, 2026
ee18421
[skip CI]rewrite the logic (untested code for deque)
trcrsired Jan 5, 2026
254927f
[skip CI]implement more deque logic
trcrsired Jan 5, 2026
fcc9dab
[skip CI]the allocating empty function has bugs for boundary, fixed it
trcrsired Jan 5, 2026
253c38a
[skip CI]implementation of the push_front() for deque has something t…
trcrsired Jan 5, 2026
b3773f6
[skip CI] deque has using namespace ::fast_io::iomnp which should be …
trcrsired Jan 5, 2026
f99d60e
[skip CI]deque balancing with realllocation has bugs we fix it
trcrsired Jan 5, 2026
bb7d980
[skip CI]backup code for failed fuzzing
trcrsired Jan 5, 2026
042e6f9
Add some tests to deque
trcrsired Jan 5, 2026
eaea7b8
[skip CI]why c malloc has no calls to aligned_alloc?
trcrsired Jan 5, 2026
aa1c975
pass all the fuzzing for deque. now run all tests
trcrsired Jan 5, 2026
023ecdb
use ::std::destroy instead ::std::ranges::destroy for deque
trcrsired Jan 5, 2026
3f54f26
Merge remote-tracking branch 'parent/next' into next
trcrsired Jan 5, 2026
876a176
remove unused variable, this should make CI happy
trcrsired Jan 5, 2026
4f609ad
[skip CI] enrich the benchmark of deque for std
trcrsired Jan 5, 2026
16d9030
[skip ci] make benchmarks also bench loop for deque
trcrsired Jan 5, 2026
35e03e5
implement deque's clear and also add tests
trcrsired Jan 5, 2026
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
26 changes: 26 additions & 0 deletions benchmark/0011.containers/deque/0001.push_back/fast_io.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <fast_io.h>
#include <fast_io_driver/timer.h>
#include <fast_io_dsal/deque.h>

int main()
{
fast_io::timer tm(u8"fast_io::deque");
fast_io::deque<std::size_t> deq;
constexpr std::size_t n{100000000};
{
fast_io::timer tm1(u8"push_back");
for (std::size_t i{}; i != n; ++i)
{
deq.push_back(i);
}
}
::std::size_t sum{};
{
fast_io::timer tm1(u8"loop");
for (auto const e : deq)
{
sum += e;
}
}
::fast_io::io::perrln("sum=",sum);
}
26 changes: 26 additions & 0 deletions benchmark/0011.containers/deque/0001.push_back/fast_io_vec.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <fast_io.h>
#include <fast_io_driver/timer.h>
#include <fast_io_dsal/vector.h>

int main()
{
fast_io::timer tm(u8"fast_io::vector");
fast_io::vector<std::size_t> vec;
constexpr std::size_t n{100000000};
{
fast_io::timer tm1(u8"push_back");
for (std::size_t i{}; i != n; ++i)
{
vec.push_back(i);
}
}
::std::size_t sum{};
{
fast_io::timer tm1(u8"loop");
for (auto const e : vec)
{
sum += e;
}
}
::fast_io::io::perrln("sum=",sum);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include <fast_io.h>
#include <fast_io_driver/timer.h>
#include <fast_io_dsal/vector.h>

int main()
{
fast_io::timer tm(u8"fast_io::vector reserve");
fast_io::vector<std::size_t> vec;
constexpr std::size_t n{100000000};
vec.reserve(n);
{
fast_io::timer tm1(u8"push_back");
for (std::size_t i{}; i != n; ++i)
{
vec.push_back(i);
}
}
::std::size_t sum{};
{
fast_io::timer tm1(u8"loop");
for (auto const e : vec)
{
sum += e;
}
}
::fast_io::io::perrln("sum=",sum);
}
26 changes: 26 additions & 0 deletions benchmark/0011.containers/deque/0001.push_back/std.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <fast_io.h>
#include <fast_io_driver/timer.h>
#include <deque>

int main()
{
fast_io::timer tm(u8"std::deque");
std::deque<std::size_t> deq;
constexpr std::size_t n{100000000};
{
fast_io::timer tm1(u8"push_back");
for (std::size_t i{}; i != n; ++i)
{
deq.push_back(i);
}
}
::std::size_t sum{};
{
fast_io::timer tm1(u8"loop");
for (auto const e : deq)
{
sum += e;
}
}
::fast_io::io::perrln("sum=",sum);
}
64 changes: 64 additions & 0 deletions fuzzing/0007.containers/deque/fuzz_deque.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include <fast_io.h>
#include <fast_io_dsal/deque.h>
#include <deque>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <ranges>

extern "C" int LLVMFuzzerTestOneInput(uint8_t const *data, size_t size)
{
::fast_io::deque<std::size_t> dq;
std::deque<std::size_t> ref;

// Interpret input as a sequence of operations
for (size_t i{}; i != size; ++i)
{
uint8_t op = data[i] & 0x3u; // 4 operations
std::size_t value = i; // deterministic, stable

switch (op)
{
case 0: // push_back

dq.push_back(value);
ref.push_back(value);
break;

case 1: // push_front

dq.push_front(value);
ref.push_front(value);
break;

case 2: // pop_back
if (!ref.empty())
{

dq.pop_back();
ref.pop_back();
}
break;

case 3: // pop_front
if (!ref.empty())
{

dq.pop_front();
ref.pop_front();
}
break;
}
}

// Validate correctness
if (dq.size() != ref.size())
{
__builtin_trap();
}
if (!std::ranges::equal(dq, ref))
{
__builtin_trap();
}
return 0;
}
80 changes: 80 additions & 0 deletions fuzzing/0007.containers/deque/fuzz_deque_clear.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include <fast_io_dsal/deque.h>
#include <deque>
#include <cstddef>
#include <cstdint>
#include <ranges>

extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
{
// Require large inputs to trigger growth/balancing
if (size < 4096)
return 0;

::fast_io::deque<std::size_t> dq;
std::deque<std::size_t> ref;

for (size_t i{}; i != size; ++i)
{
uint8_t raw = data[i];
uint8_t op = raw % 6u; // 6 operations
std::size_t value = i;

bool allow_clear =
dq.size() >= 4096 || (raw == 0xFF);
// 1/256 chance of early clear

switch (op)
{
case 0: // push_back
dq.push_back(value);
ref.push_back(value);
break;

case 1: // push_front
dq.push_front(value);
ref.push_front(value);
break;

case 2: // pop_back
if (!ref.empty())
{
dq.pop_back();
ref.pop_back();
}
break;

case 3: // pop_front
if (!ref.empty())
{
dq.pop_front();
ref.pop_front();
}
break;

case 4: // clear()
if (allow_clear)
{
dq.clear();
ref.clear();
}
break;

case 5: // clear_destroy()
if (allow_clear)
{
dq.clear_destroy();
ref.clear();
}
break;
}
}

// Validate correctness
if (dq.size() != ref.size())
__builtin_trap();

if (!std::ranges::equal(dq, ref))
__builtin_trap();

return 0;
}
29 changes: 27 additions & 2 deletions include/fast_io_core_impl/allocation/c_malloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#elif __has_include(<malloc_np.h>)
#include <malloc_np.h>
#endif
#include <cstdlib>

namespace fast_io
{
Expand Down Expand Up @@ -197,16 +198,40 @@ class c_malloc_allocator
::fast_io::noexcept_call(_aligned_free, p);
}
}
#elif !defined(__MSDOS__) && 0
static inline void *allocate_aligned(::std::size_t alignment, ::std::size_t n) noexcept
{
if (n == 0)
{
n = 1;
}
void *p =
#if FAST_IO_HAS_BUILTIN(__builtin_aligned_alloc)
__builtin_aligned_alloc(alignment, n)
#else
::std::aligned_alloc(alignment, n)
#endif
;
if (p == nullptr)
{
::fast_io::fast_terminate();
}
return p;
}
static inline void deallocate_aligned(void *p, ::std::size_t) noexcept
{
deallocate(p);
}
#endif
static inline void deallocate(void *p) noexcept
{
if (p == nullptr)
{
return;
}

#if FAST_IO_HAS_BUILTIN(__builtin_free)
__builtin_free
__builtin_free
#else
::std::free
#endif
Expand Down
Loading