SimpleKernel 1.17.0
Loading...
Searching...
No Matches
sk_unique_ptr_test.cpp
Go to the documentation of this file.
1
5#include <gtest/gtest.h>
6
7#include "kstd_unique_ptr"
8
9namespace {
10
11struct TestObj {
12 int value;
13 static int destroy_count;
14 explicit TestObj(int v) : value(v) {}
15 ~TestObj() { ++destroy_count; }
16};
17int TestObj::destroy_count = 0;
18
19class UniquePtrTest : public ::testing::Test {
20 protected:
21 void SetUp() override { TestObj::destroy_count = 0; }
22};
23
24// 1. Default construction — null
25TEST_F(UniquePtrTest, DefaultConstruction) {
26 kstd::unique_ptr<TestObj> p;
27 EXPECT_EQ(p.get(), nullptr);
28 EXPECT_FALSE(static_cast<bool>(p));
29}
30
31// 2. Construction from raw pointer
32TEST_F(UniquePtrTest, ConstructionFromRawPointer) {
33 kstd::unique_ptr<TestObj> p(new TestObj(42));
34 EXPECT_NE(p.get(), nullptr);
35 EXPECT_TRUE(static_cast<bool>(p));
36 EXPECT_EQ(p->value, 42);
37}
38
39// 3. Destructor deletes object
40TEST_F(UniquePtrTest, DestructorDeletesObject) {
41 {
42 kstd::unique_ptr<TestObj> p(new TestObj(5));
43 EXPECT_EQ(TestObj::destroy_count, 0);
44 }
45 EXPECT_EQ(TestObj::destroy_count, 1);
46}
47
48// 4. Move construction — source becomes null
49TEST_F(UniquePtrTest, MoveConstruction) {
50 kstd::unique_ptr<TestObj> p1(new TestObj(99));
51 TestObj* raw = p1.get();
52
53 kstd::unique_ptr<TestObj> p2(static_cast<kstd::unique_ptr<TestObj>&&>(p1));
54 EXPECT_EQ(p1.get(), nullptr);
55 EXPECT_EQ(p2.get(), raw);
56 EXPECT_EQ(TestObj::destroy_count, 0);
57}
58
59// 5. Move assignment
60TEST_F(UniquePtrTest, MoveAssignment) {
61 kstd::unique_ptr<TestObj> p1(new TestObj(7));
62 kstd::unique_ptr<TestObj> p2(new TestObj(8));
63 TestObj* raw1 = p1.get();
64
65 p2 = static_cast<kstd::unique_ptr<TestObj>&&>(p1);
66 EXPECT_EQ(TestObj::destroy_count, 1); // p2's old object destroyed
67 EXPECT_EQ(p1.get(), nullptr);
68 EXPECT_EQ(p2.get(), raw1);
69}
70
71// 6. release() — returns pointer, unique_ptr becomes null
72TEST_F(UniquePtrTest, Release) {
73 auto* raw = new TestObj(10);
74 kstd::unique_ptr<TestObj> p(raw);
75 TestObj* released = p.release();
76 EXPECT_EQ(released, raw);
77 EXPECT_EQ(p.get(), nullptr);
78 EXPECT_EQ(TestObj::destroy_count, 0); // not deleted!
79 delete released; // manual cleanup
80}
81
82// 7. reset() — becomes null, deletes old
83TEST_F(UniquePtrTest, ResetBecomesNull) {
84 kstd::unique_ptr<TestObj> p(new TestObj(3));
85 p.reset();
86 EXPECT_EQ(p.get(), nullptr);
87 EXPECT_EQ(TestObj::destroy_count, 1);
88}
89
90// 8. reset(T*) — replaces managed object
91TEST_F(UniquePtrTest, ResetWithNewPointer) {
92 kstd::unique_ptr<TestObj> p(new TestObj(11));
93 p.reset(new TestObj(22));
94 EXPECT_EQ(TestObj::destroy_count, 1);
95 EXPECT_EQ(p->value, 22);
96}
97
98// 9. swap
99TEST_F(UniquePtrTest, Swap) {
100 auto* raw1 = new TestObj(1);
101 auto* raw2 = new TestObj(2);
102 kstd::unique_ptr<TestObj> p1(raw1);
103 kstd::unique_ptr<TestObj> p2(raw2);
104
105 p1.swap(p2);
106 EXPECT_EQ(p1.get(), raw2);
107 EXPECT_EQ(p2.get(), raw1);
108}
109
110// 10. Non-member swap
111TEST_F(UniquePtrTest, NonMemberSwap) {
112 auto* raw1 = new TestObj(10);
113 auto* raw2 = new TestObj(20);
114 kstd::unique_ptr<TestObj> p1(raw1);
115 kstd::unique_ptr<TestObj> p2(raw2);
116
117 kstd::swap(p1, p2);
118 EXPECT_EQ(p1.get(), raw2);
119 EXPECT_EQ(p2.get(), raw1);
120}
121
122// 11. Dereference operators
123TEST_F(UniquePtrTest, DereferenceOperators) {
124 kstd::unique_ptr<TestObj> p(new TestObj(77));
125 EXPECT_EQ((*p).value, 77);
126 EXPECT_EQ(p->value, 77);
127 (*p).value = 88;
128 EXPECT_EQ(p->value, 88);
129}
130
131// 12. Bool conversion
132TEST_F(UniquePtrTest, BoolConversion) {
133 kstd::unique_ptr<TestObj> null_ptr;
134 kstd::unique_ptr<TestObj> valid_ptr(new TestObj(1));
135 EXPECT_FALSE(static_cast<bool>(null_ptr));
136 EXPECT_TRUE(static_cast<bool>(valid_ptr));
137}
138
139// 13. nullptr assignment
140TEST_F(UniquePtrTest, NullptrAssignment) {
141 kstd::unique_ptr<TestObj> p(new TestObj(5));
142 p = nullptr;
143 EXPECT_EQ(p.get(), nullptr);
144 EXPECT_EQ(TestObj::destroy_count, 1);
145}
146
147// 14. nullptr construction
148TEST_F(UniquePtrTest, NullptrConstruction) {
149 kstd::unique_ptr<TestObj> p(nullptr);
150 EXPECT_EQ(p.get(), nullptr);
151 EXPECT_FALSE(static_cast<bool>(p));
152}
153
154// 15. Custom deleter
155TEST_F(UniquePtrTest, CustomDeleter) {
156 static int custom_delete_count = 0;
157 custom_delete_count = 0;
158
159 struct CustomDeleter {
160 auto operator()(TestObj* ptr) const noexcept -> void {
161 ++custom_delete_count;
162 delete ptr;
163 }
164 };
165
166 {
167 kstd::unique_ptr<TestObj, CustomDeleter> p(new TestObj(1));
168 EXPECT_EQ(custom_delete_count, 0);
169 }
170 EXPECT_EQ(custom_delete_count, 1);
171 EXPECT_EQ(TestObj::destroy_count, 1);
172}
173
174// 16. get_deleter
175TEST_F(UniquePtrTest, GetDeleter) {
176 kstd::unique_ptr<TestObj> p(new TestObj(1));
177 auto& d = p.get_deleter();
178 // Just verify we can call it — default_delete should work
179 (void)d;
180}
181
182// 17. make_unique
183TEST_F(UniquePtrTest, MakeUnique) {
184 auto p = kstd::make_unique<TestObj>(123);
185 EXPECT_NE(p.get(), nullptr);
186 EXPECT_EQ(p->value, 123);
187}
188
189// 18. make_unique with multiple args
190TEST_F(UniquePtrTest, MakeUniqueMultipleArgs) {
191 struct Point {
192 int x;
193 int y;
194 Point(int a, int b) : x(a), y(b) {}
195 };
196 auto p = kstd::make_unique<Point>(3, 4);
197 EXPECT_EQ(p->x, 3);
198 EXPECT_EQ(p->y, 4);
199}
200
201// 19. Polymorphic — base unique_ptr managing derived
202TEST_F(UniquePtrTest, Polymorphic) {
203 struct Base {
204 virtual ~Base() = default;
205 virtual auto GetValue() -> int { return 0; }
206 };
207 struct Derived : Base {
208 int val;
209 explicit Derived(int v) : val(v) {}
210 auto GetValue() -> int override { return val; }
211 };
212
213 kstd::unique_ptr<Base> p(new Derived(42));
214 EXPECT_EQ(p->GetValue(), 42);
215}
216
217// 20. Self move assignment — safe
218TEST_F(UniquePtrTest, SelfMoveAssignment) {
219 kstd::unique_ptr<TestObj> p(new TestObj(42));
220 p = static_cast<kstd::unique_ptr<TestObj>&&>(p);
221 // Object must not be double-deleted
222 EXPECT_EQ(TestObj::destroy_count, 0);
223}
224
225// 21. Comparison operators
226TEST_F(UniquePtrTest, ComparisonOperators) {
227 kstd::unique_ptr<TestObj> null_ptr;
228 kstd::unique_ptr<TestObj> p1(new TestObj(1));
229 kstd::unique_ptr<TestObj> p2(new TestObj(2));
230
231 EXPECT_TRUE(null_ptr == nullptr);
232 EXPECT_TRUE(nullptr == null_ptr);
233 EXPECT_FALSE(p1 == nullptr);
234 EXPECT_FALSE(p1 == p2);
235 EXPECT_TRUE(p1 != p2);
236 EXPECT_TRUE(p1 != nullptr);
237}
238
239// ── Array specialization tests ──────────────────────────────────────────────
240
241struct ArrayObj {
242 int value;
243 static int destroy_count;
244 ArrayObj() : value(0) {}
245 explicit ArrayObj(int v) : value(v) {}
246 ~ArrayObj() { ++destroy_count; }
247};
248int ArrayObj::destroy_count = 0;
249
250class UniquePtrArrayTest : public ::testing::Test {
251 protected:
252 void SetUp() override { ArrayObj::destroy_count = 0; }
253};
254
255// 22. Array default construction
256TEST_F(UniquePtrArrayTest, DefaultConstruction) {
257 kstd::unique_ptr<ArrayObj[]> p;
258 EXPECT_EQ(p.get(), nullptr);
259 EXPECT_FALSE(static_cast<bool>(p));
260}
261
262// 23. Array construction + destructor calls delete[]
263TEST_F(UniquePtrArrayTest, ConstructionAndDestruction) {
264 {
265 kstd::unique_ptr<ArrayObj[]> p(new ArrayObj[3]);
266 EXPECT_NE(p.get(), nullptr);
267 EXPECT_EQ(ArrayObj::destroy_count, 0);
268 }
269 EXPECT_EQ(ArrayObj::destroy_count, 3);
270}
271
272// 24. Array subscript operator
273TEST_F(UniquePtrArrayTest, SubscriptOperator) {
274 kstd::unique_ptr<ArrayObj[]> p(new ArrayObj[3]);
275 p[0].value = 10;
276 p[1].value = 20;
277 p[2].value = 30;
278 EXPECT_EQ(p[0].value, 10);
279 EXPECT_EQ(p[1].value, 20);
280 EXPECT_EQ(p[2].value, 30);
281}
282
283// 25. Array move construction
284TEST_F(UniquePtrArrayTest, MoveConstruction) {
285 kstd::unique_ptr<ArrayObj[]> p1(new ArrayObj[2]);
286 ArrayObj* raw = p1.get();
287 kstd::unique_ptr<ArrayObj[]> p2(
288 static_cast<kstd::unique_ptr<ArrayObj[]>&&>(p1));
289 EXPECT_EQ(p1.get(), nullptr);
290 EXPECT_EQ(p2.get(), raw);
291}
292
293// 26. Array release
294TEST_F(UniquePtrArrayTest, Release) {
295 auto* raw = new ArrayObj[2];
296 kstd::unique_ptr<ArrayObj[]> p(raw);
297 ArrayObj* released = p.release();
298 EXPECT_EQ(released, raw);
299 EXPECT_EQ(p.get(), nullptr);
300 EXPECT_EQ(ArrayObj::destroy_count, 0);
301 delete[] released;
302}
303
304// 27. Array reset
305TEST_F(UniquePtrArrayTest, Reset) {
306 kstd::unique_ptr<ArrayObj[]> p(new ArrayObj[2]);
307 p.reset();
308 EXPECT_EQ(p.get(), nullptr);
309 EXPECT_EQ(ArrayObj::destroy_count, 2);
310}
311
312// 28. Array swap
313TEST_F(UniquePtrArrayTest, Swap) {
314 auto* raw1 = new ArrayObj[1];
315 auto* raw2 = new ArrayObj[1];
316 kstd::unique_ptr<ArrayObj[]> p1(raw1);
317 kstd::unique_ptr<ArrayObj[]> p2(raw2);
318 p1.swap(p2);
319 EXPECT_EQ(p1.get(), raw2);
320 EXPECT_EQ(p2.get(), raw1);
321}
322
323// 29. Array nullptr assignment
324TEST_F(UniquePtrArrayTest, NullptrAssignment) {
325 kstd::unique_ptr<ArrayObj[]> p(new ArrayObj[2]);
326 p = nullptr;
327 EXPECT_EQ(p.get(), nullptr);
328 EXPECT_EQ(ArrayObj::destroy_count, 2);
329}
330
331} // namespace
TEST_F(KernelFdtTest, ConstructorTest)
#define EXPECT_TRUE(cond, msg)
#define EXPECT_NE(val1, val2, msg)
#define EXPECT_FALSE(cond, msg)
#define EXPECT_EQ(val1, val2, msg)