Skip to content

Commit 067ed66

Browse files
committed
implement deque's copy constructor, now let's run CI
1 parent 236e77c commit 067ed66

2 files changed

Lines changed: 149 additions & 99 deletions

File tree

include/fast_io_dsal/impl/deque.h

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,7 @@ class deque FAST_IO_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE
970970
{
971971
return *this;
972972
}
973-
this->destroy();
973+
destroy_deque_controller(this->controller);
974974
this->controller = other.controller;
975975
other.controller = {{}, {}, {}};
976976
return *this;
@@ -979,18 +979,18 @@ class deque FAST_IO_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE
979979
private:
980980
struct run_destroy
981981
{
982-
deque *thisdeq{};
982+
controller_type *thiscontroller{};
983983
inline constexpr run_destroy() noexcept = default;
984-
inline explicit constexpr run_destroy(deque *p) noexcept
985-
: thisdeq(p)
984+
inline explicit constexpr run_destroy(controller_type *p) noexcept
985+
: thiscontroller(p)
986986
{}
987987
inline run_destroy(run_destroy const &) = delete;
988988
inline run_destroy &operator=(run_destroy const &) = delete;
989989
inline constexpr ~run_destroy()
990990
{
991-
if (thisdeq)
991+
if (thiscontroller)
992992
{
993-
thisdeq->destroy();
993+
destroy_deque_controller(*thiscontroller);
994994
}
995995
}
996996
};
@@ -1009,10 +1009,62 @@ class deque FAST_IO_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE
10091009
}
10101010
return;
10111011
}
1012+
else
1013+
{
1014+
if (fromcontroller.front_block.curr_ptr == fromcontroller.back_block.curr_ptr)
1015+
{
1016+
this->controller = {{}, {}, {}};
1017+
return;
1018+
}
1019+
1020+
auto front_controller_ptr{fromcontroller.front_block.controller_ptr};
1021+
auto back_controller_ptr{fromcontroller.back_block.controller_ptr};
1022+
::std::size_t blocks_required{static_cast<::std::size_t>(back_controller_ptr -
1023+
front_controller_ptr + 1)};
1024+
constexpr ::std::size_t block_bytes{block_size * sizeof(value_type)};
1025+
::fast_io::containers::details::deque_allocate_init_blocks_dezeroing_impl<allocator>(controller, alignof(value_type), block_bytes, blocks_required, false);
1026+
1027+
run_destroy destroyer(__builtin_addressof(this->controller));
1028+
auto dq_back_backup{this->controller.back_block};
1029+
this->controller.back_block = this->controller.front_block;
1030+
pointer lastblockbegin;
1031+
if (front_controller_ptr == back_controller_ptr)
1032+
{
1033+
lastblockbegin = controller.front_block.curr_ptr;
1034+
}
1035+
else
1036+
{
1037+
auto destit{controller.front_block.controller_ptr};
1038+
auto pos{fromcontroller.front_block.curr_ptr - fromcontroller.front_block.begin_ptr};
1039+
::std::uninitialized_copy(
1040+
fromcontroller.front_block.curr_ptr,
1041+
fromcontroller.front_block.end_ptr,
1042+
(controller.front_block.curr_ptr =
1043+
pos + controller.front_block.begin_ptr));
1044+
this->controller.back_block.curr_ptr = controller.front_block.end_ptr =
1045+
controller.front_block.begin_ptr + block_size;
1046+
++destit;
1047+
for (pointer *it{front_controller_ptr + 1}, *ed{back_controller_ptr}; it != ed; ++it)
1048+
{
1049+
pointer blockptr{*it};
1050+
::std::uninitialized_copy_n(blockptr, block_size, *destit);
1051+
this->controller.back_block = {destit, blockptr, blockptr, blockptr + block_size};
1052+
++destit;
1053+
}
1054+
lastblockbegin = fromcontroller.back_block.begin_ptr;
1055+
}
1056+
1057+
dq_back_backup.curr_ptr =
1058+
::std::uninitialized_copy(lastblockbegin,
1059+
fromcontroller.back_block.curr_ptr, dq_back_backup.begin_ptr);
1060+
1061+
this->controller.back_block = dq_back_backup;
1062+
destroyer.thiscontroller = nullptr;
1063+
}
10121064
}
10131065
inline constexpr void default_construct_impl()
10141066
{
1015-
run_destroy des(this);
1067+
run_destroy des(__builtin_addressof(this->controller));
10161068

10171069
auto dq_back_backup{controller.back_block};
10181070
controller.back_block = controller.front_block;
@@ -1092,7 +1144,7 @@ class deque FAST_IO_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE
10921144
controller = {{}, {}, {}};
10931145
return;
10941146
}
1095-
run_destroy des(this);
1147+
run_destroy des(__builtin_addressof(this->controller));
10961148
if constexpr (::std::sized_sentinel_for<Sentinel, Iter>)
10971149
{
10981150
auto const dist{::std::ranges::distance(first, last)};
@@ -1148,7 +1200,7 @@ class deque FAST_IO_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE
11481200
::fast_io::containers::details::deque_init_space_common<allocator, alignof(value_type), sizeof(value_type), block_size, iszeroconstr>(*reinterpret_cast<::fast_io::containers::details::deque_controller_common *>(__builtin_addressof(controller)), n);
11491201
}
11501202
}
1151-
inline constexpr void destroy_all_elements() noexcept
1203+
inline static constexpr void destroy_all_elements(controller_type &controller) noexcept
11521204
{
11531205
auto front_controller_ptr{controller.front_block.controller_ptr};
11541206
auto back_controller_ptr{controller.back_block.controller_ptr};
@@ -1170,11 +1222,11 @@ class deque FAST_IO_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE
11701222
::std::destroy(lastblockbegin, controller.back_block.curr_ptr);
11711223
}
11721224

1173-
inline constexpr void destroy() noexcept
1225+
inline static constexpr void destroy_deque_controller(controller_type &controller) noexcept
11741226
{
11751227
if constexpr (!::std::is_trivially_destructible_v<value_type>)
11761228
{
1177-
this->destroy_all_elements();
1229+
destroy_all_elements(controller);
11781230
}
11791231
::fast_io::containers::details::deque_destroy_trivial_common<allocator, alignof(value_type), sizeof(value_type)>(controller.controller_block);
11801232
}
@@ -1229,7 +1281,7 @@ class deque FAST_IO_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE
12291281
{
12301282
if constexpr (!::std::is_trivially_destructible_v<value_type>)
12311283
{
1232-
this->destroy_all_elements();
1284+
destroy_all_elements(this->controller);
12331285
}
12341286
if (__builtin_is_constant_evaluated())
12351287
{
@@ -1593,13 +1645,13 @@ class deque FAST_IO_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE
15931645

15941646
inline constexpr void clear_destroy() noexcept
15951647
{
1596-
this->destroy();
1648+
destroy_deque_controller(this->controller);
15971649
this->controller = {{}, {}, {}};
15981650
}
15991651

16001652
inline constexpr ~deque()
16011653
{
1602-
this->destroy();
1654+
destroy_deque_controller(this->controller);
16031655
}
16041656
};
16051657

tests/0026.container/0003.deque/constructors/copy_constructor.cc

Lines changed: 83 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -3,102 +3,100 @@
33
#include <fast_io_dsal/string_view.h>
44
#include <fast_io_dsal/string.h>
55

6-
template<typename T>
6+
template <typename T>
77
inline void test_copy_constructor()
88
{
9-
::fast_io::io::perr("=== copy constructor test for type ===\n");
9+
::fast_io::io::perr("=== copy constructor test for type ===\n");
1010

11-
// Fill original deque
12-
::fast_io::deque<T> dq;
13-
for (::std::size_t i{}; i != 4096u; ++i)
14-
{
15-
if constexpr(::std::same_as<T, ::std::size_t>)
16-
{
17-
dq.push_back(i);
18-
}
19-
else
20-
{
21-
dq.emplace_back(::fast_io::concat_fast_io(i));
22-
}
23-
}
11+
// Fill original deque
12+
::fast_io::deque<T> dq;
13+
for (::std::size_t i{}; i != 4096u; ++i)
14+
{
15+
if constexpr (::std::same_as<T, ::std::size_t>)
16+
{
17+
dq.push_back(i);
18+
}
19+
else
20+
{
21+
dq.emplace_back(::fast_io::concat_fast_io(i));
22+
}
23+
}
24+
// Copy construct
25+
::fast_io::deque<T> dq2(dq);
2426

25-
// Copy construct
26-
::fast_io::deque<T> dq2(dq);
27-
::fast_io::io::println("dq2.size()=",dq2.size(),"\t"
28-
"dq.size()=",dq.size());
29-
// Size must match
30-
if (dq2.size() != dq.size())
31-
{
32-
::fast_io::io::panic("ERROR: dq2.size() != dq.size() after copy construction\n");
33-
}
27+
// Size must match
28+
if (dq2.size() != dq.size())
29+
{
30+
::fast_io::io::panic("ERROR: dq2.size() != dq.size() after copy construction\n");
31+
}
3432

35-
// Elements must match
36-
::std::size_t idx{};
37-
for (T const& e : dq2)
38-
{
39-
if constexpr(::std::same_as<T, ::std::size_t>)
40-
{
41-
if (e != idx)
42-
{
43-
::fast_io::io::panicln("ERROR: dq2 element mismatch: ", e);
44-
}
45-
}
46-
else
47-
{
48-
::fast_io::string expected(::fast_io::concat_fast_io(idx));
49-
if (e != expected)
50-
{
51-
::fast_io::io::panicln("ERROR: dq2 string mismatch: ", e);
52-
}
53-
}
54-
++idx;
55-
}
33+
// Elements must match
34+
::std::size_t idx{};
35+
for (T const &e : dq2)
36+
{
37+
if constexpr (::std::same_as<T, ::std::size_t>)
38+
{
39+
if (e != idx)
40+
{
41+
::fast_io::io::panicln("ERROR: dq2 element mismatch: ", e);
42+
}
43+
}
44+
else
45+
{
46+
::fast_io::string expected(::fast_io::concat_fast_io(idx));
47+
if (e != expected)
48+
{
49+
::fast_io::io::panicln("ERROR: dq2 string mismatch: ", e);
50+
}
51+
}
52+
++idx;
53+
}
5654

57-
// Modify original to ensure deep copy
58-
if constexpr(::std::same_as<T, ::std::size_t>)
59-
{
60-
for (auto & e : dq)
61-
{
62-
++e;
63-
}
64-
}
65-
else
66-
{
67-
for (auto & e : dq)
68-
{
69-
e.append(::fast_io::u8cstring_view(u8"_changed"));
70-
}
71-
}
55+
// Modify original to ensure deep copy
56+
if constexpr (::std::same_as<T, ::std::size_t>)
57+
{
58+
for (auto &e : dq)
59+
{
60+
++e;
61+
}
62+
}
63+
else
64+
{
65+
for (auto &e : dq)
66+
{
67+
e.append("_changed");
68+
}
69+
}
7270

73-
// dq2 must remain unchanged
74-
idx = 0u;
75-
for (T const& e : dq2)
76-
{
77-
if constexpr(::std::same_as<T, ::std::size_t>)
78-
{
79-
if (e != idx)
80-
{
81-
::fast_io::io::panicln("ERROR: dq2 changed after modifying dq: ", e);
82-
}
83-
}
84-
else
85-
{
86-
::fast_io::string expected(::fast_io::concat_fast_io(idx));
87-
if (e != expected)
88-
{
89-
::fast_io::io::panicln("ERROR: dq2 string changed after modifying dq: ", e);
90-
}
91-
}
92-
++idx;
93-
}
71+
// dq2 must remain unchanged
72+
idx = 0u;
73+
for (T const &e : dq2)
74+
{
75+
if constexpr (::std::same_as<T, ::std::size_t>)
76+
{
77+
if (e != idx)
78+
{
79+
::fast_io::io::panicln("ERROR: dq2 changed after modifying dq: ", e);
80+
}
81+
}
82+
else
83+
{
84+
::fast_io::string expected(::fast_io::concat_fast_io(idx));
85+
if (e != expected)
86+
{
87+
::fast_io::io::panicln("ERROR: dq2 string changed after modifying dq: ", e);
88+
}
89+
}
90+
++idx;
91+
}
9492

95-
::fast_io::io::print("copy constructor test finished\n");
93+
::fast_io::io::print("copy constructor test finished\n");
9694
}
9795

9896
int main()
9997
{
100-
test_copy_constructor<::std::size_t>();
101-
// test_copy_constructor<::fast_io::string>();
98+
test_copy_constructor<::std::size_t>();
99+
test_copy_constructor<::fast_io::string>();
102100

103-
::fast_io::io::print("All copy constructor tests finished\n");
101+
::fast_io::io::print("All copy constructor tests finished\n");
104102
}

0 commit comments

Comments
 (0)