1 #include <c10/util/intrusive_ptr.h>
2
3 #include <gtest/gtest.h>
4 #include <map>
5 #include <set>
6 #include <unordered_map>
7 #include <unordered_set>
8
9 using c10::intrusive_ptr;
10 using c10::intrusive_ptr_target;
11 using c10::make_intrusive;
12 using c10::weak_intrusive_ptr;
13
14 #ifndef _MSC_VER
15 #pragma GCC diagnostic ignored "-Wpragmas"
16 #pragma GCC diagnostic ignored "-Wunknown-warning-option"
17 #pragma GCC diagnostic ignored "-Wself-move"
18 #pragma GCC diagnostic ignored "-Wfree-nonheap-object"
19 #endif
20
21 #ifdef __clang__
22 #pragma clang diagnostic ignored "-Wself-assign-overloaded"
23 #endif
24 // NOLINTBEGIN(clang-analyzer-cplusplus*)
25 namespace {
26 class SomeClass0Parameters : public intrusive_ptr_target {};
27 class SomeClass1Parameter : public intrusive_ptr_target {
28 public:
SomeClass1Parameter(int param_)29 SomeClass1Parameter(int param_) : param(param_) {}
30 int param;
31 };
32 class SomeClass2Parameters : public intrusive_ptr_target {
33 public:
SomeClass2Parameters(int param1_,int param2_)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 {
SomeBaseClass__anon131a80fc0111::SomeBaseClass41 SomeBaseClass(int v_) : v(v_) {}
42 int v;
43 };
44 struct SomeChildClass : SomeBaseClass {
SomeChildClass__anon131a80fc0111::SomeChildClass45 SomeChildClass(int v) : SomeBaseClass(v) {}
46 };
47
48 class DestructableMock : public intrusive_ptr_target {
49 public:
DestructableMock(bool * resourcesReleased,bool * wasDestructed)50 DestructableMock(bool* resourcesReleased, bool* wasDestructed)
51 : resourcesReleased_(resourcesReleased), wasDestructed_(wasDestructed) {}
52
~DestructableMock()53 ~DestructableMock() override {
54 *resourcesReleased_ = true;
55 *wasDestructed_ = true;
56 }
57
release_resources()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:
ChildDestructableMock(bool * resourcesReleased,bool * wasDestructed)69 ChildDestructableMock(bool* resourcesReleased, bool* wasDestructed)
70 : DestructableMock(resourcesReleased, wasDestructed) {}
71 };
72 class NullType1 final {
73 static SomeClass singleton_;
74
75 public:
singleton()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:
singleton()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_v<SomeClass, intrusive_ptr<SomeClass>::element_type>,
95 "intrusive_ptr<T>::element_type is wrong");
96
TEST(MakeIntrusiveTest,ClassWith0Parameters)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
TEST(MakeIntrusiveTest,ClassWith1Parameter)104 TEST(MakeIntrusiveTest, ClassWith1Parameter) {
105 intrusive_ptr<SomeClass1Parameter> var =
106 make_intrusive<SomeClass1Parameter>(5);
107 EXPECT_EQ(5, var->param);
108 }
109
TEST(MakeIntrusiveTest,ClassWith2Parameters)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
TEST(MakeIntrusiveTest,TypeIsAutoDeductible)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
TEST(MakeIntrusiveTest,CanAssignToBaseClassPtr)123 TEST(MakeIntrusiveTest, CanAssignToBaseClassPtr) {
124 intrusive_ptr<SomeBaseClass> var = make_intrusive<SomeChildClass>(3);
125 EXPECT_EQ(3, var->v);
126 }
127
TEST(IntrusivePtrTargetTest,whenAllocatedOnStack_thenDoesntCrash)128 TEST(IntrusivePtrTargetTest, whenAllocatedOnStack_thenDoesntCrash) {
129 SomeClass myClass;
130 }
131
TEST(IntrusivePtrTest,givenValidPtr_whenCallingGet_thenReturnsObject)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
TEST(IntrusivePtrTest,givenValidPtr_whenCallingConstGet_thenReturnsObject)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
TEST(IntrusivePtrTest,givenInvalidPtr_whenCallingGet_thenReturnsNullptr)144 TEST(IntrusivePtrTest, givenInvalidPtr_whenCallingGet_thenReturnsNullptr) {
145 intrusive_ptr<SomeClass1Parameter> obj;
146 EXPECT_EQ(nullptr, obj.get());
147 }
148
TEST(IntrusivePtrTest,givenNullptr_whenCallingGet_thenReturnsNullptr)149 TEST(IntrusivePtrTest, givenNullptr_whenCallingGet_thenReturnsNullptr) {
150 intrusive_ptr<SomeClass1Parameter> obj(nullptr);
151 EXPECT_EQ(nullptr, obj.get());
152 }
153
TEST(IntrusivePtrTest,givenValidPtr_whenDereferencing_thenReturnsObject)154 TEST(IntrusivePtrTest, givenValidPtr_whenDereferencing_thenReturnsObject) {
155 intrusive_ptr<SomeClass1Parameter> obj =
156 make_intrusive<SomeClass1Parameter>(5);
157 EXPECT_EQ(5, (*obj).param);
158 }
159
TEST(IntrusivePtrTest,givenValidPtr_whenConstDereferencing_thenReturnsObject)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
TEST(IntrusivePtrTest,givenValidPtr_whenArrowDereferencing_thenReturnsObject)166 TEST(IntrusivePtrTest, givenValidPtr_whenArrowDereferencing_thenReturnsObject) {
167 intrusive_ptr<SomeClass1Parameter> obj =
168 make_intrusive<SomeClass1Parameter>(3);
169 EXPECT_EQ(3, obj->param);
170 }
171
TEST(IntrusivePtrTest,givenValidPtr_whenConstArrowDereferencing_thenReturnsObject)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
TEST(IntrusivePtrTest,givenValidPtr_whenMoveAssigning_thenPointsToSameObject)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
TEST(IntrusivePtrTest,givenValidPtr_whenMoveAssigning_thenOldInstanceInvalid)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
TEST(IntrusivePtrTest,givenValidPtr_whenMoveAssigningToSelf_thenPointsToSameObject)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
TEST(IntrusivePtrTest,givenValidPtr_whenMoveAssigningToSelf_thenStaysValid)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
TEST(IntrusivePtrTest,givenInvalidPtr_whenMoveAssigningToSelf_thenStaysInvalid)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
TEST(IntrusivePtrTest,givenInvalidPtr_whenMoveAssigning_thenNewInstanceIsValid)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
TEST(IntrusivePtrTest,givenInvalidPtr_whenMoveAssigning_thenPointsToSameObject)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
TEST(IntrusivePtrTest,givenValidPtr_whenMoveAssigningFromInvalidPtr_thenNewInstanceIsInvalid)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
TEST(IntrusivePtrTest,givenValidPtr_whenMoveAssigningToBaseClass_thenPointsToSameObject)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
TEST(IntrusivePtrTest,givenValidPtr_whenMoveAssigningToBaseClass_thenOldInstanceInvalid)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
TEST(IntrusivePtrTest,givenInvalidPtr_whenMoveAssigningToBaseClass_thenNewInstanceIsValid)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
TEST(IntrusivePtrTest,givenInvalidPtr_whenMoveAssigningToBaseClass_thenPointsToSameObject)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
TEST(IntrusivePtrTest,givenInvalidPtr_whenMoveAssigningInvalidPtrToBaseClass_thenNewInstanceIsValid)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
TEST(IntrusivePtrTest,givenNullPtr_whenMoveAssigningToDifferentNullptr_thenHasNewNullptr)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
TEST(IntrusivePtrTest,givenValidPtr_whenCopyAssigning_thenPointsToSameObject)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
TEST(IntrusivePtrTest,givenValidPtr_whenCopyAssigning_thenOldInstanceValid)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
TEST(IntrusivePtrTest,givenValidPtr_whenCopyAssigningToSelf_thenPointsToSameObject)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
TEST(IntrusivePtrTest,givenValidPtr_whenCopyAssigningToSelf_thenStaysValid)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
TEST(IntrusivePtrTest,givenInvalidPtr_whenCopyAssigningToSelf_thenStaysInvalid)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
TEST(IntrusivePtrTest,givenInvalidPtr_whenCopyAssigning_thenNewInstanceIsValid)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
TEST(IntrusivePtrTest,givenValidPtr_whenCopyAssigningToBaseClass_thenPointsToSameObject)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
TEST(IntrusivePtrTest,givenValidPtr_whenCopyAssigningToBaseClass_thenOldInstanceInvalid)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
TEST(IntrusivePtrTest,givenInvalidPtr_whenCopyAssigningToBaseClass_thenNewInstanceIsValid)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
TEST(IntrusivePtrTest,givenInvalidPtr_whenCopyAssigningToBaseClass_thenPointsToSameObject)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
TEST(IntrusivePtrTest,givenPtr_whenCopyAssigningInvalidPtrToBaseClass_thenNewInstanceIsInvalid)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
TEST(IntrusivePtrTest,givenNullPtr_whenCopyAssigningToDifferentNullptr_thenHasNewNullptr)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
TEST(IntrusivePtrTest,givenPtr_whenMoveConstructing_thenPointsToSameObject)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
TEST(IntrusivePtrTest,givenPtr_whenMoveConstructing_thenOldInstanceInvalid)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
TEST(IntrusivePtrTest,givenPtr_whenMoveConstructing_thenNewInstanceValid)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
TEST(IntrusivePtrTest,givenPtr_whenMoveConstructingFromInvalidPtr_thenNewInstanceInvalid)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
TEST(IntrusivePtrTest,givenPtr_whenMoveConstructingToBaseClass_thenPointsToSameObject)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
TEST(IntrusivePtrTest,givenPtr_whenMoveConstructingToBaseClass_thenOldInstanceInvalid)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
TEST(IntrusivePtrTest,givenPtr_whenMoveConstructingToBaseClass_thenNewInstanceValid)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
TEST(IntrusivePtrTest,givenPtr_whenMoveConstructingToBaseClassFromInvalidPtr_thenNewInstanceInvalid)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
TEST(IntrusivePtrTest,givenNullPtr_whenMoveConstructingToDifferentNullptr_thenHasNewNullptr)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
TEST(IntrusivePtrTest,givenPtr_whenCopyConstructing_thenPointsToSameObject)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
TEST(IntrusivePtrTest,givenPtr_whenCopyConstructing_thenOldInstanceValid)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
TEST(IntrusivePtrTest,givenPtr_whenCopyConstructing_thenNewInstanceValid)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
TEST(IntrusivePtrTest,givenPtr_whenCopyConstructingFromInvalidPtr_thenNewInstanceInvalid)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
TEST(IntrusivePtrTest,givenPtr_whenCopyConstructingToBaseClass_thenPointsToSameObject)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
TEST(IntrusivePtrTest,givenPtr_whenCopyConstructingToBaseClass_thenOldInstanceInvalid)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
TEST(IntrusivePtrTest,givenPtr_whenCopyConstructingToBaseClass_thenNewInstanceInvalid)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
TEST(IntrusivePtrTest,givenPtr_whenCopyConstructingToBaseClassFromInvalidPtr_thenNewInstanceInvalid)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
TEST(IntrusivePtrTest,givenNullPtr_whenCopyConstructingToDifferentNullptr_thenHasNewNullptr)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
TEST(IntrusivePtrTest,SwapFunction)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
TEST(IntrusivePtrTest,SwapMethod)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
TEST(IntrusivePtrTest,SwapFunctionFromInvalid)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
TEST(IntrusivePtrTest,SwapMethodFromInvalid)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
TEST(IntrusivePtrTest,SwapFunctionWithInvalid)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
TEST(IntrusivePtrTest,SwapMethodWithInvalid)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
TEST(IntrusivePtrTest,SwapFunctionInvalidWithInvalid)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
TEST(IntrusivePtrTest,SwapMethodInvalidWithInvalid)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
TEST(IntrusivePtrTest,CanBePutInContainer)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
TEST(IntrusivePtrTest,CanBePutInSet)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
TEST(IntrusivePtrTest,CanBePutInUnorderedSet)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
TEST(IntrusivePtrTest,CanBePutInMap)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
TEST(IntrusivePtrTest,CanBePutInUnorderedMap)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
TEST(IntrusivePtrTest,Equality_AfterCopyConstructor)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
TEST(IntrusivePtrTest,Equality_AfterCopyAssignment)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
TEST(IntrusivePtrTest,Equality_Nullptr)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
TEST(IntrusivePtrTest,Inequality)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
TEST(IntrusivePtrTest,Inequality_NullptrLeft)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
TEST(IntrusivePtrTest,Inequality_NullptrRight)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
TEST(IntrusivePtrTest,HashIsDifferent)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
TEST(IntrusivePtrTest,HashIsDifferent_ValidAndInvalid)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
TEST(IntrusivePtrTest,HashIsSame_AfterCopyConstructor)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
TEST(IntrusivePtrTest,HashIsSame_AfterCopyAssignment)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
TEST(IntrusivePtrTest,HashIsSame_BothNullptr)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
TEST(IntrusivePtrTest,OneIsLess)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
TEST(IntrusivePtrTest,NullptrIsLess1)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
TEST(IntrusivePtrTest,NullptrIsLess2)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
TEST(IntrusivePtrTest,NullptrIsNotLessThanNullptr)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
TEST(IntrusivePtrTest,givenPtr_whenCallingReset_thenIsInvalid)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
TEST(IntrusivePtrTest,givenPtr_whenCallingReset_thenHoldsNullptr)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
TEST(IntrusivePtrTest,givenPtr_whenDestructed_thenDestructsObject)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
TEST(IntrusivePtrTest,givenPtr_whenMoveConstructed_thenDestructsObjectAfterSecondDestructed)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
TEST(IntrusivePtrTest,givenPtr_whenMoveConstructedToBaseClass_thenDestructsObjectAfterSecondDestructed)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
TEST(IntrusivePtrTest,givenPtr_whenMoveAssigned_thenDestructsOldObject)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
TEST(IntrusivePtrTest,givenPtr_whenMoveAssignedToBaseClass_thenDestructsOldObject)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
TEST(IntrusivePtrTest,givenPtrWithCopy_whenMoveAssigned_thenDestructsOldObjectAfterCopyIsDestructed)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
TEST(IntrusivePtrTest,givenPtrWithBaseClassCopy_whenMoveAssigned_thenDestructsOldObjectAfterCopyIsDestructed)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
TEST(IntrusivePtrTest,givenPtrWithCopy_whenMoveAssignedToBaseClass_thenDestructsOldObjectAfterCopyIsDestructed)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
TEST(IntrusivePtrTest,givenPtr_whenMoveAssigned_thenDestructsObjectAfterSecondDestructed)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
TEST(IntrusivePtrTest,givenPtr_whenMoveAssignedToBaseClass_thenDestructsObjectAfterSecondDestructed)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
TEST(IntrusivePtrTest,givenPtr_whenCopyConstructedAndDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(IntrusivePtrTest,givenPtr_whenCopyConstructedToBaseClassAndDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(IntrusivePtrTest,givenPtr_whenCopyConstructedAndOriginalDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(IntrusivePtrTest,givenPtr_whenCopyConstructedToBaseClassAndOriginalDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(IntrusivePtrTest,givenPtr_whenCopyAssignedAndDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(IntrusivePtrTest,givenPtr_whenCopyAssignedToBaseClassAndDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(IntrusivePtrTest,givenPtr_whenCopyAssignedAndOriginalDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(IntrusivePtrTest,givenPtr_whenCopyAssignedToBaseClassAndOriginalDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(IntrusivePtrTest,givenPtr_whenCopyAssigned_thenDestructsOldObject)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
TEST(IntrusivePtrTest,givenPtr_whenCopyAssignedToBaseClass_thenDestructsOldObject)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
TEST(IntrusivePtrTest,givenPtrWithCopy_whenCopyAssigned_thenDestructsOldObjectAfterCopyIsDestructed)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
TEST(IntrusivePtrTest,givenPtrWithBaseClassCopy_whenCopyAssigned_thenDestructsOldObjectAfterCopyIsDestructed)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
TEST(IntrusivePtrTest,givenPtrWithCopy_whenCopyAssignedToBaseClass_thenDestructsOldObjectAfterCopyIsDestructed)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
TEST(IntrusivePtrTest,givenPtr_whenCallingReset_thenDestructs)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
TEST(IntrusivePtrTest,givenPtrWithCopy_whenCallingReset_thenDestructsAfterCopyDestructed)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
TEST(IntrusivePtrTest,givenPtrWithCopy_whenCallingResetOnCopy_thenDestructsAfterOriginalDestructed)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
TEST(IntrusivePtrTest,givenPtrWithMoved_whenCallingReset_thenDestructsAfterMovedDestructed)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
TEST(IntrusivePtrTest,givenPtrWithMoved_whenCallingResetOnMoved_thenDestructsImmediately)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
TEST(IntrusivePtrTest,AllowsMoveConstructingToConst)1364 TEST(IntrusivePtrTest, AllowsMoveConstructingToConst) {
1365 intrusive_ptr<SomeClass> a = make_intrusive<SomeClass>();
1366 intrusive_ptr<const SomeClass> b = std::move(a);
1367 }
1368
TEST(IntrusivePtrTest,AllowsCopyConstructingToConst)1369 TEST(IntrusivePtrTest, AllowsCopyConstructingToConst) {
1370 intrusive_ptr<SomeClass> a = make_intrusive<SomeClass>();
1371 intrusive_ptr<const SomeClass> b = a;
1372 }
1373
TEST(IntrusivePtrTest,AllowsMoveAssigningToConst)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
TEST(IntrusivePtrTest,AllowsCopyAssigningToConst)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
TEST(IntrusivePtrTest,givenNewPtr_thenHasUseCount1)1386 TEST(IntrusivePtrTest, givenNewPtr_thenHasUseCount1) {
1387 intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>();
1388 EXPECT_EQ(1, obj.use_count());
1389 }
1390
TEST(IntrusivePtrTest,givenNewPtr_thenIsUnique)1391 TEST(IntrusivePtrTest, givenNewPtr_thenIsUnique) {
1392 intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>();
1393 EXPECT_TRUE(obj.unique());
1394 }
1395
TEST(IntrusivePtrTest,givenEmptyPtr_thenHasUseCount0)1396 TEST(IntrusivePtrTest, givenEmptyPtr_thenHasUseCount0) {
1397 intrusive_ptr<SomeClass> obj;
1398 EXPECT_EQ(0, obj.use_count());
1399 }
1400
TEST(IntrusivePtrTest,givenEmptyPtr_thenIsNotUnique)1401 TEST(IntrusivePtrTest, givenEmptyPtr_thenIsNotUnique) {
1402 intrusive_ptr<SomeClass> obj;
1403 EXPECT_FALSE(obj.unique());
1404 }
1405
TEST(IntrusivePtrTest,givenResetPtr_thenHasUseCount0)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
TEST(IntrusivePtrTest,givenResetPtr_thenIsNotUnique)1412 TEST(IntrusivePtrTest, givenResetPtr_thenIsNotUnique) {
1413 intrusive_ptr<SomeClass> obj = make_intrusive<SomeClass>();
1414 obj.reset();
1415 EXPECT_FALSE(obj.unique());
1416 }
1417
TEST(IntrusivePtrTest,givenMoveConstructedPtr_thenHasUseCount1)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
TEST(IntrusivePtrTest,givenMoveConstructedPtr_thenIsUnique)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
TEST(IntrusivePtrTest,givenMoveConstructedPtr_thenOldHasUseCount0)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
TEST(IntrusivePtrTest,givenMoveConstructedPtr_thenOldIsNotUnique)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
TEST(IntrusivePtrTest,givenMoveAssignedPtr_thenHasUseCount1)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
TEST(IntrusivePtrTest,givenMoveAssignedPtr_thenIsUnique)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
TEST(IntrusivePtrTest,givenMoveAssignedPtr_thenOldHasUseCount0)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
TEST(IntrusivePtrTest,givenMoveAssignedPtr_thenOldIsNotUnique)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
TEST(IntrusivePtrTest,givenCopyConstructedPtr_thenHasUseCount2)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
TEST(IntrusivePtrTest,givenCopyConstructedPtr_thenIsNotUnique)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
TEST(IntrusivePtrTest,givenCopyConstructedPtr_thenOldHasUseCount2)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
TEST(IntrusivePtrTest,givenCopyConstructedPtr_thenOldIsNotUnique)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
TEST(IntrusivePtrTest,givenCopyConstructedPtr_whenDestructingCopy_thenHasUseCount1)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
TEST(IntrusivePtrTest,givenCopyConstructedPtr_whenDestructingCopy_thenIsUnique)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
TEST(IntrusivePtrTest,givenCopyConstructedPtr_whenReassigningCopy_thenHasUseCount1)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
TEST(IntrusivePtrTest,givenCopyConstructedPtr_whenReassigningCopy_thenIsUnique)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
TEST(IntrusivePtrTest,givenCopyAssignedPtr_thenHasUseCount2)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
TEST(IntrusivePtrTest,givenCopyAssignedPtr_thenIsNotUnique)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
TEST(IntrusivePtrTest,givenCopyAssignedPtr_whenDestructingCopy_thenHasUseCount1)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
TEST(IntrusivePtrTest,givenCopyAssignedPtr_whenDestructingCopy_thenIsUnique)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
TEST(IntrusivePtrTest,givenCopyAssignedPtr_whenReassigningCopy_thenHasUseCount1)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
TEST(IntrusivePtrTest,givenCopyAssignedPtr_whenReassigningCopy_thenIsUnique)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
TEST(IntrusivePtrTest,givenPtr_whenReleasedAndReclaimed_thenDoesntCrash)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
TEST(IntrusivePtrTest,givenPtr_whenReleasedAndReclaimed_thenIsDestructedAtEnd)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
TEST(IntrusivePtrTest,givenPtr_whenNonOwningReclaimed_thenDoesntCrash)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
TEST(IntrusivePtrTest,givenPtr_whenNonOwningReclaimed_thenIsDestructedAtEnd)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 {
IntrusiveAndWeak__anon131a80fc0211::IntrusiveAndWeak1686 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>
make_weak_intrusive(Args &&...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>
make_weak_only(Args &&...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>>
make_invalid_weak()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 {
release_resources__anon131a80fc0211::WeakReferenceToSelf1708 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_v<SomeClass, weak_intrusive_ptr<SomeClass>::element_type>,
1719 "weak_intrusive_ptr<T>::element_type is wrong");
1720
TEST(WeakIntrusivePtrTest,givenPtr_whenCreatingAndDestructing_thenDoesntCrash)1721 TEST(
1722 WeakIntrusivePtrTest,
1723 givenPtr_whenCreatingAndDestructing_thenDoesntCrash) {
1724 IntrusiveAndWeak<SomeClass> var = make_weak_intrusive<SomeClass>();
1725 }
1726
TEST(WeakIntrusivePtrTest,givenPtr_whenLocking_thenReturnsCorrectObject)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
TEST(WeakIntrusivePtrTest,expiredPtr_whenLocking_thenReturnsNullType)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
TEST(WeakIntrusivePtrTest,weakNullPtr_locking)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
TEST(WeakIntrusivePtrTest,givenValidPtr_whenMoveAssigning_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenValidPtr_whenMoveAssigning_thenOldInstanceInvalid)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
TEST(WeakIntrusivePtrTest,vector_insert_weak_intrusive)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 }
TEST(WeakIntrusivePtrTest,givenInvalidPtr_whenMoveAssigning_thenNewInstanceIsValid)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
TEST(WeakIntrusivePtrTest,givenValidPtr_whenMoveAssigningToSelf_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenValidPtr_whenMoveAssigningToSelf_thenStaysValid)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
TEST(WeakIntrusivePtrTest,givenInvalidPtr_whenMoveAssigning_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenInvalidPtr_whenMoveAssigningToSelf_thenStaysInvalid)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
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_whenMoveAssigning_thenNewInstanceIsValid)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
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_whenMoveAssigning_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_whenMoveAssigningToSelf_thenStaysInvalid)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
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_whenMoveAssigningToSelf_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenValidPtr_whenMoveAssigningFromInvalidPtr_thenNewInstanceIsInvalid)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
TEST(WeakIntrusivePtrTest,givenValidPtr_whenMoveAssigningFromWeakOnlyPtr_thenNewInstanceIsInvalid)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
TEST(WeakIntrusivePtrTest,givenValidPtr_whenMoveAssigningToBaseClass_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenValidPtr_whenMoveAssigningToBaseClass_thenOldInstanceInvalid)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
TEST(WeakIntrusivePtrTest,givenInvalidPtr_whenMoveAssigningToBaseClass_thenNewInstanceIsValid)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
TEST(WeakIntrusivePtrTest,givenInvalidPtr_whenMoveAssigningToBaseClass_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenInvalidPtr_whenMoveAssigningInvalidPtrToBaseClass_thenNewInstanceIsValid)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
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_whenMoveAssigningToBaseClass_thenNewInstanceIsValid)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
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_whenMoveAssigningToBaseClass_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_whenMoveAssigningInvalidPtrToBaseClass_thenNewInstanceIsValid)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
TEST(WeakIntrusivePtrTest,givenNullPtr_whenMoveAssigningToDifferentNullptr_thenHasNewNullptr)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
TEST(WeakIntrusivePtrTest,givenValidPtr_whenCopyAssigning_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenValidPtr_whenCopyAssigning_thenOldInstanceValid)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
TEST(WeakIntrusivePtrTest,givenValidPtr_whenCopyAssigningToSelf_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenValidPtr_whenCopyAssigningToSelf_thenStaysValid)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
TEST(WeakIntrusivePtrTest,givenInvalidPtr_whenCopyAssigning_thenNewInstanceIsValid)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
TEST(WeakIntrusivePtrTest,givenInvalidPtr_whenCopyAssigningToSelf_thenStaysInvalid)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
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_whenCopyAssigning_thenNewInstanceIsValid)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
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_whenCopyAssigning_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_whenCopyAssigningToSelf_thenStaysInvalid)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
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_whenCopyAssigningToSelf_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenValidPtr_whenCopyAssigningToBaseClass_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenValidPtr_whenCopyAssigningToBaseClass_thenOldInstanceInvalid)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
TEST(WeakIntrusivePtrTest,givenInvalidPtr_whenCopyAssigningToBaseClass_thenNewInstanceIsValid)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
TEST(WeakIntrusivePtrTest,givenInvalidPtr_whenCopyAssigningToBaseClass_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyAssigningInvalidPtrToBaseClass_thenNewInstanceIsInvalid)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
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_whenCopyAssigningToBaseClass_thenNewInstanceIsValid)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
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_whenCopyAssigningToBaseClass_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyAssigningWeakOnlyPtrToBaseClass_thenNewInstanceIsValid)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
TEST(WeakIntrusivePtrTest,givenNullPtr_whenCopyAssigningToDifferentNullptr_thenHasNewNullptr)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveConstructing_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveConstructing_thenOldInstanceInvalid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveConstructing_thenNewInstanceValid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveConstructingFromInvalidPtr_thenNewInstanceInvalid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveConstructingFromWeakOnlyPtr_thenNewInstanceInvalid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveConstructingToBaseClass_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveConstructingToBaseClass_thenOldInstanceInvalid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveConstructingToBaseClass_thenNewInstanceValid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveConstructingToBaseClassFromInvalidPtr_thenNewInstanceInvalid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveConstructingToBaseClassFromWeakOnlyPtr_thenNewInstanceInvalid)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
TEST(WeakIntrusivePtrTest,givenNullPtr_whenMoveConstructingToDifferentNullptr_thenHasNewNullptr)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyConstructing_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyConstructing_thenOldInstanceValid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyConstructing_thenNewInstanceValid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyConstructingFromInvalidPtr_thenNewInstanceInvalid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyConstructingFromWeakOnlyPtr_thenNewInstanceInvalid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyConstructingToBaseClass_thenPointsToSameObject)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyConstructingToBaseClass_thenOldInstanceInvalid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyConstructingToBaseClass_thenNewInstanceInvalid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyConstructingToBaseClassFromInvalidPtr_thenNewInstanceInvalid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyConstructingToBaseClassFromWeakOnlyPtr_thenNewInstanceInvalid)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
TEST(WeakIntrusivePtrTest,givenNullPtr_whenCopyConstructingToDifferentNullptr_thenHasNewNullptr)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
TEST(WeakIntrusivePtrTest,SwapFunction)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
TEST(WeakIntrusivePtrTest,SwapMethod)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
TEST(WeakIntrusivePtrTest,SwapFunctionFromInvalid)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
TEST(WeakIntrusivePtrTest,SwapMethodFromInvalid)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
TEST(WeakIntrusivePtrTest,SwapFunctionWithInvalid)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
TEST(WeakIntrusivePtrTest,SwapMethodWithInvalid)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
TEST(WeakIntrusivePtrTest,SwapFunctionInvalidWithInvalid)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
TEST(WeakIntrusivePtrTest,SwapMethodInvalidWithInvalid)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
TEST(WeakIntrusivePtrTest,SwapFunctionFromWeakOnlyPtr)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
TEST(WeakIntrusivePtrTest,SwapMethodFromWeakOnlyPtr)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
TEST(WeakIntrusivePtrTest,SwapFunctionWithWeakOnlyPtr)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
TEST(WeakIntrusivePtrTest,SwapMethodWithWeakOnlyPtr)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
TEST(WeakIntrusivePtrTest,SwapFunctionWeakOnlyPtrWithWeakOnlyPtr)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
TEST(WeakIntrusivePtrTest,SwapMethodWeakOnlyPtrWithWeakOnlyPtr)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
TEST(WeakIntrusivePtrTest,CanBePutInContainer)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
TEST(WeakIntrusivePtrTest,CanBePutInSet)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
TEST(WeakIntrusivePtrTest,CanBePutInUnorderedSet)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
TEST(WeakIntrusivePtrTest,CanBePutInMap)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
TEST(WeakIntrusivePtrTest,CanBePutInUnorderedMap)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
TEST(WeakIntrusivePtrTest,Equality_AfterCopyConstructor)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
TEST(WeakIntrusivePtrTest,Equality_AfterCopyAssignment)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
TEST(WeakIntrusivePtrTest,Equality_AfterCopyAssignment_WeakOnly)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
TEST(WeakIntrusivePtrTest,Equality_Invalid)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
TEST(WeakIntrusivePtrTest,Inequality)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
TEST(WeakIntrusivePtrTest,Inequality_InvalidLeft)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
TEST(WeakIntrusivePtrTest,Inequality_InvalidRight)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
TEST(WeakIntrusivePtrTest,Inequality_WeakOnly)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
TEST(WeakIntrusivePtrTest,HashIsDifferent)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
TEST(WeakIntrusivePtrTest,HashIsDifferent_ValidAndInvalid)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
TEST(WeakIntrusivePtrTest,HashIsDifferent_ValidAndWeakOnly)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
TEST(WeakIntrusivePtrTest,HashIsDifferent_WeakOnlyAndWeakOnly)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
TEST(WeakIntrusivePtrTest,HashIsSame_AfterCopyConstructor)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
TEST(WeakIntrusivePtrTest,HashIsSame_AfterCopyConstructor_WeakOnly)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
TEST(WeakIntrusivePtrTest,HashIsSame_AfterCopyAssignment)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
TEST(WeakIntrusivePtrTest,HashIsSame_AfterCopyAssignment_WeakOnly)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
TEST(WeakIntrusivePtrTest,HashIsSame_BothInvalid)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
TEST(WeakIntrusivePtrTest,OneIsLess)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
TEST(WeakIntrusivePtrTest,InvalidIsLess1)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
TEST(WeakIntrusivePtrTest,InvalidIsLess2)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
TEST(WeakIntrusivePtrTest,InvalidIsNotLessThanInvalid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCallingResetOnWeakPtr_thenIsInvalid)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCallingResetOnStrongPtr_thenIsInvalid)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
TEST(WeakIntrusivePtrTest,AllowsMoveConstructingToConst)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
TEST(WeakIntrusivePtrTest,AllowsCopyConstructingToConst)2735 TEST(WeakIntrusivePtrTest, AllowsCopyConstructingToConst) {
2736 IntrusiveAndWeak<SomeClass> a = make_weak_intrusive<SomeClass>();
2737 weak_intrusive_ptr<const SomeClass> b = a.weak;
2738 }
2739
TEST(WeakIntrusivePtrTest,AllowsMoveAssigningToConst)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
TEST(WeakIntrusivePtrTest,AllowsCopyAssigningToConst)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
TEST(WeakIntrusivePtrTest,givenNewPtr_thenHasUseCount1)2752 TEST(WeakIntrusivePtrTest, givenNewPtr_thenHasUseCount1) {
2753 IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>();
2754 EXPECT_EQ(1, obj.weak.use_count());
2755 }
2756
TEST(WeakIntrusivePtrTest,givenNewPtr_thenIsNotExpired)2757 TEST(WeakIntrusivePtrTest, givenNewPtr_thenIsNotExpired) {
2758 IntrusiveAndWeak<SomeClass> obj = make_weak_intrusive<SomeClass>();
2759 EXPECT_FALSE(obj.weak.expired());
2760 }
2761
TEST(WeakIntrusivePtrTest,givenInvalidPtr_thenHasUseCount0)2762 TEST(WeakIntrusivePtrTest, givenInvalidPtr_thenHasUseCount0) {
2763 weak_intrusive_ptr<SomeClass> obj = make_invalid_weak<SomeClass>();
2764 EXPECT_EQ(0, obj.use_count());
2765 }
2766
TEST(WeakIntrusivePtrTest,givenInvalidPtr_thenIsExpired)2767 TEST(WeakIntrusivePtrTest, givenInvalidPtr_thenIsExpired) {
2768 weak_intrusive_ptr<SomeClass> obj = make_invalid_weak<SomeClass>();
2769 EXPECT_TRUE(obj.expired());
2770 }
2771
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_thenHasUseCount0)2772 TEST(WeakIntrusivePtrTest, givenWeakOnlyPtr_thenHasUseCount0) {
2773 weak_intrusive_ptr<SomeClass> obj = make_weak_only<SomeClass>();
2774 EXPECT_EQ(0, obj.use_count());
2775 }
2776
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_thenIsExpired)2777 TEST(WeakIntrusivePtrTest, givenWeakOnlyPtr_thenIsExpired) {
2778 weak_intrusive_ptr<SomeClass> obj = make_weak_only<SomeClass>();
2779 EXPECT_TRUE(obj.expired());
2780 }
2781
TEST(WeakIntrusivePtrTest,givenPtr_whenCallingWeakReset_thenHasUseCount0)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCallingWeakReset_thenIsExpired)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCallingStrongReset_thenHasUseCount0)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCallingStrongReset_thenIsExpired)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
TEST(WeakIntrusivePtrTest,givenMoveConstructedPtr_thenHasUseCount1)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
TEST(WeakIntrusivePtrTest,givenMoveConstructedPtr_thenIsNotExpired)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
TEST(WeakIntrusivePtrTest,givenMoveConstructedPtr_thenOldHasUseCount0)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
TEST(WeakIntrusivePtrTest,givenMoveConstructedPtr_thenOldIsExpired)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
TEST(WeakIntrusivePtrTest,givenMoveAssignedPtr_thenHasUseCount1)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
TEST(WeakIntrusivePtrTest,givenMoveAssignedPtr_thenIsNotExpired)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
TEST(WeakIntrusivePtrTest,givenMoveAssignedPtr_thenOldHasUseCount0)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
TEST(WeakIntrusivePtrTest,givenMoveAssignedPtr_thenOldIsExpired)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
TEST(WeakIntrusivePtrTest,givenCopyConstructedPtr_thenHasUseCount1)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
TEST(WeakIntrusivePtrTest,givenCopyConstructedPtr_thenIsNotExpired)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
TEST(WeakIntrusivePtrTest,givenCopyConstructedPtr_thenOldHasUseCount1)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
TEST(WeakIntrusivePtrTest,givenCopyConstructedPtr_thenOldIsNotExpired)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
TEST(WeakIntrusivePtrTest,givenPtr_whenLastStrongPointerResets_thenReleasesResources)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
TEST(WeakIntrusivePtrTest,givenPtr_whenDestructedButStillHasStrongPointers_thenDoesntReleaseResources)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
TEST(WeakIntrusivePtrTest,givenPtr_whenDestructed_thenDestructsObject)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveConstructed_thenDestructsObjectAfterSecondDestructed)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveConstructedToBaseClass_thenDestructsObjectAfterSecondDestructed)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveAssigned_thenDestructsOldObject)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveAssignedToBaseClass_thenDestructsOldObject)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
TEST(WeakIntrusivePtrTest,givenPtrWithCopy_whenMoveAssigned_thenDestructsOldObjectAfterCopyIsDestructed)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
TEST(WeakIntrusivePtrTest,givenPtrWithBaseClassCopy_whenMoveAssigned_thenDestructsOldObjectAfterCopyIsDestructed)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
TEST(WeakIntrusivePtrTest,givenPtrWithCopy_whenMoveAssignedToBaseClass_thenDestructsOldObjectAfterCopyIsDestructed)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveAssigned_thenDestructsObjectAfterSecondDestructed)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
TEST(WeakIntrusivePtrTest,givenPtr_whenMoveAssignedToBaseClass_thenDestructsObjectAfterSecondDestructed)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyConstructedAndDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyConstructedToBaseClassAndDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyConstructedAndOriginalDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyConstructedToBaseClassAndOriginalDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyAssignedAndDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyAssignedToBaseClassAndDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyAssignedAndOriginalDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyAssignedToBaseClassAndOriginalDestructed_thenDestructsObjectAfterLastDestruction)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyAssigned_thenDestructsOldObject)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCopyAssignedToBaseClass_thenDestructsOldObject)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
TEST(WeakIntrusivePtrTest,givenPtrWithCopy_whenCopyAssigned_thenDestructsOldObjectAfterCopyIsDestructed)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
TEST(WeakIntrusivePtrTest,givenPtrWithBaseClassCopy_whenCopyAssigned_thenDestructsOldObjectAfterCopyIsDestructed)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
TEST(WeakIntrusivePtrTest,givenPtrWithCopy_whenCopyAssignedToBaseClass_thenDestructsOldObjectAfterCopyIsDestructed)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
TEST(WeakIntrusivePtrTest,givenPtr_whenCallingReset_thenDestructs)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
TEST(WeakIntrusivePtrTest,givenPtrWithCopy_whenCallingReset_thenDestructsAfterCopyDestructed)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
TEST(WeakIntrusivePtrTest,givenPtrWithCopy_whenCallingResetOnCopy_thenDestructsAfterOriginalDestructed)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
TEST(WeakIntrusivePtrTest,givenPtrWithMoved_whenCallingReset_thenDestructsAfterMovedDestructed)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
TEST(WeakIntrusivePtrTest,givenPtrWithMoved_whenCallingResetOnMoved_thenDestructsImmediately)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
TEST(WeakIntrusivePtrTest,givenPtr_whenReleasedAndReclaimed_thenDoesntCrash)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
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_whenReleasedAndReclaimed_thenDoesntCrash)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
TEST(WeakIntrusivePtrTest,givenPtr_whenReleasedAndReclaimed_thenIsDestructedAtEnd)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
TEST(WeakIntrusivePtrTest,givenWeakOnlyPtr_whenReleasedAndReclaimed_thenIsDestructedAtEnd)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
TEST(WeakIntrusivePtrTest,givenStackObject_whenReclaimed_thenCrashes)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
TEST(WeakIntrusivePtrTest,givenObjectWithWeakReferenceToSelf_whenDestroyed_thenDoesNotCrash)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 // NOLINTEND(clang-analyzer-cplusplus*)
3547