Skip to content

Commit 7d0c379

Browse files
authored
Merge pull request #1250 from trcrsired/next
Implement deque push_back/pop_back/push_front/pop_front
2 parents 99d4b9b + 35e03e5 commit 7d0c379

17 files changed

Lines changed: 964 additions & 371 deletions

File tree

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include <fast_io.h>
2+
#include <fast_io_driver/timer.h>
3+
#include <fast_io_dsal/deque.h>
4+
5+
int main()
6+
{
7+
fast_io::timer tm(u8"fast_io::deque");
8+
fast_io::deque<std::size_t> deq;
9+
constexpr std::size_t n{100000000};
10+
{
11+
fast_io::timer tm1(u8"push_back");
12+
for (std::size_t i{}; i != n; ++i)
13+
{
14+
deq.push_back(i);
15+
}
16+
}
17+
::std::size_t sum{};
18+
{
19+
fast_io::timer tm1(u8"loop");
20+
for (auto const e : deq)
21+
{
22+
sum += e;
23+
}
24+
}
25+
::fast_io::io::perrln("sum=",sum);
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include <fast_io.h>
2+
#include <fast_io_driver/timer.h>
3+
#include <fast_io_dsal/vector.h>
4+
5+
int main()
6+
{
7+
fast_io::timer tm(u8"fast_io::vector");
8+
fast_io::vector<std::size_t> vec;
9+
constexpr std::size_t n{100000000};
10+
{
11+
fast_io::timer tm1(u8"push_back");
12+
for (std::size_t i{}; i != n; ++i)
13+
{
14+
vec.push_back(i);
15+
}
16+
}
17+
::std::size_t sum{};
18+
{
19+
fast_io::timer tm1(u8"loop");
20+
for (auto const e : vec)
21+
{
22+
sum += e;
23+
}
24+
}
25+
::fast_io::io::perrln("sum=",sum);
26+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <fast_io.h>
2+
#include <fast_io_driver/timer.h>
3+
#include <fast_io_dsal/vector.h>
4+
5+
int main()
6+
{
7+
fast_io::timer tm(u8"fast_io::vector reserve");
8+
fast_io::vector<std::size_t> vec;
9+
constexpr std::size_t n{100000000};
10+
vec.reserve(n);
11+
{
12+
fast_io::timer tm1(u8"push_back");
13+
for (std::size_t i{}; i != n; ++i)
14+
{
15+
vec.push_back(i);
16+
}
17+
}
18+
::std::size_t sum{};
19+
{
20+
fast_io::timer tm1(u8"loop");
21+
for (auto const e : vec)
22+
{
23+
sum += e;
24+
}
25+
}
26+
::fast_io::io::perrln("sum=",sum);
27+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include <fast_io.h>
2+
#include <fast_io_driver/timer.h>
3+
#include <deque>
4+
5+
int main()
6+
{
7+
fast_io::timer tm(u8"std::deque");
8+
std::deque<std::size_t> deq;
9+
constexpr std::size_t n{100000000};
10+
{
11+
fast_io::timer tm1(u8"push_back");
12+
for (std::size_t i{}; i != n; ++i)
13+
{
14+
deq.push_back(i);
15+
}
16+
}
17+
::std::size_t sum{};
18+
{
19+
fast_io::timer tm1(u8"loop");
20+
for (auto const e : deq)
21+
{
22+
sum += e;
23+
}
24+
}
25+
::fast_io::io::perrln("sum=",sum);
26+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include <fast_io.h>
2+
#include <fast_io_dsal/deque.h>
3+
#include <deque>
4+
#include <cstddef>
5+
#include <cstdint>
6+
#include <cstring>
7+
#include <ranges>
8+
9+
extern "C" int LLVMFuzzerTestOneInput(uint8_t const *data, size_t size)
10+
{
11+
::fast_io::deque<std::size_t> dq;
12+
std::deque<std::size_t> ref;
13+
14+
// Interpret input as a sequence of operations
15+
for (size_t i{}; i != size; ++i)
16+
{
17+
uint8_t op = data[i] & 0x3u; // 4 operations
18+
std::size_t value = i; // deterministic, stable
19+
20+
switch (op)
21+
{
22+
case 0: // push_back
23+
24+
dq.push_back(value);
25+
ref.push_back(value);
26+
break;
27+
28+
case 1: // push_front
29+
30+
dq.push_front(value);
31+
ref.push_front(value);
32+
break;
33+
34+
case 2: // pop_back
35+
if (!ref.empty())
36+
{
37+
38+
dq.pop_back();
39+
ref.pop_back();
40+
}
41+
break;
42+
43+
case 3: // pop_front
44+
if (!ref.empty())
45+
{
46+
47+
dq.pop_front();
48+
ref.pop_front();
49+
}
50+
break;
51+
}
52+
}
53+
54+
// Validate correctness
55+
if (dq.size() != ref.size())
56+
{
57+
__builtin_trap();
58+
}
59+
if (!std::ranges::equal(dq, ref))
60+
{
61+
__builtin_trap();
62+
}
63+
return 0;
64+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#include <fast_io_dsal/deque.h>
2+
#include <deque>
3+
#include <cstddef>
4+
#include <cstdint>
5+
#include <ranges>
6+
7+
extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
8+
{
9+
// Require large inputs to trigger growth/balancing
10+
if (size < 4096)
11+
return 0;
12+
13+
::fast_io::deque<std::size_t> dq;
14+
std::deque<std::size_t> ref;
15+
16+
for (size_t i{}; i != size; ++i)
17+
{
18+
uint8_t raw = data[i];
19+
uint8_t op = raw % 6u; // 6 operations
20+
std::size_t value = i;
21+
22+
bool allow_clear =
23+
dq.size() >= 4096 || (raw == 0xFF);
24+
// 1/256 chance of early clear
25+
26+
switch (op)
27+
{
28+
case 0: // push_back
29+
dq.push_back(value);
30+
ref.push_back(value);
31+
break;
32+
33+
case 1: // push_front
34+
dq.push_front(value);
35+
ref.push_front(value);
36+
break;
37+
38+
case 2: // pop_back
39+
if (!ref.empty())
40+
{
41+
dq.pop_back();
42+
ref.pop_back();
43+
}
44+
break;
45+
46+
case 3: // pop_front
47+
if (!ref.empty())
48+
{
49+
dq.pop_front();
50+
ref.pop_front();
51+
}
52+
break;
53+
54+
case 4: // clear()
55+
if (allow_clear)
56+
{
57+
dq.clear();
58+
ref.clear();
59+
}
60+
break;
61+
62+
case 5: // clear_destroy()
63+
if (allow_clear)
64+
{
65+
dq.clear_destroy();
66+
ref.clear();
67+
}
68+
break;
69+
}
70+
}
71+
72+
// Validate correctness
73+
if (dq.size() != ref.size())
74+
__builtin_trap();
75+
76+
if (!std::ranges::equal(dq, ref))
77+
__builtin_trap();
78+
79+
return 0;
80+
}

include/fast_io_core_impl/allocation/c_malloc.h

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#elif __has_include(<malloc_np.h>)
66
#include <malloc_np.h>
77
#endif
8+
#include <cstdlib>
89

910
namespace fast_io
1011
{
@@ -197,16 +198,40 @@ class c_malloc_allocator
197198
::fast_io::noexcept_call(_aligned_free, p);
198199
}
199200
}
201+
#elif !defined(__MSDOS__) && 0
202+
static inline void *allocate_aligned(::std::size_t alignment, ::std::size_t n) noexcept
203+
{
204+
if (n == 0)
205+
{
206+
n = 1;
207+
}
208+
void *p =
209+
#if FAST_IO_HAS_BUILTIN(__builtin_aligned_alloc)
210+
__builtin_aligned_alloc(alignment, n)
211+
#else
212+
::std::aligned_alloc(alignment, n)
213+
#endif
214+
;
215+
if (p == nullptr)
216+
{
217+
::fast_io::fast_terminate();
218+
}
219+
return p;
220+
}
221+
static inline void deallocate_aligned(void *p, ::std::size_t) noexcept
222+
{
223+
deallocate(p);
224+
}
200225
#endif
201226
static inline void deallocate(void *p) noexcept
202227
{
203228
if (p == nullptr)
204229
{
205230
return;
206231
}
207-
232+
208233
#if FAST_IO_HAS_BUILTIN(__builtin_free)
209-
__builtin_free
234+
__builtin_free
210235
#else
211236
::std::free
212237
#endif

0 commit comments

Comments
 (0)