1 | #include <c10/util/intrusive_ptr.h> |
2 | |
3 | #include <gtest/gtest.h> |
4 | #include <map> |
5 | #include <memory> |
6 | #include <set> |
7 | #include <unordered_map> |
8 | #include <unordered_set> |
9 | |
10 | using c10::intrusive_ptr; |
11 | using c10::intrusive_ptr_target; |
12 | using c10::make_intrusive; |
13 | using c10::weak_intrusive_ptr; |
14 | |
15 | #ifndef _MSC_VER |
16 | #pragma GCC diagnostic ignored "-Wpragmas" |
17 | #pragma GCC diagnostic ignored "-Wunknown-warning-option" |
18 | #pragma GCC diagnostic ignored "-Wself-move" |
19 | #endif |
20 | |
21 | #ifdef __clang__ |
22 | #pragma clang diagnostic ignored "-Wself-assign-overloaded" |
23 | #endif |
24 | |
25 | namespace { |
26 | class SomeClass0Parameters : public intrusive_ptr_target {}; |
27 | class SomeClass1Parameter : public intrusive_ptr_target { |
28 | public: |
29 | SomeClass1Parameter(int param_) : param(param_) {} |
30 | int param; |
31 | }; |
32 | class SomeClass2Parameters : public intrusive_ptr_target { |
33 | public: |
34 | SomeClass2Parameters(int param1_, int param2_) |
35 | : param1(param1_), param2(param2_) {} |
36 | int param1; |
37 | int param2; |
38 | }; |
39 | using SomeClass = SomeClass0Parameters; |
40 | struct SomeBaseClass : public intrusive_ptr_target { |
41 | SomeBaseClass(int v_) : v(v_) {} |
42 | int v; |
43 | }; |
44 | struct SomeChildClass : SomeBaseClass { |
45 | SomeChildClass(int v) : SomeBaseClass(v) {} |
46 | }; |
47 | |
48 | class DestructableMock : public intrusive_ptr_target { |
49 | public: |
50 | DestructableMock(bool* resourcesReleased, bool* wasDestructed) |
51 | : resourcesReleased_(resourcesReleased), wasDestructed_(wasDestructed) {} |
52 | |
53 | ~DestructableMock() override { |
54 | *resourcesReleased_ = true; |
55 | *wasDestructed_ = true; |
56 | } |
57 | |
58 | void release_resources() override { |
59 | *resourcesReleased_ = true; |
60 | } |
61 | |
62 | private: |
63 | bool* resourcesReleased_; |
64 | bool* wasDestructed_; |
65 | }; |
66 | |
67 | class ChildDestructableMock final : public DestructableMock { |
68 | public: |
69 | ChildDestructableMock(bool* resourcesReleased, bool* wasDestructed) |
70 | : DestructableMock(resourcesReleased, wasDestructed) {} |
71 | }; |
72 | class NullType1 final { |
73 | static SomeClass singleton_; |
74 | |
75 | public: |
76 | static constexpr SomeClass* singleton() { |
77 | return &singleton_; |
78 | } |
79 | }; |
80 | SomeClass NullType1::singleton_; |
81 | class NullType2 final { |
82 | static SomeClass singleton_; |
83 | |
84 | public: |
85 | static constexpr SomeClass* singleton() { |
86 | return &singleton_; |
87 | } |
88 | }; |
89 | SomeClass NullType2::singleton_; |
90 | static_assert(NullType1::singleton() != NullType2::singleton(), "" ); |
91 | } // namespace |
92 | |
93 | static_assert( |
94 | std::is_same<SomeClass, intrusive_ptr<SomeClass>::element_type>::value, |
95 | "intrusive_ptr<T>::element_type is wrong" ); |
96 | |
97 | TEST(MakeIntrusiveTest, ClassWith0Parameters) { |
98 | intrusive_ptr<SomeClass0Parameters> var = |
99 | make_intrusive<SomeClass0Parameters>(); |
100 | // Check that the type is correct |
101 | EXPECT_EQ(var.get(), dynamic_cast<SomeClass0Parameters*>(var.get())); |
102 | } |
103 | |
104 | TEST(MakeIntrusiveTest, ClassWith1Parameter) { |
105 | intrusive_ptr<SomeClass1Parameter> var = |
106 | make_intrusive<SomeClass1Parameter>(5); |
107 | EXPECT_EQ(5, var->param); |
108 | } |
109 | |
110 | TEST(MakeIntrusiveTest, ClassWith2Parameters) { |
111 | intrusive_ptr<SomeClass2Parameters> var = |
112 | make_intrusive<SomeClass2Parameters>(7, 2); |
113 | EXPECT_EQ(7, var->param1); |
114 | EXPECT_EQ(2, var->param2); |
115 | } |
116 | |
117 | TEST(MakeIntrusiveTest, TypeIsAutoDeductible) { |
118 | auto var2 = make_intrusive<SomeClass0Parameters>(); |
119 | auto var3 = make_intrusive<SomeClass1Parameter>(2); |
120 | auto var4 = make_intrusive<SomeClass2Parameters>(2, 3); |
121 | } |
122 | |
123 | TEST(MakeIntrusiveTest, CanAssignToBaseClassPtr) { |
124 | intrusive_ptr<SomeBaseClass> var = make_intrusive<SomeChildClass>(3); |
125 | EXPECT_EQ(3, var->v); |
126 | } |
127 | |
128 | TEST(IntrusivePtrTargetTest, whenAllocatedOnStack_thenDoesntCrash) { |
129 | SomeClass myClass; |
130 | } |
131 | |
132 | TEST(IntrusivePtrTest, givenValidPtr_whenCallingGet_thenReturnsObject) { |
133 | intrusive_ptr<SomeClass1Parameter> obj = |
134 | make_intrusive<SomeClass1Parameter>(5); |
135 | EXPECT_EQ(5, obj.get()->param); |
136 | } |
137 | |
138 | TEST(IntrusivePtrTest, givenValidPtr_whenCallingConstGet_thenReturnsObject) { |
139 | const intrusive_ptr<SomeClass1Parameter> obj = |
140 | make_intrusive<SomeClass1Parameter>(5); |
141 | EXPECT_EQ(5, obj.get()->param); |
142 | } |
143 | |
144 | TEST(IntrusivePtrTest, givenInvalidPtr_whenCallingGet_thenReturnsNullptr) { |
145 | intrusive_ptr<SomeClass1Parameter> obj; |
146 | EXPECT_EQ(nullptr, obj.get()); |
147 | } |
148 | |
149 | TEST(IntrusivePtrTest, givenNullptr_whenCallingGet_thenReturnsNullptr) { |
150 | intrusive_ptr<SomeClass1Parameter> obj(nullptr); |
151 | EXPECT_EQ(nullptr, obj.get()); |
152 | } |
153 | |
154 | TEST(IntrusivePtrTest, givenValidPtr_whenDereferencing_thenReturnsObject) { |
155 | intrusive_ptr<SomeClass1Parameter> obj = |
156 | make_intrusive<SomeClass1Parameter>(5); |
157 | EXPECT_EQ(5, (*obj).param); |
158 | } |
159 | |
160 | TEST(IntrusivePtrTest, givenValidPtr_whenConstDereferencing_thenReturnsObject) { |
161 | const intrusive_ptr<SomeClass1Parameter> obj = |
162 | make_intrusive<SomeClass1Parameter>(5); |
163 | EXPECT_EQ(5, (*obj).param); |
164 | } |
165 | |
166 | TEST(IntrusivePtrTest, givenValidPtr_whenArrowDereferencing_thenReturnsObject) { |
167 | intrusive_ptr<SomeClass1Parameter> obj = |
168 | make_intrusive<SomeClass1Parameter>(3); |
169 | EXPECT_EQ(3, obj->param); |
170 | } |
171 | |
172 | TEST( |
173 | IntrusivePtrTest, |
174 | givenValidPtr_whenConstArrowDereferencing_thenReturnsObject) { |
175 | const intrusive_ptr<SomeClass1Parameter> obj = |
176 | make_intrusive<SomeClass1Parameter>(3); |
177 | EXPECT_EQ(3, obj->param); |
178 | } |
179 | |
180 | TEST(IntrusivePtrTest, givenValidPtr_whenMoveAssigning_thenPointsToSameObject) { |
181 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
182 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
183 | SomeClass* obj1ptr = obj1.get(); |
184 | obj2 = std::move(obj1); |
185 | EXPECT_EQ(obj1ptr, obj2.get()); |
186 | } |
187 | |
188 | TEST(IntrusivePtrTest, givenValidPtr_whenMoveAssigning_thenOldInstanceInvalid) { |
189 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
190 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
191 | obj2 = std::move(obj1); |
192 | // NOLINTNEXTLINE(clang-analyzer-cplusplus.Move,bugprone-use-after-move) |
193 | EXPECT_FALSE(obj1.defined()); |
194 | } |
195 | |
196 | TEST( |
197 | IntrusivePtrTest, |
198 | givenValidPtr_whenMoveAssigningToSelf_thenPointsToSameObject) { |
199 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
200 | SomeClass* obj1ptr = obj1.get(); |
201 | obj1 = std::move(obj1); |
202 | // NOLINTNEXTLINE(bugprone-use-after-move) |
203 | EXPECT_EQ(obj1ptr, obj1.get()); |
204 | } |
205 | |
206 | TEST(IntrusivePtrTest, givenValidPtr_whenMoveAssigningToSelf_thenStaysValid) { |
207 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
208 | obj1 = std::move(obj1); |
209 | // NOLINTNEXTLINE(bugprone-use-after-move) |
210 | EXPECT_TRUE(obj1.defined()); |
211 | } |
212 | |
213 | TEST( |
214 | IntrusivePtrTest, |
215 | givenInvalidPtr_whenMoveAssigningToSelf_thenStaysInvalid) { |
216 | intrusive_ptr<SomeClass> obj1; |
217 | obj1 = std::move(obj1); |
218 | // NOLINTNEXTLINE(bugprone-use-after-move) |
219 | EXPECT_FALSE(obj1.defined()); |
220 | } |
221 | |
222 | TEST( |
223 | IntrusivePtrTest, |
224 | givenInvalidPtr_whenMoveAssigning_thenNewInstanceIsValid) { |
225 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
226 | intrusive_ptr<SomeClass> obj2; |
227 | obj2 = std::move(obj1); |
228 | EXPECT_TRUE(obj2.defined()); |
229 | } |
230 | |
231 | TEST( |
232 | IntrusivePtrTest, |
233 | givenInvalidPtr_whenMoveAssigning_thenPointsToSameObject) { |
234 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
235 | intrusive_ptr<SomeClass> obj2; |
236 | SomeClass* obj1ptr = obj1.get(); |
237 | obj2 = std::move(obj1); |
238 | EXPECT_EQ(obj1ptr, obj2.get()); |
239 | } |
240 | |
241 | TEST( |
242 | IntrusivePtrTest, |
243 | givenValidPtr_whenMoveAssigningFromInvalidPtr_thenNewInstanceIsInvalid) { |
244 | intrusive_ptr<SomeClass> obj1; |
245 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
246 | EXPECT_TRUE(obj2.defined()); |
247 | obj2 = std::move(obj1); |
248 | EXPECT_FALSE(obj2.defined()); |
249 | } |
250 | |
251 | TEST( |
252 | IntrusivePtrTest, |
253 | givenValidPtr_whenMoveAssigningToBaseClass_thenPointsToSameObject) { |
254 | intrusive_ptr<SomeChildClass> obj1 = make_intrusive<SomeChildClass>(1); |
255 | intrusive_ptr<SomeBaseClass> obj2 = make_intrusive<SomeBaseClass>(2); |
256 | SomeBaseClass* obj1ptr = obj1.get(); |
257 | obj2 = std::move(obj1); |
258 | EXPECT_EQ(obj1ptr, obj2.get()); |
259 | EXPECT_EQ(1, obj2->v); |
260 | } |
261 | |
262 | TEST( |
263 | IntrusivePtrTest, |
264 | givenValidPtr_whenMoveAssigningToBaseClass_thenOldInstanceInvalid) { |
265 | intrusive_ptr<SomeChildClass> obj1 = make_intrusive<SomeChildClass>(1); |
266 | intrusive_ptr<SomeBaseClass> obj2 = make_intrusive<SomeBaseClass>(2); |
267 | obj2 = std::move(obj1); |
268 | // NOLINTNEXTLINE(bugprone-use-after-move) |
269 | EXPECT_FALSE(obj1.defined()); |
270 | } |
271 | |
272 | TEST( |
273 | IntrusivePtrTest, |
274 | givenInvalidPtr_whenMoveAssigningToBaseClass_thenNewInstanceIsValid) { |
275 | intrusive_ptr<SomeChildClass> obj1 = make_intrusive<SomeChildClass>(5); |
276 | intrusive_ptr<SomeBaseClass> obj2; |
277 | obj2 = std::move(obj1); |
278 | EXPECT_TRUE(obj2.defined()); |
279 | } |
280 | |
281 | TEST( |
282 | IntrusivePtrTest, |
283 | givenInvalidPtr_whenMoveAssigningToBaseClass_thenPointsToSameObject) { |
284 | intrusive_ptr<SomeChildClass> obj1 = make_intrusive<SomeChildClass>(5); |
285 | intrusive_ptr<SomeBaseClass> obj2; |
286 | SomeBaseClass* obj1ptr = obj1.get(); |
287 | obj2 = std::move(obj1); |
288 | EXPECT_EQ(obj1ptr, obj2.get()); |
289 | EXPECT_EQ(5, obj2->v); |
290 | } |
291 | |
292 | TEST( |
293 | IntrusivePtrTest, |
294 | givenInvalidPtr_whenMoveAssigningInvalidPtrToBaseClass_thenNewInstanceIsValid) { |
295 | intrusive_ptr<SomeChildClass> obj1; |
296 | intrusive_ptr<SomeBaseClass> obj2 = make_intrusive<SomeBaseClass>(2); |
297 | EXPECT_TRUE(obj2.defined()); |
298 | obj2 = std::move(obj1); |
299 | EXPECT_FALSE(obj2.defined()); |
300 | } |
301 | |
302 | TEST( |
303 | IntrusivePtrTest, |
304 | givenNullPtr_whenMoveAssigningToDifferentNullptr_thenHasNewNullptr) { |
305 | intrusive_ptr<SomeClass, NullType1> obj1; |
306 | intrusive_ptr<SomeClass, NullType2> obj2; |
307 | obj2 = std::move(obj1); |
308 | EXPECT_NE(NullType1::singleton(), NullType2::singleton()); |
309 | // NOLINTNEXTLINE(bugprone-use-after-move) |
310 | EXPECT_EQ(NullType1::singleton(), obj1.get()); |
311 | EXPECT_EQ(NullType2::singleton(), obj2.get()); |
312 | EXPECT_FALSE(obj1.defined()); |
313 | EXPECT_FALSE(obj2.defined()); |
314 | } |
315 | |
316 | TEST(IntrusivePtrTest, givenValidPtr_whenCopyAssigning_thenPointsToSameObject) { |
317 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
318 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
319 | SomeClass* obj1ptr = obj1.get(); |
320 | obj2 = obj1; |
321 | EXPECT_EQ(obj1ptr, obj2.get()); |
322 | } |
323 | |
324 | TEST(IntrusivePtrTest, givenValidPtr_whenCopyAssigning_thenOldInstanceValid) { |
325 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
326 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
327 | obj2 = obj1; |
328 | EXPECT_TRUE(obj1.defined()); |
329 | } |
330 | |
331 | TEST( |
332 | IntrusivePtrTest, |
333 | givenValidPtr_whenCopyAssigningToSelf_thenPointsToSameObject) { |
334 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
335 | SomeClass* obj1ptr = obj1.get(); |
336 | // NOLINTNEXTLINE(clang-diagnostic-self-assign-overloaded) |
337 | obj1 = obj1; |
338 | EXPECT_EQ(obj1ptr, obj1.get()); |
339 | } |
340 | |
341 | TEST(IntrusivePtrTest, givenValidPtr_whenCopyAssigningToSelf_thenStaysValid) { |
342 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
343 | // NOLINTNEXTLINE(clang-diagnostic-self-assign-overloaded) |
344 | obj1 = obj1; |
345 | EXPECT_TRUE(obj1.defined()); |
346 | } |
347 | |
348 | TEST( |
349 | IntrusivePtrTest, |
350 | givenInvalidPtr_whenCopyAssigningToSelf_thenStaysInvalid) { |
351 | intrusive_ptr<SomeClass> obj1; |
352 | // NOLINTNEXTLINE(clang-diagnostic-self-assign-overloaded) |
353 | obj1 = obj1; |
354 | EXPECT_FALSE(obj1.defined()); |
355 | } |
356 | |
357 | TEST( |
358 | IntrusivePtrTest, |
359 | givenInvalidPtr_whenCopyAssigning_thenNewInstanceIsValid) { |
360 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
361 | intrusive_ptr<SomeClass> obj2; |
362 | obj2 = obj1; |
363 | EXPECT_TRUE(obj2.defined()); |
364 | } |
365 | |
366 | TEST( |
367 | IntrusivePtrTest, |
368 | givenValidPtr_whenCopyAssigningToBaseClass_thenPointsToSameObject) { |
369 | intrusive_ptr<SomeChildClass> child = make_intrusive<SomeChildClass>(3); |
370 | intrusive_ptr<SomeBaseClass> base = make_intrusive<SomeBaseClass>(10); |
371 | base = child; |
372 | EXPECT_EQ(3, base->v); |
373 | } |
374 | |
375 | TEST( |
376 | IntrusivePtrTest, |
377 | givenValidPtr_whenCopyAssigningToBaseClass_thenOldInstanceInvalid) { |
378 | intrusive_ptr<SomeChildClass> obj1 = make_intrusive<SomeChildClass>(3); |
379 | intrusive_ptr<SomeBaseClass> obj2 = make_intrusive<SomeBaseClass>(10); |
380 | obj2 = obj1; |
381 | EXPECT_TRUE(obj1.defined()); |
382 | } |
383 | |
384 | TEST( |
385 | IntrusivePtrTest, |
386 | givenInvalidPtr_whenCopyAssigningToBaseClass_thenNewInstanceIsValid) { |
387 | intrusive_ptr<SomeChildClass> obj1 = make_intrusive<SomeChildClass>(5); |
388 | intrusive_ptr<SomeBaseClass> obj2; |
389 | obj2 = obj1; |
390 | EXPECT_TRUE(obj2.defined()); |
391 | } |
392 | |
393 | TEST( |
394 | IntrusivePtrTest, |
395 | givenInvalidPtr_whenCopyAssigningToBaseClass_thenPointsToSameObject) { |
396 | intrusive_ptr<SomeChildClass> obj1 = make_intrusive<SomeChildClass>(5); |
397 | intrusive_ptr<SomeBaseClass> obj2; |
398 | SomeBaseClass* obj1ptr = obj1.get(); |
399 | obj2 = obj1; |
400 | EXPECT_EQ(obj1ptr, obj2.get()); |
401 | EXPECT_EQ(5, obj2->v); |
402 | } |
403 | |
404 | TEST( |
405 | IntrusivePtrTest, |
406 | givenPtr_whenCopyAssigningInvalidPtrToBaseClass_thenNewInstanceIsInvalid) { |
407 | intrusive_ptr<SomeChildClass> obj1; |
408 | intrusive_ptr<SomeBaseClass> obj2 = make_intrusive<SomeBaseClass>(2); |
409 | EXPECT_TRUE(obj2.defined()); |
410 | obj2 = obj1; |
411 | EXPECT_FALSE(obj2.defined()); |
412 | } |
413 | |
414 | TEST( |
415 | IntrusivePtrTest, |
416 | givenNullPtr_whenCopyAssigningToDifferentNullptr_thenHasNewNullptr) { |
417 | intrusive_ptr<SomeClass, NullType1> obj1; |
418 | intrusive_ptr<SomeClass, NullType2> obj2; |
419 | obj2 = obj1; |
420 | EXPECT_NE(NullType1::singleton(), NullType2::singleton()); |
421 | EXPECT_EQ(NullType1::singleton(), obj1.get()); |
422 | EXPECT_EQ(NullType2::singleton(), obj2.get()); |
423 | EXPECT_FALSE(obj1.defined()); |
424 | EXPECT_FALSE(obj2.defined()); |
425 | } |
426 | |
427 | TEST(IntrusivePtrTest, givenPtr_whenMoveConstructing_thenPointsToSameObject) { |
428 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
429 | SomeClass* obj1ptr = obj1.get(); |
430 | intrusive_ptr<SomeClass> obj2 = std::move(obj1); |
431 | EXPECT_EQ(obj1ptr, obj2.get()); |
432 | } |
433 | |
434 | TEST(IntrusivePtrTest, givenPtr_whenMoveConstructing_thenOldInstanceInvalid) { |
435 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
436 | intrusive_ptr<SomeClass> obj2 = std::move(obj1); |
437 | // NOLINTNEXTLINE(clang-analyzer-cplusplus.Move,bugprone-use-after-move) |
438 | EXPECT_FALSE(obj1.defined()); |
439 | } |
440 | |
441 | TEST(IntrusivePtrTest, givenPtr_whenMoveConstructing_thenNewInstanceValid) { |
442 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
443 | intrusive_ptr<SomeClass> obj2 = std::move(obj1); |
444 | EXPECT_TRUE(obj2.defined()); |
445 | } |
446 | |
447 | TEST( |
448 | IntrusivePtrTest, |
449 | givenPtr_whenMoveConstructingFromInvalidPtr_thenNewInstanceInvalid) { |
450 | intrusive_ptr<SomeClass> obj1; |
451 | intrusive_ptr<SomeClass> obj2 = std::move(obj1); |
452 | EXPECT_FALSE(obj2.defined()); |
453 | } |
454 | |
455 | TEST( |
456 | IntrusivePtrTest, |
457 | givenPtr_whenMoveConstructingToBaseClass_thenPointsToSameObject) { |
458 | intrusive_ptr<SomeChildClass> child = make_intrusive<SomeChildClass>(3); |
459 | SomeBaseClass* objptr = child.get(); |
460 | intrusive_ptr<SomeBaseClass> base = std::move(child); |
461 | EXPECT_EQ(3, base->v); |
462 | EXPECT_EQ(objptr, base.get()); |
463 | } |
464 | |
465 | TEST( |
466 | IntrusivePtrTest, |
467 | givenPtr_whenMoveConstructingToBaseClass_thenOldInstanceInvalid) { |
468 | intrusive_ptr<SomeChildClass> child = make_intrusive<SomeChildClass>(3); |
469 | intrusive_ptr<SomeBaseClass> base = std::move(child); |
470 | // NOLINTNEXTLINE(bugprone-use-after-move) |
471 | EXPECT_FALSE(child.defined()); |
472 | } |
473 | |
474 | TEST( |
475 | IntrusivePtrTest, |
476 | givenPtr_whenMoveConstructingToBaseClass_thenNewInstanceValid) { |
477 | intrusive_ptr<SomeChildClass> obj1 = make_intrusive<SomeChildClass>(2); |
478 | intrusive_ptr<SomeBaseClass> obj2 = std::move(obj1); |
479 | EXPECT_TRUE(obj2.defined()); |
480 | } |
481 | |
482 | TEST( |
483 | IntrusivePtrTest, |
484 | givenPtr_whenMoveConstructingToBaseClassFromInvalidPtr_thenNewInstanceInvalid) { |
485 | intrusive_ptr<SomeChildClass> obj1; |
486 | intrusive_ptr<SomeBaseClass> obj2 = std::move(obj1); |
487 | EXPECT_FALSE(obj2.defined()); |
488 | } |
489 | |
490 | TEST( |
491 | IntrusivePtrTest, |
492 | givenNullPtr_whenMoveConstructingToDifferentNullptr_thenHasNewNullptr) { |
493 | intrusive_ptr<SomeClass, NullType1> obj1; |
494 | intrusive_ptr<SomeClass, NullType2> obj2 = std::move(obj1); |
495 | EXPECT_NE(NullType1::singleton(), NullType2::singleton()); |
496 | // NOLINTNEXTLINE(bugprone-use-after-move) |
497 | EXPECT_EQ(NullType1::singleton(), obj1.get()); |
498 | EXPECT_EQ(NullType2::singleton(), obj2.get()); |
499 | EXPECT_FALSE(obj1.defined()); |
500 | EXPECT_FALSE(obj2.defined()); |
501 | } |
502 | |
503 | TEST(IntrusivePtrTest, givenPtr_whenCopyConstructing_thenPointsToSameObject) { |
504 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
505 | SomeClass* obj1ptr = obj1.get(); |
506 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
507 | intrusive_ptr<SomeClass> obj2 = obj1; |
508 | EXPECT_EQ(obj1ptr, obj2.get()); |
509 | EXPECT_TRUE(obj1.defined()); |
510 | } |
511 | |
512 | TEST(IntrusivePtrTest, givenPtr_whenCopyConstructing_thenOldInstanceValid) { |
513 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
514 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
515 | intrusive_ptr<SomeClass> obj2 = obj1; |
516 | EXPECT_TRUE(obj1.defined()); |
517 | } |
518 | |
519 | TEST(IntrusivePtrTest, givenPtr_whenCopyConstructing_thenNewInstanceValid) { |
520 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
521 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
522 | intrusive_ptr<SomeClass> obj2 = obj1; |
523 | EXPECT_TRUE(obj2.defined()); |
524 | } |
525 | |
526 | TEST( |
527 | IntrusivePtrTest, |
528 | givenPtr_whenCopyConstructingFromInvalidPtr_thenNewInstanceInvalid) { |
529 | intrusive_ptr<SomeClass> obj1; |
530 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
531 | intrusive_ptr<SomeClass> obj2 = obj1; |
532 | EXPECT_FALSE(obj2.defined()); |
533 | } |
534 | |
535 | TEST( |
536 | IntrusivePtrTest, |
537 | givenPtr_whenCopyConstructingToBaseClass_thenPointsToSameObject) { |
538 | intrusive_ptr<SomeChildClass> child = make_intrusive<SomeChildClass>(3); |
539 | SomeBaseClass* objptr = child.get(); |
540 | intrusive_ptr<SomeBaseClass> base = child; |
541 | EXPECT_EQ(3, base->v); |
542 | EXPECT_EQ(objptr, base.get()); |
543 | } |
544 | |
545 | TEST( |
546 | IntrusivePtrTest, |
547 | givenPtr_whenCopyConstructingToBaseClass_thenOldInstanceInvalid) { |
548 | intrusive_ptr<SomeChildClass> child = make_intrusive<SomeChildClass>(3); |
549 | intrusive_ptr<SomeBaseClass> base = child; |
550 | EXPECT_TRUE(child.defined()); |
551 | } |
552 | |
553 | TEST( |
554 | IntrusivePtrTest, |
555 | givenPtr_whenCopyConstructingToBaseClass_thenNewInstanceInvalid) { |
556 | intrusive_ptr<SomeChildClass> child = make_intrusive<SomeChildClass>(3); |
557 | intrusive_ptr<SomeBaseClass> base = child; |
558 | EXPECT_TRUE(base.defined()); |
559 | } |
560 | |
561 | TEST( |
562 | IntrusivePtrTest, |
563 | givenPtr_whenCopyConstructingToBaseClassFromInvalidPtr_thenNewInstanceInvalid) { |
564 | intrusive_ptr<SomeChildClass> obj1; |
565 | intrusive_ptr<SomeBaseClass> obj2 = obj1; |
566 | EXPECT_FALSE(obj2.defined()); |
567 | } |
568 | |
569 | TEST( |
570 | IntrusivePtrTest, |
571 | givenNullPtr_whenCopyConstructingToDifferentNullptr_thenHasNewNullptr) { |
572 | intrusive_ptr<SomeClass, NullType1> obj1; |
573 | intrusive_ptr<SomeClass, NullType2> obj2 = obj1; |
574 | EXPECT_NE(NullType1::singleton(), NullType2::singleton()); |
575 | EXPECT_EQ(NullType1::singleton(), obj1.get()); |
576 | EXPECT_EQ(NullType2::singleton(), obj2.get()); |
577 | EXPECT_FALSE(obj1.defined()); |
578 | EXPECT_FALSE(obj2.defined()); |
579 | } |
580 | |
581 | TEST(IntrusivePtrTest, SwapFunction) { |
582 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
583 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
584 | SomeClass* obj1ptr = obj1.get(); |
585 | SomeClass* obj2ptr = obj2.get(); |
586 | swap(obj1, obj2); |
587 | EXPECT_EQ(obj2ptr, obj1.get()); |
588 | EXPECT_EQ(obj1ptr, obj2.get()); |
589 | } |
590 | |
591 | TEST(IntrusivePtrTest, SwapMethod) { |
592 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
593 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
594 | SomeClass* obj1ptr = obj1.get(); |
595 | SomeClass* obj2ptr = obj2.get(); |
596 | obj1.swap(obj2); |
597 | EXPECT_EQ(obj2ptr, obj1.get()); |
598 | EXPECT_EQ(obj1ptr, obj2.get()); |
599 | } |
600 | |
601 | TEST(IntrusivePtrTest, SwapFunctionFromInvalid) { |
602 | intrusive_ptr<SomeClass> obj1; |
603 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
604 | SomeClass* obj2ptr = obj2.get(); |
605 | swap(obj1, obj2); |
606 | EXPECT_EQ(obj2ptr, obj1.get()); |
607 | EXPECT_TRUE(obj1.defined()); |
608 | EXPECT_FALSE(obj2.defined()); |
609 | } |
610 | |
611 | TEST(IntrusivePtrTest, SwapMethodFromInvalid) { |
612 | intrusive_ptr<SomeClass> obj1; |
613 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
614 | SomeClass* obj2ptr = obj2.get(); |
615 | obj1.swap(obj2); |
616 | EXPECT_EQ(obj2ptr, obj1.get()); |
617 | EXPECT_TRUE(obj1.defined()); |
618 | EXPECT_FALSE(obj2.defined()); |
619 | } |
620 | |
621 | TEST(IntrusivePtrTest, SwapFunctionWithInvalid) { |
622 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
623 | intrusive_ptr<SomeClass> obj2; |
624 | SomeClass* obj1ptr = obj1.get(); |
625 | swap(obj1, obj2); |
626 | EXPECT_FALSE(obj1.defined()); |
627 | EXPECT_TRUE(obj2.defined()); |
628 | EXPECT_EQ(obj1ptr, obj2.get()); |
629 | } |
630 | |
631 | TEST(IntrusivePtrTest, SwapMethodWithInvalid) { |
632 | intrusive_ptr<SomeClass> obj1 = make_intrusive<SomeClass>(); |
633 | intrusive_ptr<SomeClass> obj2; |
634 | SomeClass* obj1ptr = obj1.get(); |
635 | obj1.swap(obj2); |
636 | EXPECT_FALSE(obj1.defined()); |
637 | EXPECT_TRUE(obj2.defined()); |
638 | EXPECT_EQ(obj1ptr, obj2.get()); |
639 | } |
640 | |
641 | TEST(IntrusivePtrTest, SwapFunctionInvalidWithInvalid) { |
642 | intrusive_ptr<SomeClass> obj1; |
643 | intrusive_ptr<SomeClass> obj2; |
644 | swap(obj1, obj2); |
645 | EXPECT_FALSE(obj1.defined()); |
646 | EXPECT_FALSE(obj2.defined()); |
647 | } |
648 | |
649 | TEST(IntrusivePtrTest, SwapMethodInvalidWithInvalid) { |
650 | intrusive_ptr<SomeClass> obj1; |
651 | intrusive_ptr<SomeClass> obj2; |
652 | obj1.swap(obj2); |
653 | EXPECT_FALSE(obj1.defined()); |
654 | EXPECT_FALSE(obj2.defined()); |
655 | } |
656 | |
657 | TEST(IntrusivePtrTest, CanBePutInContainer) { |
658 | std::vector<intrusive_ptr<SomeClass1Parameter>> vec; |
659 | vec.push_back(make_intrusive<SomeClass1Parameter>(5)); |
660 | EXPECT_EQ(5, vec[0]->param); |
661 | } |
662 | |
663 | TEST(IntrusivePtrTest, CanBePutInSet) { |
664 | std::set<intrusive_ptr<SomeClass1Parameter>> set; |
665 | set.insert(make_intrusive<SomeClass1Parameter>(5)); |
666 | EXPECT_EQ(5, (*set.begin())->param); |
667 | } |
668 | |
669 | TEST(IntrusivePtrTest, CanBePutInUnorderedSet) { |
670 | std::unordered_set<intrusive_ptr<SomeClass1Parameter>> set; |
671 | set.insert(make_intrusive<SomeClass1Parameter>(5)); |
672 | EXPECT_EQ(5, (*set.begin())->param); |
673 | } |
674 | |
675 | TEST(IntrusivePtrTest, CanBePutInMap) { |
676 | std::map< |
677 | intrusive_ptr<SomeClass1Parameter>, |
678 | intrusive_ptr<SomeClass1Parameter>> |
679 | map; |
680 | map.insert(std::make_pair( |
681 | make_intrusive<SomeClass1Parameter>(5), |
682 | make_intrusive<SomeClass1Parameter>(3))); |
683 | EXPECT_EQ(5, map.begin()->first->param); |
684 | EXPECT_EQ(3, map.begin()->second->param); |
685 | } |
686 | |
687 | TEST(IntrusivePtrTest, CanBePutInUnorderedMap) { |
688 | std::unordered_map< |
689 | intrusive_ptr<SomeClass1Parameter>, |
690 | intrusive_ptr<SomeClass1Parameter>> |
691 | map; |
692 | map.insert(std::make_pair( |
693 | make_intrusive<SomeClass1Parameter>(3), |
694 | make_intrusive<SomeClass1Parameter>(5))); |
695 | EXPECT_EQ(3, map.begin()->first->param); |
696 | EXPECT_EQ(5, map.begin()->second->param); |
697 | } |
698 | |
699 | TEST(IntrusivePtrTest, Equality_AfterCopyConstructor) { |
700 | intrusive_ptr<SomeClass> var1 = make_intrusive<SomeClass>(); |
701 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
702 | intrusive_ptr<SomeClass> var2 = var1; |
703 | EXPECT_TRUE(var1 == var2); |
704 | EXPECT_FALSE(var1 != var2); |
705 | } |
706 | |
707 | TEST(IntrusivePtrTest, Equality_AfterCopyAssignment) { |
708 | intrusive_ptr<SomeClass> var1 = make_intrusive<SomeClass>(); |
709 | intrusive_ptr<SomeClass> var2 = make_intrusive<SomeClass>(); |
710 | var2 = var1; |
711 | EXPECT_TRUE(var1 == var2); |
712 | EXPECT_FALSE(var1 != var2); |
713 | } |
714 | |
715 | TEST(IntrusivePtrTest, Equality_Nullptr) { |
716 | intrusive_ptr<SomeClass> var1; |
717 | intrusive_ptr<SomeClass> var2; |
718 | EXPECT_TRUE(var1 == var2); |
719 | EXPECT_FALSE(var1 != var2); |
720 | } |
721 | |
722 | TEST(IntrusivePtrTest, Inequality) { |
723 | intrusive_ptr<SomeClass> var1 = make_intrusive<SomeClass>(); |
724 | intrusive_ptr<SomeClass> var2 = make_intrusive<SomeClass>(); |
725 | EXPECT_TRUE(var1 != var2); |
726 | EXPECT_FALSE(var1 == var2); |
727 | } |
728 | |
729 | TEST(IntrusivePtrTest, Inequality_NullptrLeft) { |
730 | intrusive_ptr<SomeClass> var1; |
731 | intrusive_ptr<SomeClass> var2 = make_intrusive<SomeClass>(); |
732 | EXPECT_TRUE(var1 != var2); |
733 | EXPECT_FALSE(var1 == var2); |
734 | } |
735 | |
736 | TEST(IntrusivePtrTest, Inequality_NullptrRight) { |
737 | intrusive_ptr<SomeClass> var1 = make_intrusive<SomeClass>(); |
738 | intrusive_ptr<SomeClass> var2; |
739 | EXPECT_TRUE(var1 != var2); |
740 | EXPECT_FALSE(var1 == var2); |
741 | } |
742 | |
743 | TEST(IntrusivePtrTest, HashIsDifferent) { |
744 | intrusive_ptr<SomeClass> var1 = make_intrusive<SomeClass>(); |
745 | intrusive_ptr<SomeClass> var2 = make_intrusive<SomeClass>(); |
746 | EXPECT_NE( |
747 | std::hash<intrusive_ptr<SomeClass>>()(var1), |
748 | std::hash<intrusive_ptr<SomeClass>>()(var2)); |
749 | } |
750 | |
751 | TEST(IntrusivePtrTest, HashIsDifferent_ValidAndInvalid) { |
752 | intrusive_ptr<SomeClass> var1; |
753 | intrusive_ptr<SomeClass> var2 = make_intrusive<SomeClass>(); |
754 | EXPECT_NE( |
755 | std::hash<intrusive_ptr<SomeClass>>()(var1), |
756 | std::hash<intrusive_ptr<SomeClass>>()(var2)); |
757 | } |
758 | |
759 | TEST(IntrusivePtrTest, HashIsSame_AfterCopyConstructor) { |
760 | intrusive_ptr<SomeClass> var1 = make_intrusive<SomeClass>(); |
761 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
762 | intrusive_ptr<SomeClass> var2 = var1; |
763 | EXPECT_EQ( |
764 | std::hash<intrusive_ptr<SomeClass>>()(var1), |
765 | std::hash<intrusive_ptr<SomeClass>>()(var2)); |
766 | } |
767 | |
768 | TEST(IntrusivePtrTest, HashIsSame_AfterCopyAssignment) { |
769 | intrusive_ptr<SomeClass> var1 = make_intrusive<SomeClass>(); |
770 | intrusive_ptr<SomeClass> var2 = make_intrusive<SomeClass>(); |
771 | var2 = var1; |
772 | EXPECT_EQ( |
773 | std::hash<intrusive_ptr<SomeClass>>()(var1), |
774 | std::hash<intrusive_ptr<SomeClass>>()(var2)); |
775 | } |
776 | |
777 | TEST(IntrusivePtrTest, HashIsSame_BothNullptr) { |
778 | intrusive_ptr<SomeClass> var1; |
779 | intrusive_ptr<SomeClass> var2; |
780 | EXPECT_EQ( |
781 | std::hash<intrusive_ptr<SomeClass>>()(var1), |
782 | std::hash<intrusive_ptr<SomeClass>>()(var2)); |
783 | } |
784 | |
785 | TEST(IntrusivePtrTest, OneIsLess) { |
786 | intrusive_ptr<SomeClass> var1 = make_intrusive<SomeClass>(); |
787 | intrusive_ptr<SomeClass> var2 = make_intrusive<SomeClass>(); |
788 | EXPECT_TRUE( |
789 | // NOLINTNEXTLINE(modernize-use-transparent-functors) |
790 | std::less<intrusive_ptr<SomeClass>>()(var1, var2) != |
791 | // NOLINTNEXTLINE(modernize-use-transparent-functors) |
792 | std::less<intrusive_ptr<SomeClass>>()(var2, var1)); |
793 | } |
794 | |
795 | TEST(IntrusivePtrTest, NullptrIsLess1) { |
796 | intrusive_ptr<SomeClass> var1; |
797 | intrusive_ptr<SomeClass> var2 = make_intrusive<SomeClass>(); |
798 | // NOLINTNEXTLINE(modernize-use-transparent-functors) |
799 | EXPECT_TRUE(std::less<intrusive_ptr<SomeClass>>()(var1, var2)); |
800 | } |
801 | |
802 | TEST(IntrusivePtrTest, NullptrIsLess2) { |
803 | intrusive_ptr<SomeClass> var1 = make_intrusive<SomeClass>(); |
804 | intrusive_ptr<SomeClass> var2; |
805 | // NOLINTNEXTLINE(modernize-use-transparent-functors) |
806 | EXPECT_FALSE(std::less<intrusive_ptr<SomeClass>>()(var1, var2)); |
807 | } |
808 | |
809 | TEST(IntrusivePtrTest, NullptrIsNotLessThanNullptr) { |
810 | intrusive_ptr<SomeClass> var1; |
811 | intrusive_ptr<SomeClass> var2; |
812 | // NOLINTNEXTLINE(modernize-use-transparent-functors) |
813 | EXPECT_FALSE(std::less<intrusive_ptr<SomeClass>>()(var1, var2)); |
814 | } |
815 | |
816 | TEST(IntrusivePtrTest, givenPtr_whenCallingReset_thenIsInvalid) { |
817 | auto obj = make_intrusive<SomeClass>(); |
818 | EXPECT_TRUE(obj.defined()); |
819 | obj.reset(); |
820 | EXPECT_FALSE(obj.defined()); |
821 | } |
822 | |
823 | TEST(IntrusivePtrTest, givenPtr_whenCallingReset_thenHoldsNullptr) { |
824 | auto obj = make_intrusive<SomeClass>(); |
825 | EXPECT_NE(nullptr, obj.get()); |
826 | obj.reset(); |
827 | EXPECT_EQ(nullptr, obj.get()); |
828 | } |
829 | |
830 | TEST(IntrusivePtrTest, givenPtr_whenDestructed_thenDestructsObject) { |
831 | bool resourcesReleased = false; |
832 | bool wasDestructed = false; |
833 | { |
834 | auto obj = |
835 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
836 | EXPECT_FALSE(resourcesReleased); |
837 | EXPECT_FALSE(wasDestructed); |
838 | } |
839 | EXPECT_TRUE(resourcesReleased); |
840 | EXPECT_TRUE(wasDestructed); |
841 | } |
842 | |
843 | TEST( |
844 | IntrusivePtrTest, |
845 | givenPtr_whenMoveConstructed_thenDestructsObjectAfterSecondDestructed) { |
846 | bool resourcesReleased = false; |
847 | bool wasDestructed = false; |
848 | auto obj = |
849 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
850 | { |
851 | auto obj2 = std::move(obj); |
852 | EXPECT_FALSE(resourcesReleased); |
853 | EXPECT_FALSE(wasDestructed); |
854 | } |
855 | EXPECT_TRUE(resourcesReleased); |
856 | EXPECT_TRUE(wasDestructed); |
857 | } |
858 | |
859 | TEST( |
860 | IntrusivePtrTest, |
861 | givenPtr_whenMoveConstructedToBaseClass_thenDestructsObjectAfterSecondDestructed) { |
862 | bool resourcesReleased = false; |
863 | bool wasDestructed = false; |
864 | auto obj = |
865 | make_intrusive<ChildDestructableMock>(&resourcesReleased, &wasDestructed); |
866 | { |
867 | intrusive_ptr<DestructableMock> obj2 = std::move(obj); |
868 | EXPECT_FALSE(resourcesReleased); |
869 | EXPECT_FALSE(wasDestructed); |
870 | } |
871 | EXPECT_TRUE(resourcesReleased); |
872 | EXPECT_TRUE(wasDestructed); |
873 | } |
874 | |
875 | TEST(IntrusivePtrTest, givenPtr_whenMoveAssigned_thenDestructsOldObject) { |
876 | bool dummy = false; |
877 | bool resourcesReleased = false; |
878 | bool wasDestructed = false; |
879 | auto obj = make_intrusive<DestructableMock>(&dummy, &dummy); |
880 | { |
881 | auto obj2 = |
882 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
883 | EXPECT_FALSE(resourcesReleased); |
884 | EXPECT_FALSE(wasDestructed); |
885 | obj2 = std::move(obj); |
886 | EXPECT_TRUE(resourcesReleased); |
887 | EXPECT_TRUE(wasDestructed); |
888 | } |
889 | } |
890 | |
891 | TEST( |
892 | IntrusivePtrTest, |
893 | givenPtr_whenMoveAssignedToBaseClass_thenDestructsOldObject) { |
894 | bool dummy = false; |
895 | bool resourcesReleased = false; |
896 | bool wasDestructed = false; |
897 | auto obj = make_intrusive<ChildDestructableMock>(&dummy, &dummy); |
898 | { |
899 | auto obj2 = |
900 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
901 | EXPECT_FALSE(resourcesReleased); |
902 | EXPECT_FALSE(wasDestructed); |
903 | obj2 = std::move(obj); |
904 | EXPECT_TRUE(resourcesReleased); |
905 | EXPECT_TRUE(wasDestructed); |
906 | } |
907 | } |
908 | |
909 | TEST( |
910 | IntrusivePtrTest, |
911 | givenPtrWithCopy_whenMoveAssigned_thenDestructsOldObjectAfterCopyIsDestructed) { |
912 | bool dummy = false; |
913 | bool resourcesReleased = false; |
914 | bool wasDestructed = false; |
915 | auto obj = make_intrusive<DestructableMock>(&dummy, &dummy); |
916 | { |
917 | auto obj2 = |
918 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
919 | { |
920 | auto copy = obj2; |
921 | EXPECT_FALSE(resourcesReleased); |
922 | EXPECT_FALSE(wasDestructed); |
923 | obj2 = std::move(obj); |
924 | EXPECT_FALSE(resourcesReleased); |
925 | EXPECT_FALSE(wasDestructed); |
926 | } |
927 | EXPECT_TRUE(resourcesReleased); |
928 | EXPECT_TRUE(wasDestructed); |
929 | } |
930 | } |
931 | |
932 | TEST( |
933 | IntrusivePtrTest, |
934 | givenPtrWithBaseClassCopy_whenMoveAssigned_thenDestructsOldObjectAfterCopyIsDestructed) { |
935 | bool dummy = false; |
936 | bool resourcesReleased = false; |
937 | bool wasDestructed = false; |
938 | auto obj = make_intrusive<ChildDestructableMock>(&dummy, &dummy); |
939 | { |
940 | auto obj2 = make_intrusive<ChildDestructableMock>( |
941 | &resourcesReleased, &wasDestructed); |
942 | { |
943 | intrusive_ptr<DestructableMock> copy = obj2; |
944 | EXPECT_FALSE(resourcesReleased); |
945 | EXPECT_FALSE(wasDestructed); |
946 | obj2 = std::move(obj); |
947 | EXPECT_FALSE(resourcesReleased); |
948 | EXPECT_FALSE(wasDestructed); |
949 | } |
950 | EXPECT_TRUE(resourcesReleased); |
951 | EXPECT_TRUE(wasDestructed); |
952 | } |
953 | } |
954 | |
955 | TEST( |
956 | IntrusivePtrTest, |
957 | givenPtrWithCopy_whenMoveAssignedToBaseClass_thenDestructsOldObjectAfterCopyIsDestructed) { |
958 | bool dummy = false; |
959 | bool resourcesReleased = false; |
960 | bool wasDestructed = false; |
961 | auto obj = make_intrusive<ChildDestructableMock>(&dummy, &dummy); |
962 | { |
963 | auto obj2 = |
964 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
965 | { |
966 | intrusive_ptr<DestructableMock> copy = obj2; |
967 | EXPECT_FALSE(resourcesReleased); |
968 | EXPECT_FALSE(wasDestructed); |
969 | obj2 = std::move(obj); |
970 | EXPECT_FALSE(resourcesReleased); |
971 | EXPECT_FALSE(wasDestructed); |
972 | } |
973 | EXPECT_TRUE(resourcesReleased); |
974 | EXPECT_TRUE(wasDestructed); |
975 | } |
976 | } |
977 | |
978 | TEST( |
979 | IntrusivePtrTest, |
980 | givenPtr_whenMoveAssigned_thenDestructsObjectAfterSecondDestructed) { |
981 | bool dummy = false; |
982 | bool resourcesReleased = false; |
983 | bool wasDestructed = false; |
984 | auto obj = |
985 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
986 | { |
987 | auto obj2 = make_intrusive<DestructableMock>(&dummy, &dummy); |
988 | obj2 = std::move(obj); |
989 | EXPECT_FALSE(resourcesReleased); |
990 | EXPECT_FALSE(wasDestructed); |
991 | } |
992 | EXPECT_TRUE(resourcesReleased); |
993 | EXPECT_TRUE(wasDestructed); |
994 | } |
995 | |
996 | TEST( |
997 | IntrusivePtrTest, |
998 | givenPtr_whenMoveAssignedToBaseClass_thenDestructsObjectAfterSecondDestructed) { |
999 | bool dummy = false; |
1000 | bool resourcesReleased = false; |
1001 | bool wasDestructed = false; |
1002 | auto obj = |
1003 | make_intrusive<ChildDestructableMock>(&resourcesReleased, &wasDestructed); |
1004 | { |
1005 | auto obj2 = make_intrusive<DestructableMock>(&dummy, &dummy); |
1006 | obj2 = std::move(obj); |
1007 | EXPECT_FALSE(resourcesReleased); |
1008 | EXPECT_FALSE(wasDestructed); |
1009 | } |
1010 | EXPECT_TRUE(resourcesReleased); |
1011 | EXPECT_TRUE(wasDestructed); |
1012 | } |
1013 | |
1014 | TEST( |
1015 | IntrusivePtrTest, |
1016 | givenPtr_whenCopyConstructedAndDestructed_thenDestructsObjectAfterLastDestruction) { |
1017 | bool resourcesReleased = false; |
1018 | bool wasDestructed = false; |
1019 | { |
1020 | auto obj = |
1021 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
1022 | { |
1023 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
1024 | intrusive_ptr<DestructableMock> copy = obj; |
1025 | EXPECT_FALSE(resourcesReleased); |
1026 | EXPECT_FALSE(wasDestructed); |
1027 | } |
1028 | EXPECT_FALSE(resourcesReleased); |
1029 | EXPECT_FALSE(wasDestructed); |
1030 | } |
1031 | EXPECT_TRUE(resourcesReleased); |
1032 | EXPECT_TRUE(wasDestructed); |
1033 | } |
1034 | |
1035 | TEST( |
1036 | IntrusivePtrTest, |
1037 | givenPtr_whenCopyConstructedToBaseClassAndDestructed_thenDestructsObjectAfterLastDestruction) { |
1038 | bool resourcesReleased = false; |
1039 | bool wasDestructed = false; |
1040 | { |
1041 | auto obj = make_intrusive<ChildDestructableMock>( |
1042 | &resourcesReleased, &wasDestructed); |
1043 | { |
1044 | intrusive_ptr<DestructableMock> copy = obj; |
1045 | EXPECT_FALSE(resourcesReleased); |
1046 | EXPECT_FALSE(wasDestructed); |
1047 | } |
1048 | EXPECT_FALSE(resourcesReleased); |
1049 | EXPECT_FALSE(wasDestructed); |
1050 | } |
1051 | EXPECT_TRUE(resourcesReleased); |
1052 | EXPECT_TRUE(wasDestructed); |
1053 | } |
1054 | |
1055 | TEST( |
1056 | IntrusivePtrTest, |
1057 | givenPtr_whenCopyConstructedAndOriginalDestructed_thenDestructsObjectAfterLastDestruction) { |
1058 | bool resourcesReleased = false; |
1059 | bool wasDestructed = false; |
1060 | { |
1061 | auto obj = |
1062 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
1063 | intrusive_ptr<DestructableMock> copy = obj; |
1064 | obj.reset(); |
1065 | EXPECT_FALSE(resourcesReleased); |
1066 | EXPECT_FALSE(wasDestructed); |
1067 | } |
1068 | EXPECT_TRUE(resourcesReleased); |
1069 | EXPECT_TRUE(wasDestructed); |
1070 | } |
1071 | |
1072 | TEST( |
1073 | IntrusivePtrTest, |
1074 | givenPtr_whenCopyConstructedToBaseClassAndOriginalDestructed_thenDestructsObjectAfterLastDestruction) { |
1075 | bool resourcesReleased = false; |
1076 | bool wasDestructed = false; |
1077 | { |
1078 | auto obj = make_intrusive<ChildDestructableMock>( |
1079 | &resourcesReleased, &wasDestructed); |
1080 | intrusive_ptr<DestructableMock> copy = obj; |
1081 | obj.reset(); |
1082 | EXPECT_FALSE(resourcesReleased); |
1083 | EXPECT_FALSE(wasDestructed); |
1084 | } |
1085 | EXPECT_TRUE(resourcesReleased); |
1086 | EXPECT_TRUE(wasDestructed); |
1087 | } |
1088 | |
1089 | TEST( |
1090 | IntrusivePtrTest, |
1091 | givenPtr_whenCopyAssignedAndDestructed_thenDestructsObjectAfterLastDestruction) { |
1092 | bool resourcesReleased = false; |
1093 | bool wasDestructed = false; |
1094 | bool dummy = false; |
1095 | { |
1096 | auto obj = |
1097 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
1098 | { |
1099 | intrusive_ptr<DestructableMock> copy = |
1100 | make_intrusive<DestructableMock>(&dummy, &dummy); |
1101 | copy = obj; |
1102 | EXPECT_FALSE(resourcesReleased); |
1103 | EXPECT_FALSE(wasDestructed); |
1104 | } |
1105 | EXPECT_FALSE(resourcesReleased); |
1106 | EXPECT_FALSE(wasDestructed); |
1107 | } |
1108 | EXPECT_TRUE(resourcesReleased); |
1109 | EXPECT_TRUE(wasDestructed); |
1110 | } |
1111 | |
1112 | TEST( |
1113 | IntrusivePtrTest, |
1114 | givenPtr_whenCopyAssignedToBaseClassAndDestructed_thenDestructsObjectAfterLastDestruction) { |
1115 | bool resourcesReleased = false; |
1116 | bool wasDestructed = false; |
1117 | bool dummy = false; |
1118 | { |
1119 | auto obj = make_intrusive<ChildDestructableMock>( |
1120 | &resourcesReleased, &wasDestructed); |
1121 | { |
1122 | intrusive_ptr<DestructableMock> copy = |
1123 | make_intrusive<DestructableMock>(&dummy, &dummy); |
1124 | copy = obj; |
1125 | EXPECT_FALSE(resourcesReleased); |
1126 | EXPECT_FALSE(wasDestructed); |
1127 | } |
1128 | EXPECT_FALSE(resourcesReleased); |
1129 | EXPECT_FALSE(wasDestructed); |
1130 | } |
1131 | EXPECT_TRUE(resourcesReleased); |
1132 | EXPECT_TRUE(wasDestructed); |
1133 | } |
1134 | |
1135 | TEST( |
1136 | IntrusivePtrTest, |
1137 | givenPtr_whenCopyAssignedAndOriginalDestructed_thenDestructsObjectAfterLastDestruction) { |
1138 | bool resourcesReleased = false; |
1139 | bool wasDestructed = false; |
1140 | bool dummy = false; |
1141 | { |
1142 | auto copy = make_intrusive<DestructableMock>(&dummy, &dummy); |
1143 | { |
1144 | auto obj = |
1145 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
1146 | copy = obj; |
1147 | EXPECT_FALSE(resourcesReleased); |
1148 | EXPECT_FALSE(wasDestructed); |
1149 | } |
1150 | EXPECT_FALSE(resourcesReleased); |
1151 | EXPECT_FALSE(wasDestructed); |
1152 | } |
1153 | EXPECT_TRUE(resourcesReleased); |
1154 | EXPECT_TRUE(wasDestructed); |
1155 | } |
1156 | |
1157 | TEST( |
1158 | IntrusivePtrTest, |
1159 | givenPtr_whenCopyAssignedToBaseClassAndOriginalDestructed_thenDestructsObjectAfterLastDestruction) { |
1160 | bool wasDestructed = false; |
1161 | bool resourcesReleased = false; |
1162 | bool dummy = false; |
1163 | { |
1164 | auto copy = make_intrusive<DestructableMock>(&dummy, &dummy); |
1165 | { |
1166 | auto obj = make_intrusive<ChildDestructableMock>( |
1167 | &resourcesReleased, &wasDestructed); |
1168 | copy = obj; |
1169 | EXPECT_FALSE(resourcesReleased); |
1170 | EXPECT_FALSE(wasDestructed); |
1171 | } |
1172 | EXPECT_FALSE(resourcesReleased); |
1173 | EXPECT_FALSE(wasDestructed); |
1174 | } |
1175 | EXPECT_TRUE(resourcesReleased); |
1176 | EXPECT_TRUE(wasDestructed); |
1177 | } |
1178 | |
1179 | TEST(IntrusivePtrTest, givenPtr_whenCopyAssigned_thenDestructsOldObject) { |
1180 | bool dummy = false; |
1181 | bool resourcesReleased = false; |
1182 | bool wasDestructed = false; |
1183 | auto obj = make_intrusive<DestructableMock>(&dummy, &dummy); |
1184 | { |
1185 | auto obj2 = |
1186 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
1187 | EXPECT_FALSE(resourcesReleased); |
1188 | EXPECT_FALSE(wasDestructed); |
1189 | obj2 = obj; |
1190 | EXPECT_TRUE(resourcesReleased); |
1191 | EXPECT_TRUE(wasDestructed); |
1192 | } |
1193 | } |
1194 | |
1195 | TEST( |
1196 | IntrusivePtrTest, |
1197 | givenPtr_whenCopyAssignedToBaseClass_thenDestructsOldObject) { |
1198 | bool dummy = false; |
1199 | bool resourcesReleased = false; |
1200 | bool wasDestructed = false; |
1201 | auto obj = make_intrusive<ChildDestructableMock>(&dummy, &dummy); |
1202 | { |
1203 | auto obj2 = |
1204 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
1205 | EXPECT_FALSE(resourcesReleased); |
1206 | EXPECT_FALSE(wasDestructed); |
1207 | obj2 = obj; |
1208 | EXPECT_TRUE(resourcesReleased); |
1209 | EXPECT_TRUE(wasDestructed); |
1210 | } |
1211 | } |
1212 | |
1213 | TEST( |
1214 | IntrusivePtrTest, |
1215 | givenPtrWithCopy_whenCopyAssigned_thenDestructsOldObjectAfterCopyIsDestructed) { |
1216 | bool dummy = false; |
1217 | bool resourcesReleased = false; |
1218 | bool wasDestructed = false; |
1219 | auto obj = make_intrusive<DestructableMock>(&dummy, &dummy); |
1220 | { |
1221 | auto obj2 = |
1222 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
1223 | { |
1224 | auto copy = obj2; |
1225 | EXPECT_FALSE(resourcesReleased); |
1226 | EXPECT_FALSE(wasDestructed); |
1227 | obj2 = obj; |
1228 | EXPECT_FALSE(resourcesReleased); |
1229 | EXPECT_FALSE(wasDestructed); |
1230 | } |
1231 | EXPECT_TRUE(resourcesReleased); |
1232 | EXPECT_TRUE(wasDestructed); |
1233 | } |
1234 | } |
1235 | |
1236 | TEST( |
1237 | IntrusivePtrTest, |
1238 | givenPtrWithBaseClassCopy_whenCopyAssigned_thenDestructsOldObjectAfterCopyIsDestructed) { |
1239 | bool dummy = false; |
1240 | bool resourcesReleased = false; |
1241 | bool wasDestructed = false; |
1242 | auto obj = make_intrusive<ChildDestructableMock>(&dummy, &dummy); |
1243 | { |
1244 | auto obj2 = make_intrusive<ChildDestructableMock>( |
1245 | &resourcesReleased, &wasDestructed); |
1246 | { |
1247 | intrusive_ptr<DestructableMock> copy = obj2; |
1248 | EXPECT_FALSE(resourcesReleased); |
1249 | EXPECT_FALSE(wasDestructed); |
1250 | obj2 = obj; |
1251 | EXPECT_FALSE(resourcesReleased); |
1252 | EXPECT_FALSE(wasDestructed); |
1253 | } |
1254 | EXPECT_TRUE(resourcesReleased); |
1255 | EXPECT_TRUE(wasDestructed); |
1256 | } |
1257 | } |
1258 | |
1259 | TEST( |
1260 | IntrusivePtrTest, |
1261 | givenPtrWithCopy_whenCopyAssignedToBaseClass_thenDestructsOldObjectAfterCopyIsDestructed) { |
1262 | bool dummy = false; |
1263 | bool resourcesReleased = false; |
1264 | bool wasDestructed = false; |
1265 | auto obj = make_intrusive<ChildDestructableMock>(&dummy, &dummy); |
1266 | { |
1267 | auto obj2 = |
1268 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
1269 | { |
1270 | intrusive_ptr<DestructableMock> copy = obj2; |
1271 | EXPECT_FALSE(resourcesReleased); |
1272 | EXPECT_FALSE(wasDestructed); |
1273 | obj2 = obj; |
1274 | EXPECT_FALSE(resourcesReleased); |
1275 | EXPECT_FALSE(wasDestructed); |
1276 | } |
1277 | EXPECT_TRUE(resourcesReleased); |
1278 | EXPECT_TRUE(wasDestructed); |
1279 | } |
1280 | } |
1281 | |
1282 | TEST(IntrusivePtrTest, givenPtr_whenCallingReset_thenDestructs) { |
1283 | bool resourcesReleased = false; |
1284 | bool wasDestructed = false; |
1285 | auto obj = |
1286 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
1287 | EXPECT_FALSE(resourcesReleased); |
1288 | EXPECT_FALSE(wasDestructed); |
1289 | obj.reset(); |
1290 | EXPECT_TRUE(resourcesReleased); |
1291 | EXPECT_TRUE(wasDestructed); |
1292 | } |
1293 | |
1294 | TEST( |
1295 | IntrusivePtrTest, |
1296 | givenPtrWithCopy_whenCallingReset_thenDestructsAfterCopyDestructed) { |
1297 | bool resourcesReleased = false; |
1298 | bool wasDestructed = false; |
1299 | auto obj = |
1300 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
1301 | { |
1302 | auto copy = obj; |
1303 | obj.reset(); |
1304 | EXPECT_FALSE(resourcesReleased); |
1305 | EXPECT_FALSE(wasDestructed); |
1306 | copy.reset(); |
1307 | EXPECT_TRUE(resourcesReleased); |
1308 | EXPECT_TRUE(wasDestructed); |
1309 | } |
1310 | } |
1311 | |
1312 | TEST( |
1313 | IntrusivePtrTest, |
1314 | givenPtrWithCopy_whenCallingResetOnCopy_thenDestructsAfterOriginalDestructed) { |
1315 | bool resourcesReleased = false; |
1316 | bool wasDestructed = false; |
1317 | auto obj = |
1318 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
1319 | { |
1320 | auto copy = obj; |
1321 | copy.reset(); |
1322 | EXPECT_FALSE(resourcesReleased); |
1323 | EXPECT_FALSE(wasDestructed); |
1324 | obj.reset(); |
1325 | EXPECT_TRUE(resourcesReleased); |
1326 | EXPECT_TRUE(wasDestructed); |
1327 | } |
1328 | } |
1329 | |
1330 | TEST( |
1331 | IntrusivePtrTest, |
1332 | givenPtrWithMoved_whenCallingReset_thenDestructsAfterMovedDestructed) { |
1333 | bool resourcesReleased = false; |
1334 | bool wasDestructed = false; |
1335 | auto obj = |
1336 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
1337 | { |
1338 | auto moved = std::move(obj); |
1339 | // NOLINTNEXTLINE(bugprone-use-after-move) |
1340 | obj.reset(); |
1341 | EXPECT_FALSE(resourcesReleased); |
1342 | EXPECT_FALSE(wasDestructed); |
1343 | moved.reset(); |
1344 | EXPECT_TRUE(resourcesReleased); |
1345 | EXPECT_TRUE(wasDestructed); |
1346 | } |
1347 | } |
1348 | |
1349 | TEST( |
1350 | IntrusivePtrTest, |
1351 | givenPtrWithMoved_whenCallingResetOnMoved_thenDestructsImmediately) { |
1352 | bool resourcesReleased = false; |
1353 | bool wasDestructed = false; |
1354 | auto obj = |
1355 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
1356 | { |
1357 | auto moved = std::move(obj); |
1358 | moved.reset(); |
1359 | EXPECT_TRUE(resourcesReleased); |
1360 | EXPECT_TRUE(wasDestructed); |
1361 | } |
1362 | } |
1363 | |
1364 | TEST(IntrusivePtrTest, AllowsMoveConstructingToConst) { |
1365 | intrusive_ptr<SomeClass> a = make_intrusive<SomeClass>(); |
1366 | intrusive_ptr<const SomeClass> b = std::move(a); |
1367 | } |
1368 | |
1369 | TEST(IntrusivePtrTest, AllowsCopyConstructingToConst) { |
1370 | intrusive_ptr<SomeClass> a = make_intrusive<SomeClass>(); |
1371 | intrusive_ptr<const SomeClass> b = a; |
1372 | } |
1373 | |
1374 | TEST(IntrusivePtrTest, AllowsMoveAssigningToConst) { |
1375 | intrusive_ptr<SomeClass> a = make_intrusive<SomeClass>(); |
1376 | intrusive_ptr<const SomeClass> b = make_intrusive<SomeClass>(); |
1377 | b = std::move(a); |
1378 | } |
1379 | |
1380 | TEST(IntrusivePtrTest, AllowsCopyAssigningToConst) { |
1381 | intrusive_ptr<SomeClass> a = make_intrusive<SomeClass>(); |
1382 | intrusive_ptr<const SomeClass> b = make_intrusive<const SomeClass>(); |
1383 | b = a; |
1384 | } |
1385 | |
1386 | TEST(IntrusivePtrTest, givenNewPtr_thenHasUseCount1) { |
1387 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1388 | EXPECT_EQ(1, obj.use_count()); |
1389 | } |
1390 | |
1391 | TEST(IntrusivePtrTest, givenNewPtr_thenIsUnique) { |
1392 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1393 | EXPECT_TRUE(obj.unique()); |
1394 | } |
1395 | |
1396 | TEST(IntrusivePtrTest, givenEmptyPtr_thenHasUseCount0) { |
1397 | intrusive_ptr<SomeClass> obj; |
1398 | EXPECT_EQ(0, obj.use_count()); |
1399 | } |
1400 | |
1401 | TEST(IntrusivePtrTest, givenEmptyPtr_thenIsNotUnique) { |
1402 | intrusive_ptr<SomeClass> obj; |
1403 | EXPECT_FALSE(obj.unique()); |
1404 | } |
1405 | |
1406 | TEST(IntrusivePtrTest, givenResetPtr_thenHasUseCount0) { |
1407 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1408 | obj.reset(); |
1409 | EXPECT_EQ(0, obj.use_count()); |
1410 | } |
1411 | |
1412 | TEST(IntrusivePtrTest, givenResetPtr_thenIsNotUnique) { |
1413 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1414 | obj.reset(); |
1415 | EXPECT_FALSE(obj.unique()); |
1416 | } |
1417 | |
1418 | TEST(IntrusivePtrTest, givenMoveConstructedPtr_thenHasUseCount1) { |
1419 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1420 | intrusive_ptr<SomeClass> obj2 = std::move(obj); |
1421 | EXPECT_EQ(1, obj2.use_count()); |
1422 | } |
1423 | |
1424 | TEST(IntrusivePtrTest, givenMoveConstructedPtr_thenIsUnique) { |
1425 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1426 | intrusive_ptr<SomeClass> obj2 = std::move(obj); |
1427 | EXPECT_TRUE(obj2.unique()); |
1428 | } |
1429 | |
1430 | TEST(IntrusivePtrTest, givenMoveConstructedPtr_thenOldHasUseCount0) { |
1431 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1432 | intrusive_ptr<SomeClass> obj2 = std::move(obj); |
1433 | // NOLINTNEXTLINE(clang-analyzer-cplusplus.Move,bugprone-use-after-move) |
1434 | EXPECT_EQ(0, obj.use_count()); |
1435 | } |
1436 | |
1437 | TEST(IntrusivePtrTest, givenMoveConstructedPtr_thenOldIsNotUnique) { |
1438 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1439 | intrusive_ptr<SomeClass> obj2 = std::move(obj); |
1440 | // NOLINTNEXTLINE(clang-analyzer-cplusplus.Move,bugprone-use-after-move) |
1441 | EXPECT_FALSE(obj.unique()); |
1442 | } |
1443 | |
1444 | TEST(IntrusivePtrTest, givenMoveAssignedPtr_thenHasUseCount1) { |
1445 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1446 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
1447 | obj2 = std::move(obj); |
1448 | EXPECT_EQ(1, obj2.use_count()); |
1449 | } |
1450 | |
1451 | TEST(IntrusivePtrTest, givenMoveAssignedPtr_thenIsUnique) { |
1452 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1453 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
1454 | obj2 = std::move(obj); |
1455 | EXPECT_TRUE(obj2.unique()); |
1456 | } |
1457 | |
1458 | TEST(IntrusivePtrTest, givenMoveAssignedPtr_thenOldHasUseCount0) { |
1459 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1460 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
1461 | obj2 = std::move(obj); |
1462 | // NOLINTNEXTLINE(clang-analyzer-cplusplus.Move,bugprone-use-after-move) |
1463 | EXPECT_EQ(0, obj.use_count()); |
1464 | } |
1465 | |
1466 | TEST(IntrusivePtrTest, givenMoveAssignedPtr_thenOldIsNotUnique) { |
1467 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1468 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
1469 | obj2 = std::move(obj); |
1470 | // NOLINTNEXTLINE(clang-analyzer-cplusplus.Move,bugprone-use-after-move) |
1471 | EXPECT_FALSE(obj.unique()); |
1472 | } |
1473 | |
1474 | TEST(IntrusivePtrTest, givenCopyConstructedPtr_thenHasUseCount2) { |
1475 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1476 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
1477 | intrusive_ptr<SomeClass> obj2 = obj; |
1478 | EXPECT_EQ(2, obj2.use_count()); |
1479 | } |
1480 | |
1481 | TEST(IntrusivePtrTest, givenCopyConstructedPtr_thenIsNotUnique) { |
1482 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1483 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
1484 | intrusive_ptr<SomeClass> obj2 = obj; |
1485 | EXPECT_FALSE(obj2.unique()); |
1486 | } |
1487 | |
1488 | TEST(IntrusivePtrTest, givenCopyConstructedPtr_thenOldHasUseCount2) { |
1489 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1490 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
1491 | intrusive_ptr<SomeClass> obj2 = obj; |
1492 | EXPECT_EQ(2, obj.use_count()); |
1493 | } |
1494 | |
1495 | TEST(IntrusivePtrTest, givenCopyConstructedPtr_thenOldIsNotUnique) { |
1496 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1497 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
1498 | intrusive_ptr<SomeClass> obj2 = obj; |
1499 | EXPECT_FALSE(obj.unique()); |
1500 | } |
1501 | |
1502 | TEST( |
1503 | IntrusivePtrTest, |
1504 | givenCopyConstructedPtr_whenDestructingCopy_thenHasUseCount1) { |
1505 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1506 | { |
1507 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
1508 | intrusive_ptr<SomeClass> obj2 = obj; |
1509 | EXPECT_EQ(2, obj.use_count()); |
1510 | } |
1511 | EXPECT_EQ(1, obj.use_count()); |
1512 | } |
1513 | |
1514 | TEST( |
1515 | IntrusivePtrTest, |
1516 | givenCopyConstructedPtr_whenDestructingCopy_thenIsUnique) { |
1517 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1518 | { |
1519 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
1520 | intrusive_ptr<SomeClass> obj2 = obj; |
1521 | EXPECT_FALSE(obj.unique()); |
1522 | } |
1523 | EXPECT_TRUE(obj.unique()); |
1524 | } |
1525 | |
1526 | TEST( |
1527 | IntrusivePtrTest, |
1528 | givenCopyConstructedPtr_whenReassigningCopy_thenHasUseCount1) { |
1529 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1530 | intrusive_ptr<SomeClass> obj2 = obj; |
1531 | EXPECT_EQ(2, obj.use_count()); |
1532 | obj2 = make_intrusive<SomeClass>(); |
1533 | EXPECT_EQ(1, obj.use_count()); |
1534 | EXPECT_EQ(1, obj2.use_count()); |
1535 | } |
1536 | |
1537 | TEST( |
1538 | IntrusivePtrTest, |
1539 | givenCopyConstructedPtr_whenReassigningCopy_thenIsUnique) { |
1540 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1541 | intrusive_ptr<SomeClass> obj2 = obj; |
1542 | EXPECT_FALSE(obj.unique()); |
1543 | obj2 = make_intrusive<SomeClass>(); |
1544 | EXPECT_TRUE(obj.unique()); |
1545 | EXPECT_TRUE(obj2.unique()); |
1546 | } |
1547 | |
1548 | TEST(IntrusivePtrTest, givenCopyAssignedPtr_thenHasUseCount2) { |
1549 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1550 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
1551 | obj2 = obj; |
1552 | EXPECT_EQ(2, obj.use_count()); |
1553 | EXPECT_EQ(2, obj2.use_count()); |
1554 | } |
1555 | |
1556 | TEST(IntrusivePtrTest, givenCopyAssignedPtr_thenIsNotUnique) { |
1557 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1558 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
1559 | obj2 = obj; |
1560 | EXPECT_FALSE(obj.unique()); |
1561 | EXPECT_FALSE(obj2.unique()); |
1562 | } |
1563 | |
1564 | TEST( |
1565 | IntrusivePtrTest, |
1566 | givenCopyAssignedPtr_whenDestructingCopy_thenHasUseCount1) { |
1567 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1568 | { |
1569 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
1570 | obj2 = obj; |
1571 | EXPECT_EQ(2, obj.use_count()); |
1572 | } |
1573 | EXPECT_EQ(1, obj.use_count()); |
1574 | } |
1575 | |
1576 | TEST(IntrusivePtrTest, givenCopyAssignedPtr_whenDestructingCopy_thenIsUnique) { |
1577 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1578 | { |
1579 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
1580 | obj2 = obj; |
1581 | EXPECT_FALSE(obj.unique()); |
1582 | } |
1583 | EXPECT_TRUE(obj.unique()); |
1584 | } |
1585 | |
1586 | TEST( |
1587 | IntrusivePtrTest, |
1588 | givenCopyAssignedPtr_whenReassigningCopy_thenHasUseCount1) { |
1589 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1590 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
1591 | obj2 = obj; |
1592 | EXPECT_EQ(2, obj.use_count()); |
1593 | obj2 = make_intrusive<SomeClass>(); |
1594 | EXPECT_EQ(1, obj.use_count()); |
1595 | EXPECT_EQ(1, obj2.use_count()); |
1596 | } |
1597 | |
1598 | TEST(IntrusivePtrTest, givenCopyAssignedPtr_whenReassigningCopy_thenIsUnique) { |
1599 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1600 | intrusive_ptr<SomeClass> obj2 = make_intrusive<SomeClass>(); |
1601 | obj2 = obj; |
1602 | EXPECT_FALSE(obj.unique()); |
1603 | obj2 = make_intrusive<SomeClass>(); |
1604 | EXPECT_TRUE(obj.unique()); |
1605 | EXPECT_TRUE(obj2.unique()); |
1606 | } |
1607 | |
1608 | TEST(IntrusivePtrTest, givenPtr_whenReleasedAndReclaimed_thenDoesntCrash) { |
1609 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1610 | SomeClass* ptr = obj.release(); |
1611 | EXPECT_FALSE(obj.defined()); |
1612 | intrusive_ptr<SomeClass> reclaimed = intrusive_ptr<SomeClass>::reclaim(ptr); |
1613 | } |
1614 | |
1615 | TEST( |
1616 | IntrusivePtrTest, |
1617 | givenPtr_whenReleasedAndReclaimed_thenIsDestructedAtEnd) { |
1618 | bool resourcesReleased = false; |
1619 | bool wasDestructed = false; |
1620 | { |
1621 | intrusive_ptr<DestructableMock> outer; |
1622 | { |
1623 | intrusive_ptr<DestructableMock> inner = |
1624 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
1625 | DestructableMock* ptr = inner.release(); |
1626 | EXPECT_FALSE(resourcesReleased); |
1627 | EXPECT_FALSE(wasDestructed); |
1628 | outer = intrusive_ptr<DestructableMock>::reclaim(ptr); |
1629 | } |
1630 | // inner is destructed |
1631 | EXPECT_FALSE(resourcesReleased); |
1632 | EXPECT_FALSE(wasDestructed); |
1633 | } |
1634 | // outer is destructed |
1635 | EXPECT_TRUE(resourcesReleased); |
1636 | EXPECT_TRUE(wasDestructed); |
1637 | } |
1638 | |
1639 | /* |
1640 | TEST(IntrusivePtrTest, givenStackObject_whenReclaimed_thenCrashes) { |
1641 | // This would cause very weird bugs on destruction. |
1642 | // Better to crash early on creation. |
1643 | SomeClass obj; |
1644 | intrusive_ptr<SomeClass> ptr; |
1645 | #ifdef NDEBUG |
1646 | EXPECT_NO_THROW(ptr = intrusive_ptr<SomeClass>::reclaim(&obj)); |
1647 | #else |
1648 | EXPECT_ANY_THROW(ptr = intrusive_ptr<SomeClass>::reclaim(&obj)); |
1649 | #endif |
1650 | }*/ |
1651 | |
1652 | TEST(IntrusivePtrTest, givenPtr_whenNonOwningReclaimed_thenDoesntCrash) { |
1653 | intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>(); |
1654 | SomeClass* raw_ptr = obj.get(); |
1655 | EXPECT_TRUE(obj.defined()); |
1656 | intrusive_ptr<SomeClass> reclaimed = |
1657 | intrusive_ptr<SomeClass>::unsafe_reclaim_from_nonowning(raw_ptr); |
1658 | EXPECT_TRUE(reclaimed.defined()); |
1659 | EXPECT_EQ(reclaimed.get(), obj.get()); |
1660 | } |
1661 | |
1662 | TEST(IntrusivePtrTest, givenPtr_whenNonOwningReclaimed_thenIsDestructedAtEnd) { |
1663 | bool resourcesReleased = false; |
1664 | bool wasDestructed = false; |
1665 | { |
1666 | intrusive_ptr<DestructableMock> outer; |
1667 | { |
1668 | intrusive_ptr<DestructableMock> inner = |
1669 | make_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
1670 | DestructableMock* raw_ptr = inner.get(); |
1671 | outer = intrusive_ptr<DestructableMock>::unsafe_reclaim_from_nonowning( |
1672 | raw_ptr); |
1673 | } |
1674 | // inner is destructed |
1675 | EXPECT_FALSE(resourcesReleased); |
1676 | EXPECT_FALSE(wasDestructed); |
1677 | } |
1678 | // outer is destructed |
1679 | EXPECT_TRUE(resourcesReleased); |
1680 | EXPECT_TRUE(wasDestructed); |
1681 | } |
1682 | |
1683 | namespace { |
1684 | template <class T> |
1685 | struct IntrusiveAndWeak final { |
1686 | IntrusiveAndWeak(intrusive_ptr<T> ptr_) : ptr(std::move(ptr_)), weak(ptr) {} |
1687 | |
1688 | intrusive_ptr<T> ptr; |
1689 | weak_intrusive_ptr<T> weak; |
1690 | }; |
1691 | template <class T, class... Args> |
1692 | IntrusiveAndWeak<T> make_weak_intrusive(Args&&... args) { |
1693 | return IntrusiveAndWeak<T>(make_intrusive<T>(std::forward<Args>(args)...)); |
1694 | } |
1695 | template <class T, class... Args> |
1696 | weak_intrusive_ptr<T> make_weak_only(Args&&... args) { |
1697 | auto intrusive = make_intrusive<T>(std::forward<Args>(args)...); |
1698 | return weak_intrusive_ptr<T>(intrusive); |
1699 | } |
1700 | template < |
1701 | class T, |
1702 | class NullType = c10::detail::intrusive_target_default_null_type<T>> |
1703 | weak_intrusive_ptr<T, NullType> make_invalid_weak() { |
1704 | return weak_intrusive_ptr<T, NullType>(intrusive_ptr<T, NullType>()); |
1705 | } |
1706 | |
1707 | struct WeakReferenceToSelf : public intrusive_ptr_target { |
1708 | void release_resources() override { |
1709 | ptr.reset(); |
1710 | } |
1711 | weak_intrusive_ptr<intrusive_ptr_target> ptr = |
1712 | weak_intrusive_ptr<intrusive_ptr_target>( |
1713 | make_intrusive<intrusive_ptr_target>()); |
1714 | }; |
1715 | } // namespace |
1716 | |
1717 | static_assert( |
1718 | std::is_same<SomeClass, weak_intrusive_ptr<SomeClass>::element_type>::value, |
1719 | "weak_intrusive_ptr<T>::element_type is wrong" ); |
1720 | |
1721 | TEST( |
1722 | WeakIntrusivePtrTest, |
1723 | givenPtr_whenCreatingAndDestructing_thenDoesntCrash) { |
1724 | IntrusiveAndWeak<SomeClass> var = make_weak_intrusive<SomeClass>(); |
1725 | } |
1726 | |
1727 | TEST(WeakIntrusivePtrTest, givenPtr_whenLocking_thenReturnsCorrectObject) { |
1728 | IntrusiveAndWeak<SomeClass> var = make_weak_intrusive<SomeClass>(); |
1729 | intrusive_ptr<SomeClass> locked = var.weak.lock(); |
1730 | EXPECT_EQ(var.ptr.get(), locked.get()); |
1731 | } |
1732 | |
1733 | TEST(WeakIntrusivePtrTest, expiredPtr_whenLocking_thenReturnsNullType) { |
1734 | IntrusiveAndWeak<SomeClass> var = make_weak_intrusive<SomeClass>(); |
1735 | // reset the intrusive_ptr to test if weak pointer still valid |
1736 | var.ptr.reset(); |
1737 | EXPECT_TRUE(var.weak.expired()); |
1738 | intrusive_ptr<SomeClass> locked = var.weak.lock(); |
1739 | EXPECT_FALSE(locked.defined()); |
1740 | } |
1741 | |
1742 | TEST(WeakIntrusivePtrTest, weakNullPtr_locking) { |
1743 | auto weak_ptr = make_invalid_weak<SomeClass>(); |
1744 | intrusive_ptr<SomeClass> locked = weak_ptr.lock(); |
1745 | EXPECT_FALSE(locked.defined()); |
1746 | } |
1747 | |
1748 | TEST( |
1749 | WeakIntrusivePtrTest, |
1750 | givenValidPtr_whenMoveAssigning_thenPointsToSameObject) { |
1751 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
1752 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
1753 | SomeClass* obj1ptr = obj1.weak.lock().get(); |
1754 | obj2.weak = std::move(obj1.weak); |
1755 | EXPECT_EQ(obj1ptr, obj2.weak.lock().get()); |
1756 | } |
1757 | |
1758 | TEST( |
1759 | WeakIntrusivePtrTest, |
1760 | givenValidPtr_whenMoveAssigning_thenOldInstanceInvalid) { |
1761 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
1762 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
1763 | obj2.weak = std::move(obj1.weak); |
1764 | EXPECT_TRUE(obj1.weak.expired()); |
1765 | } |
1766 | |
1767 | TEST(WeakIntrusivePtrTest, vector_insert_weak_intrusive) { |
1768 | std::vector<weak_intrusive_ptr<SomeClass>> priorWorks; |
1769 | std::vector<intrusive_ptr<SomeClass>> wips; |
1770 | wips.push_back(make_intrusive<SomeClass>()); |
1771 | priorWorks.insert(priorWorks.end(), wips.begin(), wips.end()); |
1772 | EXPECT_EQ(priorWorks.size(), 1); |
1773 | } |
1774 | TEST( |
1775 | WeakIntrusivePtrTest, |
1776 | givenInvalidPtr_whenMoveAssigning_thenNewInstanceIsValid) { |
1777 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
1778 | weak_intrusive_ptr<SomeClass> obj2 = make_invalid_weak<SomeClass>(); |
1779 | obj1.weak.lock().get(); |
1780 | obj2 = std::move(obj1.weak); |
1781 | EXPECT_FALSE(obj2.expired()); |
1782 | } |
1783 | |
1784 | TEST( |
1785 | WeakIntrusivePtrTest, |
1786 | givenValidPtr_whenMoveAssigningToSelf_thenPointsToSameObject) { |
1787 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
1788 | SomeClass* obj1ptr = obj1.weak.lock().get(); |
1789 | obj1.weak = std::move(obj1.weak); |
1790 | EXPECT_EQ(obj1ptr, obj1.weak.lock().get()); |
1791 | } |
1792 | |
1793 | TEST( |
1794 | WeakIntrusivePtrTest, |
1795 | givenValidPtr_whenMoveAssigningToSelf_thenStaysValid) { |
1796 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
1797 | obj1.weak = std::move(obj1.weak); |
1798 | EXPECT_FALSE(obj1.weak.expired()); |
1799 | } |
1800 | |
1801 | TEST( |
1802 | WeakIntrusivePtrTest, |
1803 | givenInvalidPtr_whenMoveAssigning_thenPointsToSameObject) { |
1804 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
1805 | weak_intrusive_ptr<SomeClass> obj2 = make_invalid_weak<SomeClass>(); |
1806 | SomeClass* obj1ptr = obj1.weak.lock().get(); |
1807 | obj2 = std::move(obj1.weak); |
1808 | EXPECT_EQ(obj1ptr, obj2.lock().get()); |
1809 | } |
1810 | |
1811 | TEST( |
1812 | WeakIntrusivePtrTest, |
1813 | givenInvalidPtr_whenMoveAssigningToSelf_thenStaysInvalid) { |
1814 | weak_intrusive_ptr<SomeClass> obj1 = make_invalid_weak<SomeClass>(); |
1815 | obj1 = std::move(obj1); |
1816 | // NOLINTNEXTLINE(bugprone-use-after-move) |
1817 | EXPECT_TRUE(obj1.expired()); |
1818 | } |
1819 | |
1820 | TEST( |
1821 | WeakIntrusivePtrTest, |
1822 | givenWeakOnlyPtr_whenMoveAssigning_thenNewInstanceIsValid) { |
1823 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
1824 | weak_intrusive_ptr<SomeClass> obj2 = make_weak_only<SomeClass>(); |
1825 | obj1.weak.lock().get(); |
1826 | obj2 = std::move(obj1.weak); |
1827 | EXPECT_FALSE(obj2.expired()); |
1828 | } |
1829 | |
1830 | TEST( |
1831 | WeakIntrusivePtrTest, |
1832 | givenWeakOnlyPtr_whenMoveAssigning_thenPointsToSameObject) { |
1833 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
1834 | weak_intrusive_ptr<SomeClass> obj2 = make_weak_only<SomeClass>(); |
1835 | SomeClass* obj1ptr = obj1.weak.lock().get(); |
1836 | obj2 = std::move(obj1.weak); |
1837 | EXPECT_EQ(obj1ptr, obj2.lock().get()); |
1838 | } |
1839 | |
1840 | TEST( |
1841 | WeakIntrusivePtrTest, |
1842 | givenWeakOnlyPtr_whenMoveAssigningToSelf_thenStaysInvalid) { |
1843 | weak_intrusive_ptr<SomeClass> obj1 = make_weak_only<SomeClass>(); |
1844 | obj1.lock().get(); |
1845 | obj1 = std::move(obj1); |
1846 | // NOLINTNEXTLINE(bugprone-use-after-move) |
1847 | EXPECT_TRUE(obj1.expired()); |
1848 | } |
1849 | |
1850 | TEST( |
1851 | WeakIntrusivePtrTest, |
1852 | givenWeakOnlyPtr_whenMoveAssigningToSelf_thenPointsToSameObject) { |
1853 | weak_intrusive_ptr<SomeClass> obj1 = make_weak_only<SomeClass>(); |
1854 | SomeClass* obj1ptr = obj1.lock().get(); |
1855 | obj1 = std::move(obj1); |
1856 | // NOLINTNEXTLINE(bugprone-use-after-move) |
1857 | EXPECT_EQ(obj1ptr, obj1.lock().get()); |
1858 | } |
1859 | |
1860 | TEST( |
1861 | WeakIntrusivePtrTest, |
1862 | givenValidPtr_whenMoveAssigningFromInvalidPtr_thenNewInstanceIsInvalid) { |
1863 | weak_intrusive_ptr<SomeClass> obj1 = make_invalid_weak<SomeClass>(); |
1864 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
1865 | EXPECT_FALSE(obj2.weak.expired()); |
1866 | obj2.weak = std::move(obj1); |
1867 | EXPECT_TRUE(obj2.weak.expired()); |
1868 | } |
1869 | |
1870 | TEST( |
1871 | WeakIntrusivePtrTest, |
1872 | givenValidPtr_whenMoveAssigningFromWeakOnlyPtr_thenNewInstanceIsInvalid) { |
1873 | weak_intrusive_ptr<SomeClass> obj1 = make_weak_only<SomeClass>(); |
1874 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
1875 | EXPECT_FALSE(obj2.weak.expired()); |
1876 | obj2.weak = std::move(obj1); |
1877 | EXPECT_TRUE(obj2.weak.expired()); |
1878 | } |
1879 | |
1880 | TEST( |
1881 | WeakIntrusivePtrTest, |
1882 | givenValidPtr_whenMoveAssigningToBaseClass_thenPointsToSameObject) { |
1883 | IntrusiveAndWeak<SomeChildClass> obj1 = |
1884 | make_weak_intrusive<SomeChildClass>(1); |
1885 | IntrusiveAndWeak<SomeBaseClass> obj2 = make_weak_intrusive<SomeBaseClass>(2); |
1886 | SomeBaseClass* obj1ptr = obj1.weak.lock().get(); |
1887 | obj2.weak = std::move(obj1.weak); |
1888 | EXPECT_EQ(obj1ptr, obj2.weak.lock().get()); |
1889 | EXPECT_EQ(1, obj2.weak.lock()->v); |
1890 | } |
1891 | |
1892 | TEST( |
1893 | WeakIntrusivePtrTest, |
1894 | givenValidPtr_whenMoveAssigningToBaseClass_thenOldInstanceInvalid) { |
1895 | IntrusiveAndWeak<SomeChildClass> obj1 = |
1896 | make_weak_intrusive<SomeChildClass>(1); |
1897 | IntrusiveAndWeak<SomeBaseClass> obj2 = make_weak_intrusive<SomeBaseClass>(2); |
1898 | obj2.weak = std::move(obj1.weak); |
1899 | EXPECT_TRUE(obj1.weak.expired()); |
1900 | } |
1901 | |
1902 | TEST( |
1903 | WeakIntrusivePtrTest, |
1904 | givenInvalidPtr_whenMoveAssigningToBaseClass_thenNewInstanceIsValid) { |
1905 | IntrusiveAndWeak<SomeChildClass> obj1 = |
1906 | make_weak_intrusive<SomeChildClass>(5); |
1907 | weak_intrusive_ptr<SomeBaseClass> obj2 = make_invalid_weak<SomeBaseClass>(); |
1908 | obj1.weak.lock().get(); |
1909 | obj2 = std::move(obj1.weak); |
1910 | EXPECT_FALSE(obj2.expired()); |
1911 | } |
1912 | |
1913 | TEST( |
1914 | WeakIntrusivePtrTest, |
1915 | givenInvalidPtr_whenMoveAssigningToBaseClass_thenPointsToSameObject) { |
1916 | IntrusiveAndWeak<SomeChildClass> obj1 = |
1917 | make_weak_intrusive<SomeChildClass>(5); |
1918 | weak_intrusive_ptr<SomeBaseClass> obj2 = make_invalid_weak<SomeBaseClass>(); |
1919 | SomeBaseClass* obj1ptr = obj1.weak.lock().get(); |
1920 | obj2 = std::move(obj1.weak); |
1921 | EXPECT_EQ(obj1ptr, obj2.lock().get()); |
1922 | EXPECT_EQ(5, obj2.lock()->v); |
1923 | } |
1924 | |
1925 | TEST( |
1926 | WeakIntrusivePtrTest, |
1927 | givenInvalidPtr_whenMoveAssigningInvalidPtrToBaseClass_thenNewInstanceIsValid) { |
1928 | weak_intrusive_ptr<SomeChildClass> obj1 = make_invalid_weak<SomeChildClass>(); |
1929 | IntrusiveAndWeak<SomeBaseClass> obj2 = make_weak_intrusive<SomeBaseClass>(2); |
1930 | EXPECT_FALSE(obj2.weak.expired()); |
1931 | obj2.weak = std::move(obj1); |
1932 | EXPECT_TRUE(obj2.weak.expired()); |
1933 | } |
1934 | |
1935 | TEST( |
1936 | WeakIntrusivePtrTest, |
1937 | givenWeakOnlyPtr_whenMoveAssigningToBaseClass_thenNewInstanceIsValid) { |
1938 | IntrusiveAndWeak<SomeChildClass> obj1 = |
1939 | make_weak_intrusive<SomeChildClass>(5); |
1940 | weak_intrusive_ptr<SomeBaseClass> obj2 = make_weak_only<SomeBaseClass>(2); |
1941 | obj1.weak.lock().get(); |
1942 | obj2 = std::move(obj1.weak); |
1943 | EXPECT_FALSE(obj2.expired()); |
1944 | } |
1945 | |
1946 | TEST( |
1947 | WeakIntrusivePtrTest, |
1948 | givenWeakOnlyPtr_whenMoveAssigningToBaseClass_thenPointsToSameObject) { |
1949 | IntrusiveAndWeak<SomeChildClass> obj1 = |
1950 | make_weak_intrusive<SomeChildClass>(5); |
1951 | weak_intrusive_ptr<SomeBaseClass> obj2 = make_weak_only<SomeBaseClass>(2); |
1952 | SomeBaseClass* obj1ptr = obj1.weak.lock().get(); |
1953 | obj2 = std::move(obj1.weak); |
1954 | EXPECT_EQ(obj1ptr, obj2.lock().get()); |
1955 | EXPECT_EQ(5, obj2.lock()->v); |
1956 | } |
1957 | |
1958 | TEST( |
1959 | WeakIntrusivePtrTest, |
1960 | givenWeakOnlyPtr_whenMoveAssigningInvalidPtrToBaseClass_thenNewInstanceIsValid) { |
1961 | weak_intrusive_ptr<SomeChildClass> obj1 = make_weak_only<SomeChildClass>(5); |
1962 | IntrusiveAndWeak<SomeBaseClass> obj2 = make_weak_intrusive<SomeBaseClass>(2); |
1963 | EXPECT_FALSE(obj2.weak.expired()); |
1964 | obj2.weak = std::move(obj1); |
1965 | EXPECT_TRUE(obj2.weak.expired()); |
1966 | } |
1967 | |
1968 | TEST( |
1969 | WeakIntrusivePtrTest, |
1970 | givenNullPtr_whenMoveAssigningToDifferentNullptr_thenHasNewNullptr) { |
1971 | weak_intrusive_ptr<SomeClass, NullType1> obj1 = |
1972 | make_invalid_weak<SomeClass, NullType1>(); |
1973 | weak_intrusive_ptr<SomeClass, NullType2> obj2 = |
1974 | make_invalid_weak<SomeClass, NullType2>(); |
1975 | obj2 = std::move(obj1); |
1976 | EXPECT_NE(NullType1::singleton(), NullType2::singleton()); |
1977 | // NOLINTNEXTLINE(bugprone-use-after-move) |
1978 | EXPECT_TRUE(obj1.expired()); |
1979 | EXPECT_TRUE(obj2.expired()); |
1980 | } |
1981 | |
1982 | TEST( |
1983 | WeakIntrusivePtrTest, |
1984 | givenValidPtr_whenCopyAssigning_thenPointsToSameObject) { |
1985 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
1986 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
1987 | SomeClass* obj1ptr = obj1.weak.lock().get(); |
1988 | obj2.weak = obj1.weak; |
1989 | EXPECT_EQ(obj1ptr, obj2.weak.lock().get()); |
1990 | } |
1991 | |
1992 | TEST( |
1993 | WeakIntrusivePtrTest, |
1994 | givenValidPtr_whenCopyAssigning_thenOldInstanceValid) { |
1995 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
1996 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
1997 | obj2.weak = obj1.weak; |
1998 | EXPECT_FALSE(obj1.weak.expired()); |
1999 | } |
2000 | |
2001 | TEST( |
2002 | WeakIntrusivePtrTest, |
2003 | givenValidPtr_whenCopyAssigningToSelf_thenPointsToSameObject) { |
2004 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2005 | SomeClass* obj1ptr = obj1.weak.lock().get(); |
2006 | obj1.weak = obj1.weak; |
2007 | EXPECT_EQ(obj1ptr, obj1.weak.lock().get()); |
2008 | } |
2009 | |
2010 | TEST( |
2011 | WeakIntrusivePtrTest, |
2012 | givenValidPtr_whenCopyAssigningToSelf_thenStaysValid) { |
2013 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2014 | obj1.weak = obj1.weak; |
2015 | EXPECT_FALSE(obj1.weak.expired()); |
2016 | } |
2017 | |
2018 | TEST( |
2019 | WeakIntrusivePtrTest, |
2020 | givenInvalidPtr_whenCopyAssigning_thenNewInstanceIsValid) { |
2021 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2022 | weak_intrusive_ptr<SomeClass> obj2 = make_invalid_weak<SomeClass>(); |
2023 | obj1.weak.lock().get(); |
2024 | obj2 = obj1.weak; |
2025 | EXPECT_FALSE(obj2.expired()); |
2026 | } |
2027 | |
2028 | TEST( |
2029 | WeakIntrusivePtrTest, |
2030 | givenInvalidPtr_whenCopyAssigningToSelf_thenStaysInvalid) { |
2031 | weak_intrusive_ptr<SomeClass> obj1 = make_invalid_weak<SomeClass>(); |
2032 | // NOLINTNEXTLINE(clang-diagnostic-self-assign-overloaded) |
2033 | obj1 = obj1; |
2034 | EXPECT_TRUE(obj1.expired()); |
2035 | } |
2036 | |
2037 | TEST( |
2038 | WeakIntrusivePtrTest, |
2039 | givenWeakOnlyPtr_whenCopyAssigning_thenNewInstanceIsValid) { |
2040 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2041 | weak_intrusive_ptr<SomeClass> obj2 = make_weak_only<SomeClass>(); |
2042 | obj1.weak.lock().get(); |
2043 | obj2 = obj1.weak; |
2044 | EXPECT_FALSE(obj2.expired()); |
2045 | } |
2046 | |
2047 | TEST( |
2048 | WeakIntrusivePtrTest, |
2049 | givenWeakOnlyPtr_whenCopyAssigning_thenPointsToSameObject) { |
2050 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2051 | weak_intrusive_ptr<SomeClass> obj2 = make_weak_only<SomeClass>(); |
2052 | SomeClass* obj1ptr = obj1.weak.lock().get(); |
2053 | obj2 = obj1.weak; |
2054 | EXPECT_EQ(obj1ptr, obj2.lock().get()); |
2055 | } |
2056 | |
2057 | TEST( |
2058 | WeakIntrusivePtrTest, |
2059 | givenWeakOnlyPtr_whenCopyAssigningToSelf_thenStaysInvalid) { |
2060 | weak_intrusive_ptr<SomeClass> obj1 = make_weak_only<SomeClass>(); |
2061 | obj1.lock().get(); |
2062 | // NOLINTNEXTLINE(clang-diagnostic-self-assign-overloaded) |
2063 | obj1 = obj1; |
2064 | EXPECT_TRUE(obj1.expired()); |
2065 | } |
2066 | |
2067 | TEST( |
2068 | WeakIntrusivePtrTest, |
2069 | givenWeakOnlyPtr_whenCopyAssigningToSelf_thenPointsToSameObject) { |
2070 | weak_intrusive_ptr<SomeClass> obj1 = make_weak_only<SomeClass>(); |
2071 | SomeClass* obj1ptr = obj1.lock().get(); |
2072 | // NOLINTNEXTLINE(clang-diagnostic-self-assign-overloaded) |
2073 | obj1 = obj1; |
2074 | EXPECT_EQ(obj1ptr, obj1.lock().get()); |
2075 | } |
2076 | |
2077 | TEST( |
2078 | WeakIntrusivePtrTest, |
2079 | givenValidPtr_whenCopyAssigningToBaseClass_thenPointsToSameObject) { |
2080 | IntrusiveAndWeak<SomeChildClass> child = |
2081 | make_weak_intrusive<SomeChildClass>(3); |
2082 | IntrusiveAndWeak<SomeBaseClass> base = make_weak_intrusive<SomeBaseClass>(10); |
2083 | base.weak = child.weak; |
2084 | EXPECT_EQ(3, base.weak.lock()->v); |
2085 | } |
2086 | |
2087 | TEST( |
2088 | WeakIntrusivePtrTest, |
2089 | givenValidPtr_whenCopyAssigningToBaseClass_thenOldInstanceInvalid) { |
2090 | IntrusiveAndWeak<SomeChildClass> obj1 = |
2091 | make_weak_intrusive<SomeChildClass>(3); |
2092 | IntrusiveAndWeak<SomeBaseClass> obj2 = make_weak_intrusive<SomeBaseClass>(10); |
2093 | obj2.weak = obj1.weak; |
2094 | EXPECT_FALSE(obj1.weak.expired()); |
2095 | } |
2096 | |
2097 | TEST( |
2098 | WeakIntrusivePtrTest, |
2099 | givenInvalidPtr_whenCopyAssigningToBaseClass_thenNewInstanceIsValid) { |
2100 | IntrusiveAndWeak<SomeChildClass> obj1 = |
2101 | make_weak_intrusive<SomeChildClass>(5); |
2102 | weak_intrusive_ptr<SomeBaseClass> obj2 = make_invalid_weak<SomeBaseClass>(); |
2103 | obj1.weak.lock().get(); |
2104 | obj2 = obj1.weak; |
2105 | EXPECT_FALSE(obj2.expired()); |
2106 | } |
2107 | |
2108 | TEST( |
2109 | WeakIntrusivePtrTest, |
2110 | givenInvalidPtr_whenCopyAssigningToBaseClass_thenPointsToSameObject) { |
2111 | IntrusiveAndWeak<SomeChildClass> obj1 = |
2112 | make_weak_intrusive<SomeChildClass>(5); |
2113 | weak_intrusive_ptr<SomeBaseClass> obj2 = make_invalid_weak<SomeBaseClass>(); |
2114 | SomeBaseClass* obj1ptr = obj1.weak.lock().get(); |
2115 | obj2 = obj1.weak; |
2116 | EXPECT_EQ(obj1ptr, obj2.lock().get()); |
2117 | EXPECT_EQ(5, obj2.lock()->v); |
2118 | } |
2119 | |
2120 | TEST( |
2121 | WeakIntrusivePtrTest, |
2122 | givenPtr_whenCopyAssigningInvalidPtrToBaseClass_thenNewInstanceIsInvalid) { |
2123 | weak_intrusive_ptr<SomeChildClass> obj1 = make_invalid_weak<SomeChildClass>(); |
2124 | IntrusiveAndWeak<SomeBaseClass> obj2 = make_weak_intrusive<SomeBaseClass>(2); |
2125 | EXPECT_FALSE(obj2.weak.expired()); |
2126 | obj2.weak = obj1; |
2127 | EXPECT_TRUE(obj2.weak.expired()); |
2128 | } |
2129 | |
2130 | TEST( |
2131 | WeakIntrusivePtrTest, |
2132 | givenWeakOnlyPtr_whenCopyAssigningToBaseClass_thenNewInstanceIsValid) { |
2133 | IntrusiveAndWeak<SomeChildClass> obj1 = |
2134 | make_weak_intrusive<SomeChildClass>(5); |
2135 | weak_intrusive_ptr<SomeBaseClass> obj2 = make_weak_only<SomeBaseClass>(2); |
2136 | obj1.weak.lock().get(); |
2137 | obj2 = obj1.weak; |
2138 | EXPECT_FALSE(obj2.expired()); |
2139 | } |
2140 | |
2141 | TEST( |
2142 | WeakIntrusivePtrTest, |
2143 | givenWeakOnlyPtr_whenCopyAssigningToBaseClass_thenPointsToSameObject) { |
2144 | IntrusiveAndWeak<SomeChildClass> obj1 = |
2145 | make_weak_intrusive<SomeChildClass>(5); |
2146 | weak_intrusive_ptr<SomeBaseClass> obj2 = make_weak_only<SomeBaseClass>(2); |
2147 | SomeBaseClass* obj1ptr = obj1.weak.lock().get(); |
2148 | obj2 = obj1.weak; |
2149 | EXPECT_EQ(obj1ptr, obj2.lock().get()); |
2150 | EXPECT_EQ(5, obj2.lock()->v); |
2151 | } |
2152 | |
2153 | TEST( |
2154 | WeakIntrusivePtrTest, |
2155 | givenPtr_whenCopyAssigningWeakOnlyPtrToBaseClass_thenNewInstanceIsValid) { |
2156 | weak_intrusive_ptr<SomeChildClass> obj1 = make_weak_only<SomeChildClass>(2); |
2157 | IntrusiveAndWeak<SomeBaseClass> obj2 = make_weak_intrusive<SomeBaseClass>(2); |
2158 | EXPECT_FALSE(obj2.weak.expired()); |
2159 | obj2.weak = obj1; |
2160 | EXPECT_TRUE(obj2.weak.expired()); |
2161 | } |
2162 | |
2163 | TEST( |
2164 | WeakIntrusivePtrTest, |
2165 | givenNullPtr_whenCopyAssigningToDifferentNullptr_thenHasNewNullptr) { |
2166 | weak_intrusive_ptr<SomeClass, NullType1> obj1 = |
2167 | make_invalid_weak<SomeClass, NullType1>(); |
2168 | weak_intrusive_ptr<SomeClass, NullType2> obj2 = |
2169 | make_invalid_weak<SomeClass, NullType2>(); |
2170 | obj2 = obj1; |
2171 | EXPECT_NE(NullType1::singleton(), NullType2::singleton()); |
2172 | EXPECT_TRUE(obj1.expired()); |
2173 | EXPECT_TRUE(obj2.expired()); |
2174 | } |
2175 | |
2176 | TEST( |
2177 | WeakIntrusivePtrTest, |
2178 | givenPtr_whenMoveConstructing_thenPointsToSameObject) { |
2179 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2180 | SomeClass* obj1ptr = obj1.weak.lock().get(); |
2181 | weak_intrusive_ptr<SomeClass> obj2 = std::move(obj1.weak); |
2182 | EXPECT_EQ(obj1ptr, obj2.lock().get()); |
2183 | } |
2184 | |
2185 | TEST( |
2186 | WeakIntrusivePtrTest, |
2187 | givenPtr_whenMoveConstructing_thenOldInstanceInvalid) { |
2188 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2189 | weak_intrusive_ptr<SomeClass> obj2 = std::move(obj1.weak); |
2190 | EXPECT_TRUE(obj1.weak.expired()); |
2191 | } |
2192 | |
2193 | TEST(WeakIntrusivePtrTest, givenPtr_whenMoveConstructing_thenNewInstanceValid) { |
2194 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2195 | weak_intrusive_ptr<SomeClass> obj2 = std::move(obj1.weak); |
2196 | EXPECT_FALSE(obj2.expired()); |
2197 | } |
2198 | |
2199 | TEST( |
2200 | WeakIntrusivePtrTest, |
2201 | givenPtr_whenMoveConstructingFromInvalidPtr_thenNewInstanceInvalid) { |
2202 | weak_intrusive_ptr<SomeClass> obj1 = make_invalid_weak<SomeClass>(); |
2203 | weak_intrusive_ptr<SomeClass> obj2 = std::move(obj1); |
2204 | EXPECT_TRUE(obj2.expired()); |
2205 | } |
2206 | |
2207 | TEST( |
2208 | WeakIntrusivePtrTest, |
2209 | givenPtr_whenMoveConstructingFromWeakOnlyPtr_thenNewInstanceInvalid) { |
2210 | weak_intrusive_ptr<SomeClass> obj1 = make_weak_only<SomeClass>(); |
2211 | weak_intrusive_ptr<SomeClass> obj2 = std::move(obj1); |
2212 | EXPECT_TRUE(obj2.expired()); |
2213 | } |
2214 | |
2215 | TEST( |
2216 | WeakIntrusivePtrTest, |
2217 | givenPtr_whenMoveConstructingToBaseClass_thenPointsToSameObject) { |
2218 | IntrusiveAndWeak<SomeChildClass> child = |
2219 | make_weak_intrusive<SomeChildClass>(3); |
2220 | SomeBaseClass* objptr = child.weak.lock().get(); |
2221 | weak_intrusive_ptr<SomeBaseClass> base = std::move(child.weak); |
2222 | EXPECT_EQ(3, base.lock()->v); |
2223 | EXPECT_EQ(objptr, base.lock().get()); |
2224 | } |
2225 | |
2226 | TEST( |
2227 | WeakIntrusivePtrTest, |
2228 | givenPtr_whenMoveConstructingToBaseClass_thenOldInstanceInvalid) { |
2229 | IntrusiveAndWeak<SomeChildClass> child = |
2230 | make_weak_intrusive<SomeChildClass>(3); |
2231 | weak_intrusive_ptr<SomeBaseClass> base = std::move(child.weak); |
2232 | EXPECT_TRUE(child.weak.expired()); |
2233 | } |
2234 | |
2235 | TEST( |
2236 | WeakIntrusivePtrTest, |
2237 | givenPtr_whenMoveConstructingToBaseClass_thenNewInstanceValid) { |
2238 | IntrusiveAndWeak<SomeChildClass> obj1 = |
2239 | make_weak_intrusive<SomeChildClass>(2); |
2240 | weak_intrusive_ptr<SomeBaseClass> obj2 = std::move(obj1.weak); |
2241 | EXPECT_FALSE(obj2.expired()); |
2242 | } |
2243 | |
2244 | TEST( |
2245 | WeakIntrusivePtrTest, |
2246 | givenPtr_whenMoveConstructingToBaseClassFromInvalidPtr_thenNewInstanceInvalid) { |
2247 | weak_intrusive_ptr<SomeChildClass> obj1 = make_invalid_weak<SomeChildClass>(); |
2248 | weak_intrusive_ptr<SomeBaseClass> obj2 = std::move(obj1); |
2249 | EXPECT_TRUE(obj2.expired()); |
2250 | } |
2251 | |
2252 | TEST( |
2253 | WeakIntrusivePtrTest, |
2254 | givenPtr_whenMoveConstructingToBaseClassFromWeakOnlyPtr_thenNewInstanceInvalid) { |
2255 | weak_intrusive_ptr<SomeChildClass> obj1 = make_weak_only<SomeChildClass>(2); |
2256 | weak_intrusive_ptr<SomeBaseClass> obj2 = std::move(obj1); |
2257 | EXPECT_TRUE(obj2.expired()); |
2258 | } |
2259 | |
2260 | TEST( |
2261 | WeakIntrusivePtrTest, |
2262 | givenNullPtr_whenMoveConstructingToDifferentNullptr_thenHasNewNullptr) { |
2263 | weak_intrusive_ptr<SomeClass, NullType1> obj1 = |
2264 | make_invalid_weak<SomeClass, NullType1>(); |
2265 | weak_intrusive_ptr<SomeClass, NullType2> obj2 = std::move(obj1); |
2266 | EXPECT_NE(NullType1::singleton(), NullType2::singleton()); |
2267 | // NOLINTNEXTLINE(bugprone-use-after-move) |
2268 | EXPECT_TRUE(obj1.expired()); |
2269 | EXPECT_TRUE(obj2.expired()); |
2270 | } |
2271 | |
2272 | TEST( |
2273 | WeakIntrusivePtrTest, |
2274 | givenPtr_whenCopyConstructing_thenPointsToSameObject) { |
2275 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2276 | SomeClass* obj1ptr = obj1.weak.lock().get(); |
2277 | weak_intrusive_ptr<SomeClass> obj2 = obj1.weak; |
2278 | EXPECT_EQ(obj1ptr, obj2.lock().get()); |
2279 | EXPECT_FALSE(obj1.weak.expired()); |
2280 | } |
2281 | |
2282 | TEST(WeakIntrusivePtrTest, givenPtr_whenCopyConstructing_thenOldInstanceValid) { |
2283 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2284 | weak_intrusive_ptr<SomeClass> obj2 = obj1.weak; |
2285 | EXPECT_FALSE(obj1.weak.expired()); |
2286 | } |
2287 | |
2288 | TEST(WeakIntrusivePtrTest, givenPtr_whenCopyConstructing_thenNewInstanceValid) { |
2289 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2290 | weak_intrusive_ptr<SomeClass> obj2 = obj1.weak; |
2291 | EXPECT_FALSE(obj2.expired()); |
2292 | } |
2293 | |
2294 | TEST( |
2295 | WeakIntrusivePtrTest, |
2296 | givenPtr_whenCopyConstructingFromInvalidPtr_thenNewInstanceInvalid) { |
2297 | weak_intrusive_ptr<SomeClass> obj1 = make_invalid_weak<SomeClass>(); |
2298 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
2299 | weak_intrusive_ptr<SomeClass> obj2 = obj1; |
2300 | EXPECT_TRUE(obj2.expired()); |
2301 | } |
2302 | |
2303 | TEST( |
2304 | WeakIntrusivePtrTest, |
2305 | givenPtr_whenCopyConstructingFromWeakOnlyPtr_thenNewInstanceInvalid) { |
2306 | weak_intrusive_ptr<SomeClass> obj1 = make_weak_only<SomeClass>(); |
2307 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
2308 | weak_intrusive_ptr<SomeClass> obj2 = obj1; |
2309 | EXPECT_TRUE(obj2.expired()); |
2310 | } |
2311 | |
2312 | TEST( |
2313 | WeakIntrusivePtrTest, |
2314 | givenPtr_whenCopyConstructingToBaseClass_thenPointsToSameObject) { |
2315 | IntrusiveAndWeak<SomeChildClass> child = |
2316 | make_weak_intrusive<SomeChildClass>(3); |
2317 | SomeBaseClass* objptr = child.weak.lock().get(); |
2318 | weak_intrusive_ptr<SomeBaseClass> base = child.weak; |
2319 | EXPECT_EQ(3, base.lock()->v); |
2320 | EXPECT_EQ(objptr, base.lock().get()); |
2321 | } |
2322 | |
2323 | TEST( |
2324 | WeakIntrusivePtrTest, |
2325 | givenPtr_whenCopyConstructingToBaseClass_thenOldInstanceInvalid) { |
2326 | IntrusiveAndWeak<SomeChildClass> child = |
2327 | make_weak_intrusive<SomeChildClass>(3); |
2328 | weak_intrusive_ptr<SomeBaseClass> base = child.weak; |
2329 | EXPECT_FALSE(child.weak.expired()); |
2330 | } |
2331 | |
2332 | TEST( |
2333 | WeakIntrusivePtrTest, |
2334 | givenPtr_whenCopyConstructingToBaseClass_thenNewInstanceInvalid) { |
2335 | IntrusiveAndWeak<SomeChildClass> child = |
2336 | make_weak_intrusive<SomeChildClass>(3); |
2337 | weak_intrusive_ptr<SomeBaseClass> base = child.weak; |
2338 | EXPECT_FALSE(base.expired()); |
2339 | } |
2340 | |
2341 | TEST( |
2342 | WeakIntrusivePtrTest, |
2343 | givenPtr_whenCopyConstructingToBaseClassFromInvalidPtr_thenNewInstanceInvalid) { |
2344 | weak_intrusive_ptr<SomeChildClass> obj1 = make_invalid_weak<SomeChildClass>(); |
2345 | weak_intrusive_ptr<SomeBaseClass> obj2 = obj1; |
2346 | EXPECT_TRUE(obj2.expired()); |
2347 | } |
2348 | |
2349 | TEST( |
2350 | WeakIntrusivePtrTest, |
2351 | givenPtr_whenCopyConstructingToBaseClassFromWeakOnlyPtr_thenNewInstanceInvalid) { |
2352 | weak_intrusive_ptr<SomeChildClass> obj1 = make_weak_only<SomeChildClass>(2); |
2353 | weak_intrusive_ptr<SomeBaseClass> obj2 = obj1; |
2354 | EXPECT_TRUE(obj2.expired()); |
2355 | } |
2356 | |
2357 | TEST( |
2358 | WeakIntrusivePtrTest, |
2359 | givenNullPtr_whenCopyConstructingToDifferentNullptr_thenHasNewNullptr) { |
2360 | weak_intrusive_ptr<SomeClass, NullType1> obj1 = |
2361 | make_invalid_weak<SomeClass, NullType1>(); |
2362 | weak_intrusive_ptr<SomeClass, NullType2> obj2 = obj1; |
2363 | EXPECT_NE(NullType1::singleton(), NullType2::singleton()); |
2364 | EXPECT_TRUE(obj1.expired()); |
2365 | EXPECT_TRUE(obj2.expired()); |
2366 | } |
2367 | |
2368 | TEST(WeakIntrusivePtrTest, SwapFunction) { |
2369 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2370 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
2371 | SomeClass* obj1ptr = obj1.weak.lock().get(); |
2372 | SomeClass* obj2ptr = obj2.weak.lock().get(); |
2373 | swap(obj1.weak, obj2.weak); |
2374 | EXPECT_EQ(obj2ptr, obj1.weak.lock().get()); |
2375 | EXPECT_EQ(obj1ptr, obj2.weak.lock().get()); |
2376 | } |
2377 | |
2378 | TEST(WeakIntrusivePtrTest, SwapMethod) { |
2379 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2380 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
2381 | SomeClass* obj1ptr = obj1.weak.lock().get(); |
2382 | SomeClass* obj2ptr = obj2.weak.lock().get(); |
2383 | obj1.weak.swap(obj2.weak); |
2384 | EXPECT_EQ(obj2ptr, obj1.weak.lock().get()); |
2385 | EXPECT_EQ(obj1ptr, obj2.weak.lock().get()); |
2386 | } |
2387 | |
2388 | TEST(WeakIntrusivePtrTest, SwapFunctionFromInvalid) { |
2389 | weak_intrusive_ptr<SomeClass> obj1 = make_invalid_weak<SomeClass>(); |
2390 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
2391 | SomeClass* obj2ptr = obj2.weak.lock().get(); |
2392 | swap(obj1, obj2.weak); |
2393 | EXPECT_EQ(obj2ptr, obj1.lock().get()); |
2394 | EXPECT_FALSE(obj1.expired()); |
2395 | EXPECT_TRUE(obj2.weak.expired()); |
2396 | } |
2397 | |
2398 | TEST(WeakIntrusivePtrTest, SwapMethodFromInvalid) { |
2399 | weak_intrusive_ptr<SomeClass> obj1 = make_invalid_weak<SomeClass>(); |
2400 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
2401 | SomeClass* obj2ptr = obj2.weak.lock().get(); |
2402 | obj1.swap(obj2.weak); |
2403 | EXPECT_EQ(obj2ptr, obj1.lock().get()); |
2404 | EXPECT_FALSE(obj1.expired()); |
2405 | EXPECT_TRUE(obj2.weak.expired()); |
2406 | } |
2407 | |
2408 | TEST(WeakIntrusivePtrTest, SwapFunctionWithInvalid) { |
2409 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2410 | weak_intrusive_ptr<SomeClass> obj2 = make_invalid_weak<SomeClass>(); |
2411 | SomeClass* obj1ptr = obj1.weak.lock().get(); |
2412 | swap(obj1.weak, obj2); |
2413 | EXPECT_TRUE(obj1.weak.expired()); |
2414 | EXPECT_FALSE(obj2.expired()); |
2415 | EXPECT_EQ(obj1ptr, obj2.lock().get()); |
2416 | } |
2417 | |
2418 | TEST(WeakIntrusivePtrTest, SwapMethodWithInvalid) { |
2419 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2420 | weak_intrusive_ptr<SomeClass> obj2 = make_invalid_weak<SomeClass>(); |
2421 | SomeClass* obj1ptr = obj1.weak.lock().get(); |
2422 | obj1.weak.swap(obj2); |
2423 | EXPECT_TRUE(obj1.weak.expired()); |
2424 | EXPECT_FALSE(obj2.expired()); |
2425 | EXPECT_EQ(obj1ptr, obj2.lock().get()); |
2426 | } |
2427 | |
2428 | TEST(WeakIntrusivePtrTest, SwapFunctionInvalidWithInvalid) { |
2429 | weak_intrusive_ptr<SomeClass> obj1 = make_invalid_weak<SomeClass>(); |
2430 | weak_intrusive_ptr<SomeClass> obj2 = make_invalid_weak<SomeClass>(); |
2431 | swap(obj1, obj2); |
2432 | EXPECT_TRUE(obj1.expired()); |
2433 | EXPECT_TRUE(obj2.expired()); |
2434 | } |
2435 | |
2436 | TEST(WeakIntrusivePtrTest, SwapMethodInvalidWithInvalid) { |
2437 | weak_intrusive_ptr<SomeClass> obj1 = make_invalid_weak<SomeClass>(); |
2438 | weak_intrusive_ptr<SomeClass> obj2 = make_invalid_weak<SomeClass>(); |
2439 | obj1.swap(obj2); |
2440 | EXPECT_TRUE(obj1.expired()); |
2441 | EXPECT_TRUE(obj2.expired()); |
2442 | } |
2443 | |
2444 | TEST(WeakIntrusivePtrTest, SwapFunctionFromWeakOnlyPtr) { |
2445 | weak_intrusive_ptr<SomeClass> obj1 = make_weak_only<SomeClass>(); |
2446 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
2447 | SomeClass* obj2ptr = obj2.weak.lock().get(); |
2448 | swap(obj1, obj2.weak); |
2449 | EXPECT_EQ(obj2ptr, obj1.lock().get()); |
2450 | EXPECT_FALSE(obj1.expired()); |
2451 | EXPECT_TRUE(obj2.weak.expired()); |
2452 | } |
2453 | |
2454 | TEST(WeakIntrusivePtrTest, SwapMethodFromWeakOnlyPtr) { |
2455 | weak_intrusive_ptr<SomeClass> obj1 = make_weak_only<SomeClass>(); |
2456 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
2457 | SomeClass* obj2ptr = obj2.weak.lock().get(); |
2458 | obj1.swap(obj2.weak); |
2459 | EXPECT_EQ(obj2ptr, obj1.lock().get()); |
2460 | EXPECT_FALSE(obj1.expired()); |
2461 | EXPECT_TRUE(obj2.weak.expired()); |
2462 | } |
2463 | |
2464 | TEST(WeakIntrusivePtrTest, SwapFunctionWithWeakOnlyPtr) { |
2465 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2466 | weak_intrusive_ptr<SomeClass> obj2 = make_weak_only<SomeClass>(); |
2467 | SomeClass* obj1ptr = obj1.weak.lock().get(); |
2468 | swap(obj1.weak, obj2); |
2469 | EXPECT_TRUE(obj1.weak.expired()); |
2470 | EXPECT_FALSE(obj2.expired()); |
2471 | EXPECT_EQ(obj1ptr, obj2.lock().get()); |
2472 | } |
2473 | |
2474 | TEST(WeakIntrusivePtrTest, SwapMethodWithWeakOnlyPtr) { |
2475 | IntrusiveAndWeak<SomeClass> obj1 = make_weak_intrusive<SomeClass>(); |
2476 | weak_intrusive_ptr<SomeClass> obj2 = make_weak_only<SomeClass>(); |
2477 | SomeClass* obj1ptr = obj1.weak.lock().get(); |
2478 | obj1.weak.swap(obj2); |
2479 | EXPECT_TRUE(obj1.weak.expired()); |
2480 | EXPECT_FALSE(obj2.expired()); |
2481 | EXPECT_EQ(obj1ptr, obj2.lock().get()); |
2482 | } |
2483 | |
2484 | TEST(WeakIntrusivePtrTest, SwapFunctionWeakOnlyPtrWithWeakOnlyPtr) { |
2485 | weak_intrusive_ptr<SomeClass> obj1 = make_weak_only<SomeClass>(); |
2486 | weak_intrusive_ptr<SomeClass> obj2 = make_weak_only<SomeClass>(); |
2487 | swap(obj1, obj2); |
2488 | EXPECT_TRUE(obj1.expired()); |
2489 | EXPECT_TRUE(obj2.expired()); |
2490 | } |
2491 | |
2492 | TEST(WeakIntrusivePtrTest, SwapMethodWeakOnlyPtrWithWeakOnlyPtr) { |
2493 | weak_intrusive_ptr<SomeClass> obj1 = make_weak_only<SomeClass>(); |
2494 | weak_intrusive_ptr<SomeClass> obj2 = make_weak_only<SomeClass>(); |
2495 | obj1.swap(obj2); |
2496 | EXPECT_TRUE(obj1.expired()); |
2497 | EXPECT_TRUE(obj2.expired()); |
2498 | } |
2499 | |
2500 | TEST(WeakIntrusivePtrTest, CanBePutInContainer) { |
2501 | std::vector<weak_intrusive_ptr<SomeClass1Parameter>> vec; |
2502 | IntrusiveAndWeak<SomeClass1Parameter> obj = |
2503 | make_weak_intrusive<SomeClass1Parameter>(5); |
2504 | vec.push_back(obj.weak); |
2505 | EXPECT_EQ(5, vec[0].lock()->param); |
2506 | } |
2507 | |
2508 | TEST(WeakIntrusivePtrTest, CanBePutInSet) { |
2509 | std::set<weak_intrusive_ptr<SomeClass1Parameter>> set; |
2510 | IntrusiveAndWeak<SomeClass1Parameter> obj = |
2511 | make_weak_intrusive<SomeClass1Parameter>(5); |
2512 | set.insert(obj.weak); |
2513 | EXPECT_EQ(5, set.begin()->lock()->param); |
2514 | } |
2515 | |
2516 | TEST(WeakIntrusivePtrTest, CanBePutInUnorderedSet) { |
2517 | std::unordered_set<weak_intrusive_ptr<SomeClass1Parameter>> set; |
2518 | IntrusiveAndWeak<SomeClass1Parameter> obj = |
2519 | make_weak_intrusive<SomeClass1Parameter>(5); |
2520 | set.insert(obj.weak); |
2521 | EXPECT_EQ(5, set.begin()->lock()->param); |
2522 | } |
2523 | |
2524 | TEST(WeakIntrusivePtrTest, CanBePutInMap) { |
2525 | std::map< |
2526 | weak_intrusive_ptr<SomeClass1Parameter>, |
2527 | weak_intrusive_ptr<SomeClass1Parameter>> |
2528 | map; |
2529 | IntrusiveAndWeak<SomeClass1Parameter> obj1 = |
2530 | make_weak_intrusive<SomeClass1Parameter>(5); |
2531 | IntrusiveAndWeak<SomeClass1Parameter> obj2 = |
2532 | make_weak_intrusive<SomeClass1Parameter>(3); |
2533 | map.insert(std::make_pair(obj1.weak, obj2.weak)); |
2534 | EXPECT_EQ(5, map.begin()->first.lock()->param); |
2535 | EXPECT_EQ(3, map.begin()->second.lock()->param); |
2536 | } |
2537 | |
2538 | TEST(WeakIntrusivePtrTest, CanBePutInUnorderedMap) { |
2539 | std::unordered_map< |
2540 | weak_intrusive_ptr<SomeClass1Parameter>, |
2541 | weak_intrusive_ptr<SomeClass1Parameter>> |
2542 | map; |
2543 | IntrusiveAndWeak<SomeClass1Parameter> obj1 = |
2544 | make_weak_intrusive<SomeClass1Parameter>(5); |
2545 | IntrusiveAndWeak<SomeClass1Parameter> obj2 = |
2546 | make_weak_intrusive<SomeClass1Parameter>(3); |
2547 | map.insert(std::make_pair(obj1.weak, obj2.weak)); |
2548 | EXPECT_EQ(5, map.begin()->first.lock()->param); |
2549 | EXPECT_EQ(3, map.begin()->second.lock()->param); |
2550 | } |
2551 | |
2552 | TEST(WeakIntrusivePtrTest, Equality_AfterCopyConstructor) { |
2553 | IntrusiveAndWeak<SomeClass> var1 = make_weak_intrusive<SomeClass>(); |
2554 | weak_intrusive_ptr<SomeClass> var2 = var1.weak; |
2555 | EXPECT_TRUE(var1.weak == var2); |
2556 | EXPECT_FALSE(var1.weak != var2); |
2557 | } |
2558 | |
2559 | TEST(WeakIntrusivePtrTest, Equality_AfterCopyAssignment) { |
2560 | IntrusiveAndWeak<SomeClass> var1 = make_weak_intrusive<SomeClass>(); |
2561 | IntrusiveAndWeak<SomeClass> var2 = make_weak_intrusive<SomeClass>(); |
2562 | var2.weak = var1.weak; |
2563 | EXPECT_TRUE(var1.weak == var2.weak); |
2564 | EXPECT_FALSE(var1.weak != var2.weak); |
2565 | } |
2566 | |
2567 | TEST(WeakIntrusivePtrTest, Equality_AfterCopyAssignment_WeakOnly) { |
2568 | weak_intrusive_ptr<SomeClass> var1 = make_weak_only<SomeClass>(); |
2569 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
2570 | weak_intrusive_ptr<SomeClass> var2 = var1; |
2571 | EXPECT_TRUE(var1 == var2); |
2572 | EXPECT_FALSE(var1 != var2); |
2573 | } |
2574 | |
2575 | TEST(WeakIntrusivePtrTest, Equality_Invalid) { |
2576 | weak_intrusive_ptr<SomeClass> var1 = make_invalid_weak<SomeClass>(); |
2577 | weak_intrusive_ptr<SomeClass> var2 = make_invalid_weak<SomeClass>(); |
2578 | EXPECT_TRUE(var1 == var2); |
2579 | EXPECT_FALSE(var1 != var2); |
2580 | } |
2581 | |
2582 | TEST(WeakIntrusivePtrTest, Inequality) { |
2583 | IntrusiveAndWeak<SomeClass> var1 = make_intrusive<SomeClass>(); |
2584 | IntrusiveAndWeak<SomeClass> var2 = make_intrusive<SomeClass>(); |
2585 | EXPECT_TRUE(var1.weak != var2.weak); |
2586 | EXPECT_FALSE(var1.weak == var2.weak); |
2587 | } |
2588 | |
2589 | TEST(WeakIntrusivePtrTest, Inequality_InvalidLeft) { |
2590 | weak_intrusive_ptr<SomeClass> var1 = make_invalid_weak<SomeClass>(); |
2591 | IntrusiveAndWeak<SomeClass> var2 = make_intrusive<SomeClass>(); |
2592 | EXPECT_TRUE(var1 != var2.weak); |
2593 | EXPECT_FALSE(var1 == var2.weak); |
2594 | } |
2595 | |
2596 | TEST(WeakIntrusivePtrTest, Inequality_InvalidRight) { |
2597 | IntrusiveAndWeak<SomeClass> var1 = make_intrusive<SomeClass>(); |
2598 | weak_intrusive_ptr<SomeClass> var2 = make_invalid_weak<SomeClass>(); |
2599 | EXPECT_TRUE(var1.weak != var2); |
2600 | EXPECT_FALSE(var1.weak == var2); |
2601 | } |
2602 | |
2603 | TEST(WeakIntrusivePtrTest, Inequality_WeakOnly) { |
2604 | weak_intrusive_ptr<SomeClass> var1 = make_weak_only<SomeClass>(); |
2605 | weak_intrusive_ptr<SomeClass> var2 = make_weak_only<SomeClass>(); |
2606 | EXPECT_TRUE(var1 != var2); |
2607 | EXPECT_FALSE(var1 == var2); |
2608 | } |
2609 | |
2610 | TEST(WeakIntrusivePtrTest, HashIsDifferent) { |
2611 | IntrusiveAndWeak<SomeClass> var1 = make_weak_intrusive<SomeClass>(); |
2612 | IntrusiveAndWeak<SomeClass> var2 = make_weak_intrusive<SomeClass>(); |
2613 | EXPECT_NE( |
2614 | std::hash<weak_intrusive_ptr<SomeClass>>()(var1.weak), |
2615 | std::hash<weak_intrusive_ptr<SomeClass>>()(var2.weak)); |
2616 | } |
2617 | |
2618 | TEST(WeakIntrusivePtrTest, HashIsDifferent_ValidAndInvalid) { |
2619 | weak_intrusive_ptr<SomeClass> var1 = make_invalid_weak<SomeClass>(); |
2620 | IntrusiveAndWeak<SomeClass> var2 = make_weak_intrusive<SomeClass>(); |
2621 | EXPECT_NE( |
2622 | std::hash<weak_intrusive_ptr<SomeClass>>()(var1), |
2623 | std::hash<weak_intrusive_ptr<SomeClass>>()(var2.weak)); |
2624 | } |
2625 | |
2626 | TEST(WeakIntrusivePtrTest, HashIsDifferent_ValidAndWeakOnly) { |
2627 | weak_intrusive_ptr<SomeClass> var1 = make_weak_only<SomeClass>(); |
2628 | IntrusiveAndWeak<SomeClass> var2 = make_weak_intrusive<SomeClass>(); |
2629 | EXPECT_NE( |
2630 | std::hash<weak_intrusive_ptr<SomeClass>>()(var1), |
2631 | std::hash<weak_intrusive_ptr<SomeClass>>()(var2.weak)); |
2632 | } |
2633 | |
2634 | TEST(WeakIntrusivePtrTest, HashIsDifferent_WeakOnlyAndWeakOnly) { |
2635 | weak_intrusive_ptr<SomeClass> var1 = make_weak_only<SomeClass>(); |
2636 | weak_intrusive_ptr<SomeClass> var2 = make_weak_only<SomeClass>(); |
2637 | EXPECT_NE( |
2638 | std::hash<weak_intrusive_ptr<SomeClass>>()(var1), |
2639 | std::hash<weak_intrusive_ptr<SomeClass>>()(var2)); |
2640 | } |
2641 | |
2642 | TEST(WeakIntrusivePtrTest, HashIsSame_AfterCopyConstructor) { |
2643 | IntrusiveAndWeak<SomeClass> var1 = make_weak_intrusive<SomeClass>(); |
2644 | weak_intrusive_ptr<SomeClass> var2 = var1.weak; |
2645 | EXPECT_EQ( |
2646 | std::hash<weak_intrusive_ptr<SomeClass>>()(var1.weak), |
2647 | std::hash<weak_intrusive_ptr<SomeClass>>()(var2)); |
2648 | } |
2649 | |
2650 | TEST(WeakIntrusivePtrTest, HashIsSame_AfterCopyConstructor_WeakOnly) { |
2651 | weak_intrusive_ptr<SomeClass> var1 = make_weak_only<SomeClass>(); |
2652 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
2653 | weak_intrusive_ptr<SomeClass> var2 = var1; |
2654 | EXPECT_EQ( |
2655 | std::hash<weak_intrusive_ptr<SomeClass>>()(var1), |
2656 | std::hash<weak_intrusive_ptr<SomeClass>>()(var2)); |
2657 | } |
2658 | |
2659 | TEST(WeakIntrusivePtrTest, HashIsSame_AfterCopyAssignment) { |
2660 | IntrusiveAndWeak<SomeClass> var1 = make_weak_intrusive<SomeClass>(); |
2661 | IntrusiveAndWeak<SomeClass> var2 = make_weak_intrusive<SomeClass>(); |
2662 | var2.weak = var1.weak; |
2663 | EXPECT_EQ( |
2664 | std::hash<weak_intrusive_ptr<SomeClass>>()(var1.weak), |
2665 | std::hash<weak_intrusive_ptr<SomeClass>>()(var2.weak)); |
2666 | } |
2667 | |
2668 | TEST(WeakIntrusivePtrTest, HashIsSame_AfterCopyAssignment_WeakOnly) { |
2669 | weak_intrusive_ptr<SomeClass> var1 = make_weak_only<SomeClass>(); |
2670 | weak_intrusive_ptr<SomeClass> var2 = make_invalid_weak<SomeClass>(); |
2671 | var2 = var1; |
2672 | EXPECT_EQ( |
2673 | std::hash<weak_intrusive_ptr<SomeClass>>()(var1), |
2674 | std::hash<weak_intrusive_ptr<SomeClass>>()(var2)); |
2675 | } |
2676 | |
2677 | TEST(WeakIntrusivePtrTest, HashIsSame_BothInvalid) { |
2678 | weak_intrusive_ptr<SomeClass> var1 = make_invalid_weak<SomeClass>(); |
2679 | weak_intrusive_ptr<SomeClass> var2 = make_invalid_weak<SomeClass>(); |
2680 | EXPECT_EQ( |
2681 | std::hash<weak_intrusive_ptr<SomeClass>>()(var1), |
2682 | std::hash<weak_intrusive_ptr<SomeClass>>()(var2)); |
2683 | } |
2684 | |
2685 | TEST(WeakIntrusivePtrTest, OneIsLess) { |
2686 | IntrusiveAndWeak<SomeClass> var1 = make_weak_intrusive<SomeClass>(); |
2687 | IntrusiveAndWeak<SomeClass> var2 = make_weak_intrusive<SomeClass>(); |
2688 | EXPECT_TRUE( |
2689 | // NOLINTNEXTLINE(modernize-use-transparent-functors) |
2690 | std::less<weak_intrusive_ptr<SomeClass>>()(var1.weak, var2.weak) != |
2691 | // NOLINTNEXTLINE(modernize-use-transparent-functors) |
2692 | std::less<weak_intrusive_ptr<SomeClass>>()(var2.weak, var1.weak)); |
2693 | } |
2694 | |
2695 | TEST(WeakIntrusivePtrTest, InvalidIsLess1) { |
2696 | weak_intrusive_ptr<SomeClass> var1 = make_invalid_weak<SomeClass>(); |
2697 | IntrusiveAndWeak<SomeClass> var2 = make_weak_intrusive<SomeClass>(); |
2698 | // NOLINTNEXTLINE(modernize-use-transparent-functors) |
2699 | EXPECT_TRUE(std::less<weak_intrusive_ptr<SomeClass>>()(var1, var2.weak)); |
2700 | } |
2701 | |
2702 | TEST(WeakIntrusivePtrTest, InvalidIsLess2) { |
2703 | IntrusiveAndWeak<SomeClass> var1 = make_weak_intrusive<SomeClass>(); |
2704 | weak_intrusive_ptr<SomeClass> var2 = make_invalid_weak<SomeClass>(); |
2705 | // NOLINTNEXTLINE(modernize-use-transparent-functors) |
2706 | EXPECT_FALSE(std::less<weak_intrusive_ptr<SomeClass>>()(var1.weak, var2)); |
2707 | } |
2708 | |
2709 | TEST(WeakIntrusivePtrTest, InvalidIsNotLessThanInvalid) { |
2710 | weak_intrusive_ptr<SomeClass> var1 = make_invalid_weak<SomeClass>(); |
2711 | weak_intrusive_ptr<SomeClass> var2 = make_invalid_weak<SomeClass>(); |
2712 | // NOLINTNEXTLINE(modernize-use-transparent-functors) |
2713 | EXPECT_FALSE(std::less<weak_intrusive_ptr<SomeClass>>()(var1, var2)); |
2714 | } |
2715 | |
2716 | TEST(WeakIntrusivePtrTest, givenPtr_whenCallingResetOnWeakPtr_thenIsInvalid) { |
2717 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2718 | EXPECT_FALSE(obj.weak.expired()); |
2719 | obj.weak.reset(); |
2720 | EXPECT_TRUE(obj.weak.expired()); |
2721 | } |
2722 | |
2723 | TEST(WeakIntrusivePtrTest, givenPtr_whenCallingResetOnStrongPtr_thenIsInvalid) { |
2724 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2725 | EXPECT_FALSE(obj.weak.expired()); |
2726 | obj.ptr.reset(); |
2727 | EXPECT_TRUE(obj.weak.expired()); |
2728 | } |
2729 | |
2730 | TEST(WeakIntrusivePtrTest, AllowsMoveConstructingToConst) { |
2731 | IntrusiveAndWeak<SomeClass> a = make_weak_intrusive<SomeClass>(); |
2732 | weak_intrusive_ptr<const SomeClass> b = std::move(a.weak); |
2733 | } |
2734 | |
2735 | TEST(WeakIntrusivePtrTest, AllowsCopyConstructingToConst) { |
2736 | IntrusiveAndWeak<SomeClass> a = make_weak_intrusive<SomeClass>(); |
2737 | weak_intrusive_ptr<const SomeClass> b = a.weak; |
2738 | } |
2739 | |
2740 | TEST(WeakIntrusivePtrTest, AllowsMoveAssigningToConst) { |
2741 | IntrusiveAndWeak<SomeClass> a = make_weak_intrusive<SomeClass>(); |
2742 | IntrusiveAndWeak<const SomeClass> b = make_weak_intrusive<const SomeClass>(); |
2743 | b.weak = std::move(a.weak); |
2744 | } |
2745 | |
2746 | TEST(WeakIntrusivePtrTest, AllowsCopyAssigningToConst) { |
2747 | IntrusiveAndWeak<SomeClass> a = make_weak_intrusive<SomeClass>(); |
2748 | IntrusiveAndWeak<const SomeClass> b = make_weak_intrusive<const SomeClass>(); |
2749 | b.weak = a.weak; |
2750 | } |
2751 | |
2752 | TEST(WeakIntrusivePtrTest, givenNewPtr_thenHasUseCount1) { |
2753 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2754 | EXPECT_EQ(1, obj.weak.use_count()); |
2755 | } |
2756 | |
2757 | TEST(WeakIntrusivePtrTest, givenNewPtr_thenIsNotExpired) { |
2758 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2759 | EXPECT_FALSE(obj.weak.expired()); |
2760 | } |
2761 | |
2762 | TEST(WeakIntrusivePtrTest, givenInvalidPtr_thenHasUseCount0) { |
2763 | weak_intrusive_ptr<SomeClass> obj = make_invalid_weak<SomeClass>(); |
2764 | EXPECT_EQ(0, obj.use_count()); |
2765 | } |
2766 | |
2767 | TEST(WeakIntrusivePtrTest, givenInvalidPtr_thenIsExpired) { |
2768 | weak_intrusive_ptr<SomeClass> obj = make_invalid_weak<SomeClass>(); |
2769 | EXPECT_TRUE(obj.expired()); |
2770 | } |
2771 | |
2772 | TEST(WeakIntrusivePtrTest, givenWeakOnlyPtr_thenHasUseCount0) { |
2773 | weak_intrusive_ptr<SomeClass> obj = make_weak_only<SomeClass>(); |
2774 | EXPECT_EQ(0, obj.use_count()); |
2775 | } |
2776 | |
2777 | TEST(WeakIntrusivePtrTest, givenWeakOnlyPtr_thenIsExpired) { |
2778 | weak_intrusive_ptr<SomeClass> obj = make_weak_only<SomeClass>(); |
2779 | EXPECT_TRUE(obj.expired()); |
2780 | } |
2781 | |
2782 | TEST(WeakIntrusivePtrTest, givenPtr_whenCallingWeakReset_thenHasUseCount0) { |
2783 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2784 | obj.weak.reset(); |
2785 | EXPECT_EQ(0, obj.weak.use_count()); |
2786 | } |
2787 | |
2788 | TEST(WeakIntrusivePtrTest, givenPtr_whenCallingWeakReset_thenIsExpired) { |
2789 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2790 | obj.weak.reset(); |
2791 | EXPECT_TRUE(obj.weak.expired()); |
2792 | } |
2793 | |
2794 | TEST(WeakIntrusivePtrTest, givenPtr_whenCallingStrongReset_thenHasUseCount0) { |
2795 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2796 | obj.ptr.reset(); |
2797 | EXPECT_EQ(0, obj.weak.use_count()); |
2798 | } |
2799 | |
2800 | TEST(WeakIntrusivePtrTest, givenPtr_whenCallingStrongReset_thenIsExpired) { |
2801 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2802 | obj.ptr.reset(); |
2803 | EXPECT_TRUE(obj.weak.expired()); |
2804 | } |
2805 | |
2806 | TEST(WeakIntrusivePtrTest, givenMoveConstructedPtr_thenHasUseCount1) { |
2807 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2808 | weak_intrusive_ptr<SomeClass> obj2 = std::move(obj.weak); |
2809 | EXPECT_EQ(1, obj2.use_count()); |
2810 | } |
2811 | |
2812 | TEST(WeakIntrusivePtrTest, givenMoveConstructedPtr_thenIsNotExpired) { |
2813 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2814 | weak_intrusive_ptr<SomeClass> obj2 = std::move(obj.weak); |
2815 | EXPECT_FALSE(obj2.expired()); |
2816 | } |
2817 | |
2818 | TEST(WeakIntrusivePtrTest, givenMoveConstructedPtr_thenOldHasUseCount0) { |
2819 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2820 | weak_intrusive_ptr<SomeClass> obj2 = std::move(obj.weak); |
2821 | EXPECT_EQ(0, obj.weak.use_count()); |
2822 | } |
2823 | |
2824 | TEST(WeakIntrusivePtrTest, givenMoveConstructedPtr_thenOldIsExpired) { |
2825 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2826 | weak_intrusive_ptr<SomeClass> obj2 = std::move(obj.weak); |
2827 | EXPECT_TRUE(obj.weak.expired()); |
2828 | } |
2829 | |
2830 | TEST(WeakIntrusivePtrTest, givenMoveAssignedPtr_thenHasUseCount1) { |
2831 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2832 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
2833 | obj2.weak = std::move(obj.weak); |
2834 | EXPECT_EQ(1, obj2.weak.use_count()); |
2835 | } |
2836 | |
2837 | TEST(WeakIntrusivePtrTest, givenMoveAssignedPtr_thenIsNotExpired) { |
2838 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2839 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
2840 | obj2.weak = std::move(obj.weak); |
2841 | EXPECT_FALSE(obj2.weak.expired()); |
2842 | } |
2843 | |
2844 | TEST(WeakIntrusivePtrTest, givenMoveAssignedPtr_thenOldHasUseCount0) { |
2845 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2846 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
2847 | obj2.weak = std::move(obj.weak); |
2848 | EXPECT_EQ(0, obj.weak.use_count()); |
2849 | } |
2850 | |
2851 | TEST(WeakIntrusivePtrTest, givenMoveAssignedPtr_thenOldIsExpired) { |
2852 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2853 | IntrusiveAndWeak<SomeClass> obj2 = make_weak_intrusive<SomeClass>(); |
2854 | obj2.weak = std::move(obj.weak); |
2855 | EXPECT_TRUE(obj.weak.expired()); |
2856 | } |
2857 | |
2858 | TEST(WeakIntrusivePtrTest, givenCopyConstructedPtr_thenHasUseCount1) { |
2859 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2860 | weak_intrusive_ptr<SomeClass> obj2 = obj.weak; |
2861 | EXPECT_EQ(1, obj2.use_count()); |
2862 | } |
2863 | |
2864 | TEST(WeakIntrusivePtrTest, givenCopyConstructedPtr_thenIsNotExpired) { |
2865 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2866 | weak_intrusive_ptr<SomeClass> obj2 = obj.weak; |
2867 | EXPECT_FALSE(obj2.expired()); |
2868 | } |
2869 | |
2870 | TEST(WeakIntrusivePtrTest, givenCopyConstructedPtr_thenOldHasUseCount1) { |
2871 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2872 | weak_intrusive_ptr<SomeClass> obj2 = obj.weak; |
2873 | EXPECT_EQ(1, obj.weak.use_count()); |
2874 | } |
2875 | |
2876 | TEST(WeakIntrusivePtrTest, givenCopyConstructedPtr_thenOldIsNotExpired) { |
2877 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
2878 | weak_intrusive_ptr<SomeClass> obj2 = obj.weak; |
2879 | EXPECT_FALSE(obj.weak.expired()); |
2880 | } |
2881 | |
2882 | TEST( |
2883 | WeakIntrusivePtrTest, |
2884 | givenPtr_whenLastStrongPointerResets_thenReleasesResources) { |
2885 | bool resourcesReleased = false; |
2886 | bool wasDestructed = false; |
2887 | auto obj = |
2888 | make_weak_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
2889 | EXPECT_FALSE(resourcesReleased); |
2890 | EXPECT_FALSE(wasDestructed); |
2891 | obj.ptr.reset(); |
2892 | EXPECT_TRUE(resourcesReleased); |
2893 | EXPECT_FALSE(wasDestructed); |
2894 | obj.weak.reset(); |
2895 | EXPECT_TRUE(resourcesReleased); |
2896 | EXPECT_TRUE(wasDestructed); |
2897 | } |
2898 | |
2899 | TEST( |
2900 | WeakIntrusivePtrTest, |
2901 | givenPtr_whenDestructedButStillHasStrongPointers_thenDoesntReleaseResources) { |
2902 | bool resourcesReleased = false; |
2903 | bool wasDestructed = false; |
2904 | auto obj = |
2905 | make_weak_intrusive<DestructableMock>(&resourcesReleased, &wasDestructed); |
2906 | EXPECT_FALSE(resourcesReleased); |
2907 | EXPECT_FALSE(wasDestructed); |
2908 | obj.weak.reset(); |
2909 | EXPECT_FALSE(resourcesReleased); |
2910 | EXPECT_FALSE(wasDestructed); |
2911 | obj.ptr.reset(); |
2912 | EXPECT_TRUE(resourcesReleased); |
2913 | EXPECT_TRUE(wasDestructed); |
2914 | } |
2915 | |
2916 | TEST(WeakIntrusivePtrTest, givenPtr_whenDestructed_thenDestructsObject) { |
2917 | bool resourcesReleased = false; |
2918 | bool wasDestructed = false; |
2919 | { |
2920 | auto obj = |
2921 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
2922 | EXPECT_TRUE(resourcesReleased); |
2923 | EXPECT_FALSE(wasDestructed); |
2924 | } |
2925 | EXPECT_TRUE(resourcesReleased); |
2926 | EXPECT_TRUE(wasDestructed); |
2927 | } |
2928 | |
2929 | TEST( |
2930 | WeakIntrusivePtrTest, |
2931 | givenPtr_whenMoveConstructed_thenDestructsObjectAfterSecondDestructed) { |
2932 | bool resourcesReleased = false; |
2933 | bool wasDestructed = false; |
2934 | auto obj = |
2935 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
2936 | { |
2937 | auto obj2 = std::move(obj); |
2938 | EXPECT_TRUE(resourcesReleased); |
2939 | EXPECT_FALSE(wasDestructed); |
2940 | } |
2941 | EXPECT_TRUE(resourcesReleased); |
2942 | EXPECT_TRUE(wasDestructed); |
2943 | } |
2944 | |
2945 | TEST( |
2946 | WeakIntrusivePtrTest, |
2947 | givenPtr_whenMoveConstructedToBaseClass_thenDestructsObjectAfterSecondDestructed) { |
2948 | bool resourcesReleased = false; |
2949 | bool wasDestructed = false; |
2950 | auto obj = |
2951 | make_weak_only<ChildDestructableMock>(&resourcesReleased, &wasDestructed); |
2952 | { |
2953 | weak_intrusive_ptr<DestructableMock> obj2 = std::move(obj); |
2954 | EXPECT_TRUE(resourcesReleased); |
2955 | EXPECT_FALSE(wasDestructed); |
2956 | } |
2957 | EXPECT_TRUE(resourcesReleased); |
2958 | EXPECT_TRUE(wasDestructed); |
2959 | } |
2960 | |
2961 | TEST(WeakIntrusivePtrTest, givenPtr_whenMoveAssigned_thenDestructsOldObject) { |
2962 | bool dummy = false; |
2963 | bool resourcesReleased = false; |
2964 | bool wasDestructed = false; |
2965 | auto obj = make_weak_only<DestructableMock>(&dummy, &dummy); |
2966 | { |
2967 | auto obj2 = |
2968 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
2969 | EXPECT_TRUE(resourcesReleased); |
2970 | EXPECT_FALSE(wasDestructed); |
2971 | obj2 = std::move(obj); |
2972 | EXPECT_TRUE(resourcesReleased); |
2973 | EXPECT_TRUE(wasDestructed); |
2974 | } |
2975 | } |
2976 | |
2977 | TEST( |
2978 | WeakIntrusivePtrTest, |
2979 | givenPtr_whenMoveAssignedToBaseClass_thenDestructsOldObject) { |
2980 | bool dummy = false; |
2981 | bool resourcesReleased = false; |
2982 | bool wasDestructed = false; |
2983 | auto obj = make_weak_only<ChildDestructableMock>(&dummy, &dummy); |
2984 | { |
2985 | auto obj2 = |
2986 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
2987 | EXPECT_TRUE(resourcesReleased); |
2988 | EXPECT_FALSE(wasDestructed); |
2989 | obj2 = std::move(obj); |
2990 | EXPECT_TRUE(resourcesReleased); |
2991 | EXPECT_TRUE(wasDestructed); |
2992 | } |
2993 | } |
2994 | |
2995 | TEST( |
2996 | WeakIntrusivePtrTest, |
2997 | givenPtrWithCopy_whenMoveAssigned_thenDestructsOldObjectAfterCopyIsDestructed) { |
2998 | bool dummy = false; |
2999 | bool resourcesReleased = false; |
3000 | bool wasDestructed = false; |
3001 | auto obj = make_weak_only<DestructableMock>(&dummy, &dummy); |
3002 | { |
3003 | auto obj2 = |
3004 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3005 | { |
3006 | auto copy = obj2; |
3007 | EXPECT_TRUE(resourcesReleased); |
3008 | EXPECT_FALSE(wasDestructed); |
3009 | obj2 = std::move(obj); |
3010 | EXPECT_TRUE(resourcesReleased); |
3011 | EXPECT_FALSE(wasDestructed); |
3012 | } |
3013 | EXPECT_TRUE(resourcesReleased); |
3014 | EXPECT_TRUE(wasDestructed); |
3015 | } |
3016 | } |
3017 | |
3018 | TEST( |
3019 | WeakIntrusivePtrTest, |
3020 | givenPtrWithBaseClassCopy_whenMoveAssigned_thenDestructsOldObjectAfterCopyIsDestructed) { |
3021 | bool dummy = false; |
3022 | bool resourcesReleased = false; |
3023 | bool wasDestructed = false; |
3024 | auto obj = make_weak_only<ChildDestructableMock>(&dummy, &dummy); |
3025 | { |
3026 | auto obj2 = make_weak_only<ChildDestructableMock>( |
3027 | &resourcesReleased, &wasDestructed); |
3028 | { |
3029 | weak_intrusive_ptr<DestructableMock> copy = obj2; |
3030 | EXPECT_TRUE(resourcesReleased); |
3031 | EXPECT_FALSE(wasDestructed); |
3032 | obj2 = std::move(obj); |
3033 | EXPECT_TRUE(resourcesReleased); |
3034 | EXPECT_FALSE(wasDestructed); |
3035 | } |
3036 | EXPECT_TRUE(resourcesReleased); |
3037 | EXPECT_TRUE(wasDestructed); |
3038 | } |
3039 | } |
3040 | |
3041 | TEST( |
3042 | WeakIntrusivePtrTest, |
3043 | givenPtrWithCopy_whenMoveAssignedToBaseClass_thenDestructsOldObjectAfterCopyIsDestructed) { |
3044 | bool dummy = false; |
3045 | bool resourcesReleased = false; |
3046 | bool wasDestructed = false; |
3047 | auto obj = make_weak_only<ChildDestructableMock>(&dummy, &dummy); |
3048 | { |
3049 | auto obj2 = |
3050 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3051 | { |
3052 | weak_intrusive_ptr<DestructableMock> copy = obj2; |
3053 | EXPECT_TRUE(resourcesReleased); |
3054 | EXPECT_FALSE(wasDestructed); |
3055 | obj2 = std::move(obj); |
3056 | EXPECT_TRUE(resourcesReleased); |
3057 | EXPECT_FALSE(wasDestructed); |
3058 | } |
3059 | EXPECT_TRUE(resourcesReleased); |
3060 | EXPECT_TRUE(wasDestructed); |
3061 | } |
3062 | } |
3063 | |
3064 | TEST( |
3065 | WeakIntrusivePtrTest, |
3066 | givenPtr_whenMoveAssigned_thenDestructsObjectAfterSecondDestructed) { |
3067 | bool dummy = false; |
3068 | bool resourcesReleased = false; |
3069 | bool wasDestructed = false; |
3070 | auto obj = |
3071 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3072 | { |
3073 | auto obj2 = make_weak_only<DestructableMock>(&dummy, &dummy); |
3074 | obj2 = std::move(obj); |
3075 | EXPECT_TRUE(resourcesReleased); |
3076 | EXPECT_FALSE(wasDestructed); |
3077 | } |
3078 | EXPECT_TRUE(resourcesReleased); |
3079 | EXPECT_TRUE(wasDestructed); |
3080 | } |
3081 | |
3082 | TEST( |
3083 | WeakIntrusivePtrTest, |
3084 | givenPtr_whenMoveAssignedToBaseClass_thenDestructsObjectAfterSecondDestructed) { |
3085 | bool dummy = false; |
3086 | bool resourcesReleased = false; |
3087 | bool wasDestructed = false; |
3088 | auto obj = |
3089 | make_weak_only<ChildDestructableMock>(&resourcesReleased, &wasDestructed); |
3090 | { |
3091 | auto obj2 = make_weak_only<DestructableMock>(&dummy, &dummy); |
3092 | obj2 = std::move(obj); |
3093 | EXPECT_TRUE(resourcesReleased); |
3094 | EXPECT_FALSE(wasDestructed); |
3095 | } |
3096 | EXPECT_TRUE(resourcesReleased); |
3097 | EXPECT_TRUE(wasDestructed); |
3098 | } |
3099 | |
3100 | TEST( |
3101 | WeakIntrusivePtrTest, |
3102 | givenPtr_whenCopyConstructedAndDestructed_thenDestructsObjectAfterLastDestruction) { |
3103 | bool resourcesReleased = false; |
3104 | bool wasDestructed = false; |
3105 | { |
3106 | auto obj = |
3107 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3108 | { |
3109 | // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) |
3110 | weak_intrusive_ptr<DestructableMock> copy = obj; |
3111 | EXPECT_TRUE(resourcesReleased); |
3112 | EXPECT_FALSE(wasDestructed); |
3113 | } |
3114 | EXPECT_TRUE(resourcesReleased); |
3115 | EXPECT_FALSE(wasDestructed); |
3116 | } |
3117 | EXPECT_TRUE(resourcesReleased); |
3118 | EXPECT_TRUE(wasDestructed); |
3119 | } |
3120 | |
3121 | TEST( |
3122 | WeakIntrusivePtrTest, |
3123 | givenPtr_whenCopyConstructedToBaseClassAndDestructed_thenDestructsObjectAfterLastDestruction) { |
3124 | bool resourcesReleased = false; |
3125 | bool wasDestructed = false; |
3126 | { |
3127 | auto obj = make_weak_only<ChildDestructableMock>( |
3128 | &resourcesReleased, &wasDestructed); |
3129 | { |
3130 | weak_intrusive_ptr<DestructableMock> copy = obj; |
3131 | EXPECT_TRUE(resourcesReleased); |
3132 | EXPECT_FALSE(wasDestructed); |
3133 | } |
3134 | EXPECT_TRUE(resourcesReleased); |
3135 | EXPECT_FALSE(wasDestructed); |
3136 | } |
3137 | EXPECT_TRUE(resourcesReleased); |
3138 | EXPECT_TRUE(wasDestructed); |
3139 | } |
3140 | |
3141 | TEST( |
3142 | WeakIntrusivePtrTest, |
3143 | givenPtr_whenCopyConstructedAndOriginalDestructed_thenDestructsObjectAfterLastDestruction) { |
3144 | bool resourcesReleased = false; |
3145 | bool wasDestructed = false; |
3146 | { |
3147 | auto obj = |
3148 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3149 | weak_intrusive_ptr<DestructableMock> copy = obj; |
3150 | obj.reset(); |
3151 | EXPECT_TRUE(resourcesReleased); |
3152 | EXPECT_FALSE(wasDestructed); |
3153 | } |
3154 | EXPECT_TRUE(resourcesReleased); |
3155 | EXPECT_TRUE(wasDestructed); |
3156 | } |
3157 | |
3158 | TEST( |
3159 | WeakIntrusivePtrTest, |
3160 | givenPtr_whenCopyConstructedToBaseClassAndOriginalDestructed_thenDestructsObjectAfterLastDestruction) { |
3161 | bool resourcesReleased = false; |
3162 | bool wasDestructed = false; |
3163 | { |
3164 | auto obj = make_weak_only<ChildDestructableMock>( |
3165 | &resourcesReleased, &wasDestructed); |
3166 | weak_intrusive_ptr<DestructableMock> copy = obj; |
3167 | obj.reset(); |
3168 | EXPECT_TRUE(resourcesReleased); |
3169 | EXPECT_FALSE(wasDestructed); |
3170 | } |
3171 | EXPECT_TRUE(resourcesReleased); |
3172 | EXPECT_TRUE(wasDestructed); |
3173 | } |
3174 | |
3175 | TEST( |
3176 | WeakIntrusivePtrTest, |
3177 | givenPtr_whenCopyAssignedAndDestructed_thenDestructsObjectAfterLastDestruction) { |
3178 | bool resourcesReleased = false; |
3179 | bool wasDestructed = false; |
3180 | bool dummy = false; |
3181 | { |
3182 | auto obj = |
3183 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3184 | { |
3185 | weak_intrusive_ptr<DestructableMock> copy = |
3186 | make_weak_only<DestructableMock>(&dummy, &dummy); |
3187 | copy = obj; |
3188 | EXPECT_TRUE(resourcesReleased); |
3189 | EXPECT_FALSE(wasDestructed); |
3190 | } |
3191 | EXPECT_TRUE(resourcesReleased); |
3192 | EXPECT_FALSE(wasDestructed); |
3193 | } |
3194 | EXPECT_TRUE(resourcesReleased); |
3195 | EXPECT_TRUE(wasDestructed); |
3196 | } |
3197 | |
3198 | TEST( |
3199 | WeakIntrusivePtrTest, |
3200 | givenPtr_whenCopyAssignedToBaseClassAndDestructed_thenDestructsObjectAfterLastDestruction) { |
3201 | bool resourcesReleased = false; |
3202 | bool wasDestructed = false; |
3203 | bool dummy = false; |
3204 | { |
3205 | auto obj = make_weak_only<ChildDestructableMock>( |
3206 | &resourcesReleased, &wasDestructed); |
3207 | { |
3208 | weak_intrusive_ptr<DestructableMock> copy = |
3209 | make_weak_only<DestructableMock>(&dummy, &dummy); |
3210 | copy = obj; |
3211 | EXPECT_TRUE(resourcesReleased); |
3212 | EXPECT_FALSE(wasDestructed); |
3213 | } |
3214 | EXPECT_TRUE(resourcesReleased); |
3215 | EXPECT_FALSE(wasDestructed); |
3216 | } |
3217 | EXPECT_TRUE(resourcesReleased); |
3218 | EXPECT_TRUE(wasDestructed); |
3219 | } |
3220 | |
3221 | TEST( |
3222 | WeakIntrusivePtrTest, |
3223 | givenPtr_whenCopyAssignedAndOriginalDestructed_thenDestructsObjectAfterLastDestruction) { |
3224 | bool resourcesReleased = false; |
3225 | bool wasDestructed = false; |
3226 | bool dummy = false; |
3227 | { |
3228 | auto copy = make_weak_only<DestructableMock>(&dummy, &dummy); |
3229 | { |
3230 | auto obj = |
3231 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3232 | copy = obj; |
3233 | EXPECT_TRUE(resourcesReleased); |
3234 | EXPECT_FALSE(wasDestructed); |
3235 | } |
3236 | EXPECT_TRUE(resourcesReleased); |
3237 | EXPECT_FALSE(wasDestructed); |
3238 | } |
3239 | EXPECT_TRUE(resourcesReleased); |
3240 | EXPECT_TRUE(wasDestructed); |
3241 | } |
3242 | |
3243 | TEST( |
3244 | WeakIntrusivePtrTest, |
3245 | givenPtr_whenCopyAssignedToBaseClassAndOriginalDestructed_thenDestructsObjectAfterLastDestruction) { |
3246 | bool wasDestructed = false; |
3247 | bool resourcesReleased = false; |
3248 | bool dummy = false; |
3249 | { |
3250 | auto copy = make_weak_only<DestructableMock>(&dummy, &dummy); |
3251 | { |
3252 | auto obj = make_weak_only<ChildDestructableMock>( |
3253 | &resourcesReleased, &wasDestructed); |
3254 | copy = obj; |
3255 | EXPECT_TRUE(resourcesReleased); |
3256 | EXPECT_FALSE(wasDestructed); |
3257 | } |
3258 | EXPECT_TRUE(resourcesReleased); |
3259 | EXPECT_FALSE(wasDestructed); |
3260 | } |
3261 | EXPECT_TRUE(resourcesReleased); |
3262 | EXPECT_TRUE(wasDestructed); |
3263 | } |
3264 | |
3265 | TEST(WeakIntrusivePtrTest, givenPtr_whenCopyAssigned_thenDestructsOldObject) { |
3266 | bool dummy = false; |
3267 | bool resourcesReleased = false; |
3268 | bool wasDestructed = false; |
3269 | auto obj = make_weak_only<DestructableMock>(&dummy, &dummy); |
3270 | { |
3271 | auto obj2 = |
3272 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3273 | EXPECT_TRUE(resourcesReleased); |
3274 | EXPECT_FALSE(wasDestructed); |
3275 | obj2 = obj; |
3276 | EXPECT_TRUE(resourcesReleased); |
3277 | EXPECT_TRUE(wasDestructed); |
3278 | } |
3279 | } |
3280 | |
3281 | TEST( |
3282 | WeakIntrusivePtrTest, |
3283 | givenPtr_whenCopyAssignedToBaseClass_thenDestructsOldObject) { |
3284 | bool dummy = false; |
3285 | bool resourcesReleased = false; |
3286 | bool wasDestructed = false; |
3287 | auto obj = make_weak_only<ChildDestructableMock>(&dummy, &dummy); |
3288 | { |
3289 | auto obj2 = |
3290 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3291 | EXPECT_TRUE(resourcesReleased); |
3292 | EXPECT_FALSE(wasDestructed); |
3293 | obj2 = obj; |
3294 | EXPECT_TRUE(resourcesReleased); |
3295 | EXPECT_TRUE(wasDestructed); |
3296 | } |
3297 | } |
3298 | |
3299 | TEST( |
3300 | WeakIntrusivePtrTest, |
3301 | givenPtrWithCopy_whenCopyAssigned_thenDestructsOldObjectAfterCopyIsDestructed) { |
3302 | bool dummy = false; |
3303 | bool resourcesReleased = false; |
3304 | bool wasDestructed = false; |
3305 | auto obj = make_weak_only<DestructableMock>(&dummy, &dummy); |
3306 | { |
3307 | auto obj2 = |
3308 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3309 | { |
3310 | auto copy = obj2; |
3311 | EXPECT_TRUE(resourcesReleased); |
3312 | EXPECT_FALSE(wasDestructed); |
3313 | obj2 = obj; |
3314 | EXPECT_TRUE(resourcesReleased); |
3315 | EXPECT_FALSE(wasDestructed); |
3316 | } |
3317 | EXPECT_TRUE(resourcesReleased); |
3318 | EXPECT_TRUE(wasDestructed); |
3319 | } |
3320 | } |
3321 | |
3322 | TEST( |
3323 | WeakIntrusivePtrTest, |
3324 | givenPtrWithBaseClassCopy_whenCopyAssigned_thenDestructsOldObjectAfterCopyIsDestructed) { |
3325 | bool dummy = false; |
3326 | bool resourcesReleased = false; |
3327 | bool wasDestructed = false; |
3328 | auto obj = make_weak_only<ChildDestructableMock>(&dummy, &dummy); |
3329 | { |
3330 | auto obj2 = make_weak_only<ChildDestructableMock>( |
3331 | &resourcesReleased, &wasDestructed); |
3332 | { |
3333 | weak_intrusive_ptr<DestructableMock> copy = obj2; |
3334 | EXPECT_TRUE(resourcesReleased); |
3335 | EXPECT_FALSE(wasDestructed); |
3336 | obj2 = obj; |
3337 | EXPECT_TRUE(resourcesReleased); |
3338 | EXPECT_FALSE(wasDestructed); |
3339 | } |
3340 | EXPECT_TRUE(resourcesReleased); |
3341 | EXPECT_TRUE(wasDestructed); |
3342 | } |
3343 | } |
3344 | |
3345 | TEST( |
3346 | WeakIntrusivePtrTest, |
3347 | givenPtrWithCopy_whenCopyAssignedToBaseClass_thenDestructsOldObjectAfterCopyIsDestructed) { |
3348 | bool dummy = false; |
3349 | bool resourcesReleased = false; |
3350 | bool wasDestructed = false; |
3351 | auto obj = make_weak_only<ChildDestructableMock>(&dummy, &dummy); |
3352 | { |
3353 | auto obj2 = |
3354 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3355 | { |
3356 | weak_intrusive_ptr<DestructableMock> copy = obj2; |
3357 | EXPECT_TRUE(resourcesReleased); |
3358 | EXPECT_FALSE(wasDestructed); |
3359 | obj2 = obj; |
3360 | EXPECT_TRUE(resourcesReleased); |
3361 | EXPECT_FALSE(wasDestructed); |
3362 | } |
3363 | EXPECT_TRUE(resourcesReleased); |
3364 | EXPECT_TRUE(wasDestructed); |
3365 | } |
3366 | } |
3367 | |
3368 | TEST(WeakIntrusivePtrTest, givenPtr_whenCallingReset_thenDestructs) { |
3369 | bool resourcesReleased = false; |
3370 | bool wasDestructed = false; |
3371 | auto obj = |
3372 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3373 | EXPECT_TRUE(resourcesReleased); |
3374 | EXPECT_FALSE(wasDestructed); |
3375 | obj.reset(); |
3376 | EXPECT_TRUE(resourcesReleased); |
3377 | EXPECT_TRUE(wasDestructed); |
3378 | } |
3379 | |
3380 | TEST( |
3381 | WeakIntrusivePtrTest, |
3382 | givenPtrWithCopy_whenCallingReset_thenDestructsAfterCopyDestructed) { |
3383 | bool resourcesReleased = false; |
3384 | bool wasDestructed = false; |
3385 | auto obj = |
3386 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3387 | { |
3388 | auto copy = obj; |
3389 | obj.reset(); |
3390 | EXPECT_TRUE(resourcesReleased); |
3391 | EXPECT_FALSE(wasDestructed); |
3392 | copy.reset(); |
3393 | EXPECT_TRUE(resourcesReleased); |
3394 | EXPECT_TRUE(wasDestructed); |
3395 | } |
3396 | } |
3397 | |
3398 | TEST( |
3399 | WeakIntrusivePtrTest, |
3400 | givenPtrWithCopy_whenCallingResetOnCopy_thenDestructsAfterOriginalDestructed) { |
3401 | bool resourcesReleased = false; |
3402 | bool wasDestructed = false; |
3403 | auto obj = |
3404 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3405 | { |
3406 | auto copy = obj; |
3407 | copy.reset(); |
3408 | EXPECT_TRUE(resourcesReleased); |
3409 | EXPECT_FALSE(wasDestructed); |
3410 | obj.reset(); |
3411 | EXPECT_TRUE(resourcesReleased); |
3412 | EXPECT_TRUE(wasDestructed); |
3413 | } |
3414 | } |
3415 | |
3416 | TEST( |
3417 | WeakIntrusivePtrTest, |
3418 | givenPtrWithMoved_whenCallingReset_thenDestructsAfterMovedDestructed) { |
3419 | bool resourcesReleased = false; |
3420 | bool wasDestructed = false; |
3421 | auto obj = |
3422 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3423 | { |
3424 | auto moved = std::move(obj); |
3425 | // NOLINTNEXTLINE(bugprone-use-after-move) |
3426 | obj.reset(); |
3427 | EXPECT_TRUE(resourcesReleased); |
3428 | EXPECT_FALSE(wasDestructed); |
3429 | moved.reset(); |
3430 | EXPECT_TRUE(resourcesReleased); |
3431 | EXPECT_TRUE(wasDestructed); |
3432 | } |
3433 | } |
3434 | |
3435 | TEST( |
3436 | WeakIntrusivePtrTest, |
3437 | givenPtrWithMoved_whenCallingResetOnMoved_thenDestructsImmediately) { |
3438 | bool resourcesReleased = false; |
3439 | bool wasDestructed = false; |
3440 | auto obj = |
3441 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3442 | { |
3443 | auto moved = std::move(obj); |
3444 | moved.reset(); |
3445 | EXPECT_TRUE(resourcesReleased); |
3446 | EXPECT_TRUE(wasDestructed); |
3447 | } |
3448 | } |
3449 | |
3450 | TEST(WeakIntrusivePtrTest, givenPtr_whenReleasedAndReclaimed_thenDoesntCrash) { |
3451 | IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>(); |
3452 | SomeClass* ptr = obj.weak.release(); |
3453 | weak_intrusive_ptr<SomeClass> reclaimed = |
3454 | weak_intrusive_ptr<SomeClass>::reclaim(ptr); |
3455 | } |
3456 | |
3457 | TEST( |
3458 | WeakIntrusivePtrTest, |
3459 | givenWeakOnlyPtr_whenReleasedAndReclaimed_thenDoesntCrash) { |
3460 | weak_intrusive_ptr<SomeClass> obj = make_weak_only<SomeClass>(); |
3461 | SomeClass* ptr = obj.release(); |
3462 | weak_intrusive_ptr<SomeClass> reclaimed = |
3463 | weak_intrusive_ptr<SomeClass>::reclaim(ptr); |
3464 | } |
3465 | |
3466 | TEST( |
3467 | WeakIntrusivePtrTest, |
3468 | givenPtr_whenReleasedAndReclaimed_thenIsDestructedAtEnd) { |
3469 | bool resourcesReleased = false; |
3470 | bool wasDestructed = false; |
3471 | bool dummy = false; |
3472 | { |
3473 | IntrusiveAndWeak<DestructableMock> outer = |
3474 | make_weak_intrusive<DestructableMock>(&dummy, &dummy); |
3475 | { |
3476 | IntrusiveAndWeak<DestructableMock> inner = |
3477 | make_weak_intrusive<DestructableMock>( |
3478 | &resourcesReleased, &wasDestructed); |
3479 | EXPECT_FALSE(resourcesReleased); |
3480 | EXPECT_FALSE(wasDestructed); |
3481 | DestructableMock* ptr = inner.weak.release(); |
3482 | EXPECT_FALSE(resourcesReleased); |
3483 | EXPECT_FALSE(wasDestructed); |
3484 | outer.ptr = inner.ptr; |
3485 | outer.weak = weak_intrusive_ptr<DestructableMock>::reclaim(ptr); |
3486 | } |
3487 | // inner is destructed |
3488 | EXPECT_FALSE(resourcesReleased); |
3489 | EXPECT_FALSE(wasDestructed); |
3490 | outer.weak.reset(); |
3491 | EXPECT_FALSE(resourcesReleased); |
3492 | EXPECT_FALSE(wasDestructed); |
3493 | } |
3494 | // outer is destructed |
3495 | EXPECT_TRUE(resourcesReleased); |
3496 | EXPECT_TRUE(wasDestructed); |
3497 | } |
3498 | |
3499 | TEST( |
3500 | WeakIntrusivePtrTest, |
3501 | givenWeakOnlyPtr_whenReleasedAndReclaimed_thenIsDestructedAtEnd) { |
3502 | bool resourcesReleased = false; |
3503 | bool wasDestructed = false; |
3504 | { |
3505 | weak_intrusive_ptr<DestructableMock> outer = |
3506 | make_invalid_weak<DestructableMock>(); |
3507 | { |
3508 | weak_intrusive_ptr<DestructableMock> inner = |
3509 | make_weak_only<DestructableMock>(&resourcesReleased, &wasDestructed); |
3510 | EXPECT_TRUE(resourcesReleased); |
3511 | EXPECT_FALSE(wasDestructed); |
3512 | DestructableMock* ptr = inner.release(); |
3513 | EXPECT_TRUE(resourcesReleased); |
3514 | EXPECT_FALSE(wasDestructed); |
3515 | outer = weak_intrusive_ptr<DestructableMock>::reclaim(ptr); |
3516 | } |
3517 | // inner is destructed |
3518 | EXPECT_TRUE(resourcesReleased); |
3519 | EXPECT_FALSE(wasDestructed); |
3520 | } |
3521 | // outer is destructed |
3522 | EXPECT_TRUE(resourcesReleased); |
3523 | EXPECT_TRUE(wasDestructed); |
3524 | } |
3525 | |
3526 | TEST(WeakIntrusivePtrTest, givenStackObject_whenReclaimed_thenCrashes) { |
3527 | // This would cause very weird bugs on destruction. |
3528 | // Better to crash early on creation. |
3529 | SomeClass obj; |
3530 | weak_intrusive_ptr<SomeClass> ptr = make_invalid_weak<SomeClass>(); |
3531 | #ifdef NDEBUG |
3532 | // NOLINTNEXTLINE(cppcoreguidelines-avoid-goto,hicpp-avoid-goto) |
3533 | EXPECT_NO_THROW(ptr = weak_intrusive_ptr<SomeClass>::reclaim(&obj)); |
3534 | #else |
3535 | EXPECT_ANY_THROW(ptr = weak_intrusive_ptr<SomeClass>::reclaim(&obj)); |
3536 | #endif |
3537 | } |
3538 | |
3539 | TEST( |
3540 | WeakIntrusivePtrTest, |
3541 | givenObjectWithWeakReferenceToSelf_whenDestroyed_thenDoesNotCrash) { |
3542 | auto p = make_intrusive<WeakReferenceToSelf>(); |
3543 | p->ptr = weak_intrusive_ptr<intrusive_ptr_target>( |
3544 | intrusive_ptr<intrusive_ptr_target>(p)); |
3545 | } |
3546 | |