Skip to content

Commit d5c1789

Browse files
authored
Merge pull request #1252 from trcrsired/next
implement copy assignment for deque
2 parents e459aa1 + f03c79a commit d5c1789

File tree

2 files changed

+153
-1
lines changed

2 files changed

+153
-1
lines changed

include/fast_io_dsal/impl/deque.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,18 @@ class deque FAST_IO_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE
958958
{
959959
this->copy_construct_impl(other.controller);
960960
}
961-
inline constexpr deque &operator=(deque const &) = delete;
961+
inline constexpr deque &operator=(deque const &other) noexcept(::std::is_nothrow_copy_constructible_v<value_type>)
962+
{
963+
if (__builtin_addressof(other) == this)
964+
{
965+
return *this;
966+
}
967+
deque temp(other);
968+
destroy_deque_controller(this->controller);
969+
this->controller = temp.controller;
970+
temp.controller = {{}, {}, {}};
971+
return *this;
972+
}
962973

963974
inline constexpr deque(deque &&other) noexcept : controller(other.controller)
964975
{
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
#include <fast_io.h>
2+
#include <fast_io_dsal/deque.h>
3+
#include <fast_io_dsal/string.h>
4+
5+
template <typename T>
6+
inline void test_copy_assignment()
7+
{
8+
::fast_io::io::perr("=== copy assignment test ===\n");
9+
10+
// Build source deque
11+
::fast_io::deque<T> src;
12+
for (::std::size_t i{}; i != 4096u; ++i)
13+
{
14+
if constexpr (::std::same_as<T, ::std::size_t>)
15+
{
16+
src.push_back(i);
17+
}
18+
else
19+
{
20+
src.push_back(::fast_io::string(::fast_io::concat_fast_io(i)));
21+
}
22+
}
23+
24+
// Build destination deque with garbage data
25+
::fast_io::deque<T> dst;
26+
for (::std::size_t i{}; i != 1234u; ++i)
27+
{
28+
if constexpr (::std::same_as<T, ::std::size_t>)
29+
{
30+
dst.push_back(999999u);
31+
}
32+
else
33+
{
34+
dst.emplace_back("garbage");
35+
}
36+
}
37+
38+
// Perform copy assignment
39+
dst = src;
40+
41+
// Check size
42+
if (dst.size() != src.size())
43+
{
44+
::fast_io::io::panic("ERROR: dst.size() != src.size() after copy assignment\n");
45+
}
46+
47+
// Check element equality
48+
::std::size_t idx{};
49+
for (T const &e : dst)
50+
{
51+
if constexpr (::std::same_as<T, ::std::size_t>)
52+
{
53+
if (e != idx)
54+
{
55+
::fast_io::io::panicln("ERROR: dst element mismatch: ", e);
56+
}
57+
}
58+
else
59+
{
60+
::fast_io::string expected(::fast_io::concat_fast_io(idx));
61+
if (e != expected)
62+
{
63+
::fast_io::io::panicln("ERROR: dst string mismatch: ", e);
64+
}
65+
}
66+
++idx;
67+
}
68+
69+
// Modify src to ensure deep copy
70+
if constexpr (::std::same_as<T, ::std::size_t>)
71+
{
72+
for (::std::size_t i{}; i != src.size(); ++i)
73+
{
74+
src[i] = src[i] + 1u;
75+
}
76+
}
77+
else
78+
{
79+
for (::std::size_t i{}; i != src.size(); ++i)
80+
{
81+
src[i].append("_changed");
82+
}
83+
}
84+
85+
// dst must remain unchanged
86+
idx = 0u;
87+
for (T const &e : dst)
88+
{
89+
if constexpr (::std::same_as<T, ::std::size_t>)
90+
{
91+
if (e != idx)
92+
{
93+
::fast_io::io::panicln("ERROR: dst changed after modifying src: ", e);
94+
}
95+
}
96+
else
97+
{
98+
::fast_io::string expected(::fast_io::concat_fast_io(idx));
99+
if (e != expected)
100+
{
101+
::fast_io::io::panicln("ERROR: dst string changed after modifying src: ", e);
102+
}
103+
}
104+
++idx;
105+
}
106+
107+
// Self-assignment test
108+
dst = dst;
109+
110+
// Verify unchanged after self-assignment
111+
idx = 0u;
112+
for (T const &e : dst)
113+
{
114+
if constexpr (::std::same_as<T, ::std::size_t>)
115+
{
116+
if (e != idx)
117+
{
118+
::fast_io::io::panicln("ERROR: dst changed after self-assignment: ", e);
119+
}
120+
}
121+
else
122+
{
123+
::fast_io::string expected(::fast_io::concat_fast_io(idx));
124+
if (e != expected)
125+
{
126+
::fast_io::io::panicln("ERROR: dst string changed after self-assignment: ", e);
127+
}
128+
}
129+
++idx;
130+
}
131+
132+
::fast_io::io::print("copy assignment test finished\n");
133+
}
134+
135+
int main()
136+
{
137+
test_copy_assignment<::std::size_t>();
138+
test_copy_assignment<::fast_io::string>();
139+
140+
::fast_io::io::print("All copy assignment tests finished\n");
141+
}

0 commit comments

Comments
 (0)