blob: d88fc5409a86371e1d8aa5bf59dbfcf3fb96c0ba [file] [log] [blame]
[email protected]e6130b272012-01-05 10:52:551// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commitd7cae122008-07-26 21:49:384
[email protected]3b63f8f42011-03-28 01:54:155#include "base/memory/ref_counted.h"
mdempsky3d16d9f62014-10-09 22:17:096
François Degros017f0ce2017-12-14 05:29:057#include <type_traits>
gab37af9ea62016-10-31 17:03:208#include <utility>
9
tzik65f396932017-04-03 05:27:3410#include "base/test/gtest_util.h"
initial.commitd7cae122008-07-26 21:49:3811#include "testing/gtest/include/gtest/gtest.h"
initial.commitd7cae122008-07-26 21:49:3812
[email protected]935f7762009-01-10 00:53:1313namespace {
14
initial.commitd7cae122008-07-26 21:49:3815class SelfAssign : public base::RefCounted<SelfAssign> {
dcheng5ab2ac72014-11-26 02:35:0816 protected:
Chris Watkinsbb7211c2017-11-29 07:16:3817 virtual ~SelfAssign() = default;
[email protected]877d55d2009-11-05 21:53:0818
dcheng5ab2ac72014-11-26 02:35:0819 private:
20 friend class base::RefCounted<SelfAssign>;
21};
22
23class Derived : public SelfAssign {
24 protected:
Chris Watkinsbb7211c2017-11-29 07:16:3825 ~Derived() override = default;
dcheng5ab2ac72014-11-26 02:35:0826
27 private:
28 friend class base::RefCounted<Derived>;
initial.commitd7cae122008-07-26 21:49:3829};
30
[email protected]935f7762009-01-10 00:53:1331class CheckDerivedMemberAccess : public scoped_refptr<SelfAssign> {
32 public:
33 CheckDerivedMemberAccess() {
34 // This shouldn't compile if we don't have access to the member variable.
35 SelfAssign** pptr = &ptr_;
36 EXPECT_EQ(*pptr, ptr_);
37 }
38};
39
[email protected]e6130b272012-01-05 10:52:5540class ScopedRefPtrToSelf : public base::RefCounted<ScopedRefPtrToSelf> {
41 public:
[email protected]c9f977b2013-04-25 12:17:1542 ScopedRefPtrToSelf() : self_ptr_(this) {}
[email protected]e6130b272012-01-05 10:52:5543
44 static bool was_destroyed() { return was_destroyed_; }
45
kkimlabsaa3927982015-04-13 20:49:4346 static void reset_was_destroyed() { was_destroyed_ = false; }
47
48 scoped_refptr<ScopedRefPtrToSelf> self_ptr_;
[email protected]e6130b272012-01-05 10:52:5549
50 private:
51 friend class base::RefCounted<ScopedRefPtrToSelf>;
[email protected]a9aaa9d12012-04-25 00:42:5152 ~ScopedRefPtrToSelf() { was_destroyed_ = true; }
[email protected]e6130b272012-01-05 10:52:5553
54 static bool was_destroyed_;
[email protected]e6130b272012-01-05 10:52:5555};
56
57bool ScopedRefPtrToSelf::was_destroyed_ = false;
58
kkimlabsaa3927982015-04-13 20:49:4359class ScopedRefPtrCountBase : public base::RefCounted<ScopedRefPtrCountBase> {
60 public:
61 ScopedRefPtrCountBase() { ++constructor_count_; }
62
63 static int constructor_count() { return constructor_count_; }
64
65 static int destructor_count() { return destructor_count_; }
66
67 static void reset_count() {
68 constructor_count_ = 0;
69 destructor_count_ = 0;
70 }
71
72 protected:
73 virtual ~ScopedRefPtrCountBase() { ++destructor_count_; }
74
75 private:
76 friend class base::RefCounted<ScopedRefPtrCountBase>;
77
78 static int constructor_count_;
79 static int destructor_count_;
80};
81
82int ScopedRefPtrCountBase::constructor_count_ = 0;
83int ScopedRefPtrCountBase::destructor_count_ = 0;
84
85class ScopedRefPtrCountDerived : public ScopedRefPtrCountBase {
86 public:
87 ScopedRefPtrCountDerived() { ++constructor_count_; }
88
89 static int constructor_count() { return constructor_count_; }
90
91 static int destructor_count() { return destructor_count_; }
92
93 static void reset_count() {
94 constructor_count_ = 0;
95 destructor_count_ = 0;
96 }
97
98 protected:
99 ~ScopedRefPtrCountDerived() override { ++destructor_count_; }
100
101 private:
102 friend class base::RefCounted<ScopedRefPtrCountDerived>;
103
104 static int constructor_count_;
105 static int destructor_count_;
106};
107
108int ScopedRefPtrCountDerived::constructor_count_ = 0;
109int ScopedRefPtrCountDerived::destructor_count_ = 0;
110
piman53130922016-04-20 01:04:40111class Other : public base::RefCounted<Other> {
112 private:
113 friend class base::RefCounted<Other>;
114
Chris Watkinsbb7211c2017-11-29 07:16:38115 ~Other() = default;
piman53130922016-04-20 01:04:40116};
117
tzika52799b2017-09-27 17:21:41118class HasPrivateDestructorWithDeleter;
119
120struct Deleter {
121 static void Destruct(const HasPrivateDestructorWithDeleter* x);
122};
123
124class HasPrivateDestructorWithDeleter
125 : public base::RefCounted<HasPrivateDestructorWithDeleter, Deleter> {
126 public:
Chris Watkinsbb7211c2017-11-29 07:16:38127 HasPrivateDestructorWithDeleter() = default;
tzika52799b2017-09-27 17:21:41128
129 private:
130 friend struct Deleter;
Chris Watkinsbb7211c2017-11-29 07:16:38131 ~HasPrivateDestructorWithDeleter() = default;
tzika52799b2017-09-27 17:21:41132};
133
134void Deleter::Destruct(const HasPrivateDestructorWithDeleter* x) {
135 delete x;
136}
137
piman53130922016-04-20 01:04:40138scoped_refptr<Other> Overloaded(scoped_refptr<Other> other) {
139 return other;
140}
141
142scoped_refptr<SelfAssign> Overloaded(scoped_refptr<SelfAssign> self_assign) {
143 return self_assign;
144}
145
tzik65f396932017-04-03 05:27:34146class InitialRefCountIsOne : public base::RefCounted<InitialRefCountIsOne> {
147 public:
148 REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
149
Chris Watkinsbb7211c2017-11-29 07:16:38150 InitialRefCountIsOne() = default;
tzik65f396932017-04-03 05:27:34151
152 private:
153 friend class base::RefCounted<InitialRefCountIsOne>;
Chris Watkinsbb7211c2017-11-29 07:16:38154 ~InitialRefCountIsOne() = default;
tzik65f396932017-04-03 05:27:34155};
piman53130922016-04-20 01:04:40156
[email protected]935f7762009-01-10 00:53:13157} // end namespace
158
initial.commitd7cae122008-07-26 21:49:38159TEST(RefCountedUnitTest, TestSelfAssignment) {
160 SelfAssign* p = new SelfAssign;
[email protected]ad8e04a2010-11-01 04:16:27161 scoped_refptr<SelfAssign> var(p);
Hans Wennborg792903f2018-04-09 11:20:06162 var = *&var; // The *& defeats Clang's -Wself-assign warning.
initial.commitd7cae122008-07-26 21:49:38163 EXPECT_EQ(var.get(), p);
François Degros017f0ce2017-12-14 05:29:05164 var = std::move(var);
165 EXPECT_EQ(var.get(), p);
166 var.swap(var);
167 EXPECT_EQ(var.get(), p);
168 swap(var, var);
169 EXPECT_EQ(var.get(), p);
initial.commitd7cae122008-07-26 21:49:38170}
license.botbf09a502008-08-24 00:55:55171
[email protected]935f7762009-01-10 00:53:13172TEST(RefCountedUnitTest, ScopedRefPtrMemberAccess) {
173 CheckDerivedMemberAccess check;
174}
[email protected]e6130b272012-01-05 10:52:55175
kkimlabsaa3927982015-04-13 20:49:43176TEST(RefCountedUnitTest, ScopedRefPtrToSelfPointerAssignment) {
177 ScopedRefPtrToSelf::reset_was_destroyed();
178
[email protected]e6130b272012-01-05 10:52:55179 ScopedRefPtrToSelf* check = new ScopedRefPtrToSelf();
180 EXPECT_FALSE(ScopedRefPtrToSelf::was_destroyed());
kkimlabsaa3927982015-04-13 20:49:43181 check->self_ptr_ = nullptr;
182 EXPECT_TRUE(ScopedRefPtrToSelf::was_destroyed());
183}
184
185TEST(RefCountedUnitTest, ScopedRefPtrToSelfMoveAssignment) {
186 ScopedRefPtrToSelf::reset_was_destroyed();
187
188 ScopedRefPtrToSelf* check = new ScopedRefPtrToSelf();
189 EXPECT_FALSE(ScopedRefPtrToSelf::was_destroyed());
190 // Releasing |check->self_ptr_| will delete |check|.
191 // The move assignment operator must assign |check->self_ptr_| first then
192 // release |check->self_ptr_|.
193 check->self_ptr_ = scoped_refptr<ScopedRefPtrToSelf>();
[email protected]e6130b272012-01-05 10:52:55194 EXPECT_TRUE(ScopedRefPtrToSelf::was_destroyed());
195}
mdempsky3d16d9f62014-10-09 22:17:09196
dcheng5ab2ac72014-11-26 02:35:08197TEST(RefCountedUnitTest, BooleanTesting) {
scheib28aacfca2016-02-23 20:57:19198 scoped_refptr<SelfAssign> ptr_to_an_instance = new SelfAssign;
199 EXPECT_TRUE(ptr_to_an_instance);
200 EXPECT_FALSE(!ptr_to_an_instance);
201
202 if (ptr_to_an_instance) {
203 } else {
204 ADD_FAILURE() << "Pointer to an instance should result in true.";
205 }
206
207 if (!ptr_to_an_instance) { // check for operator!().
208 ADD_FAILURE() << "Pointer to an instance should result in !x being false.";
209 }
210
211 scoped_refptr<SelfAssign> null_ptr;
212 EXPECT_FALSE(null_ptr);
213 EXPECT_TRUE(!null_ptr);
214
215 if (null_ptr) {
216 ADD_FAILURE() << "Null pointer should result in false.";
217 }
218
219 if (!null_ptr) { // check for operator!().
220 } else {
221 ADD_FAILURE() << "Null pointer should result in !x being true.";
222 }
dcheng5ab2ac72014-11-26 02:35:08223}
224
225TEST(RefCountedUnitTest, Equality) {
226 scoped_refptr<SelfAssign> p1(new SelfAssign);
227 scoped_refptr<SelfAssign> p2(new SelfAssign);
228
229 EXPECT_EQ(p1, p1);
230 EXPECT_EQ(p2, p2);
231
232 EXPECT_NE(p1, p2);
233 EXPECT_NE(p2, p1);
234}
235
robpercival3d1a0002016-05-19 00:48:51236TEST(RefCountedUnitTest, NullptrEquality) {
237 scoped_refptr<SelfAssign> ptr_to_an_instance(new SelfAssign);
238 scoped_refptr<SelfAssign> ptr_to_nullptr;
239
240 EXPECT_NE(nullptr, ptr_to_an_instance);
241 EXPECT_NE(ptr_to_an_instance, nullptr);
242 EXPECT_EQ(nullptr, ptr_to_nullptr);
243 EXPECT_EQ(ptr_to_nullptr, nullptr);
244}
245
dcheng5ab2ac72014-11-26 02:35:08246TEST(RefCountedUnitTest, ConvertibleEquality) {
247 scoped_refptr<Derived> p1(new Derived);
248 scoped_refptr<SelfAssign> p2;
249
250 EXPECT_NE(p1, p2);
251 EXPECT_NE(p2, p1);
252
253 p2 = p1;
254
255 EXPECT_EQ(p1, p2);
256 EXPECT_EQ(p2, p1);
257}
kkimlabsaa3927982015-04-13 20:49:43258
kkimlabsaa3927982015-04-13 20:49:43259TEST(RefCountedUnitTest, MoveAssignment1) {
260 ScopedRefPtrCountBase::reset_count();
261
262 {
263 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
264 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
265 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
266 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
267
268 {
269 scoped_refptr<ScopedRefPtrCountBase> p2;
270
danakj0c8d4aa2015-11-25 05:29:58271 p2 = std::move(p1);
kkimlabsaa3927982015-04-13 20:49:43272 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
273 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
274 EXPECT_EQ(nullptr, p1.get());
275 EXPECT_EQ(raw, p2.get());
276
277 // p2 goes out of scope.
278 }
279 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
280 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
281
282 // p1 goes out of scope.
283 }
284 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
285 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
286}
287
288TEST(RefCountedUnitTest, MoveAssignment2) {
289 ScopedRefPtrCountBase::reset_count();
290
291 {
292 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
293 scoped_refptr<ScopedRefPtrCountBase> p1;
294 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
295 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
296
297 {
298 scoped_refptr<ScopedRefPtrCountBase> p2(raw);
299 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
300 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
301
danakj0c8d4aa2015-11-25 05:29:58302 p1 = std::move(p2);
kkimlabsaa3927982015-04-13 20:49:43303 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
304 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
305 EXPECT_EQ(raw, p1.get());
306 EXPECT_EQ(nullptr, p2.get());
307
308 // p2 goes out of scope.
309 }
310 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
311 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
312
313 // p1 goes out of scope.
314 }
315 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
316 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
317}
318
319TEST(RefCountedUnitTest, MoveAssignmentSameInstance1) {
320 ScopedRefPtrCountBase::reset_count();
321
322 {
323 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
324 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
325 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
326 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
327
328 {
329 scoped_refptr<ScopedRefPtrCountBase> p2(p1);
330 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
331 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
332
danakj0c8d4aa2015-11-25 05:29:58333 p1 = std::move(p2);
kkimlabsaa3927982015-04-13 20:49:43334 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
335 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
336 EXPECT_EQ(raw, p1.get());
337 EXPECT_EQ(nullptr, p2.get());
338
339 // p2 goes out of scope.
340 }
341 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
342 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
343
344 // p1 goes out of scope.
345 }
346 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
347 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
348}
349
350TEST(RefCountedUnitTest, MoveAssignmentSameInstance2) {
351 ScopedRefPtrCountBase::reset_count();
352
353 {
354 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
355 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
356 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
357 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
358
359 {
360 scoped_refptr<ScopedRefPtrCountBase> p2(p1);
361 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
362 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
363
danakj0c8d4aa2015-11-25 05:29:58364 p2 = std::move(p1);
kkimlabsaa3927982015-04-13 20:49:43365 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
366 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
367 EXPECT_EQ(nullptr, p1.get());
368 EXPECT_EQ(raw, p2.get());
369
370 // p2 goes out of scope.
371 }
372 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
373 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
374
375 // p1 goes out of scope.
376 }
377 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
378 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
379}
380
381TEST(RefCountedUnitTest, MoveAssignmentDifferentInstances) {
382 ScopedRefPtrCountBase::reset_count();
383
384 {
385 ScopedRefPtrCountBase *raw1 = new ScopedRefPtrCountBase();
386 scoped_refptr<ScopedRefPtrCountBase> p1(raw1);
387 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
388 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
389
390 {
391 ScopedRefPtrCountBase *raw2 = new ScopedRefPtrCountBase();
392 scoped_refptr<ScopedRefPtrCountBase> p2(raw2);
393 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
394 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
395
danakj0c8d4aa2015-11-25 05:29:58396 p1 = std::move(p2);
kkimlabsaa3927982015-04-13 20:49:43397 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
398 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
399 EXPECT_EQ(raw2, p1.get());
400 EXPECT_EQ(nullptr, p2.get());
401
402 // p2 goes out of scope.
403 }
404 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
405 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
406
407 // p1 goes out of scope.
408 }
409 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
410 EXPECT_EQ(2, ScopedRefPtrCountBase::destructor_count());
411}
412
Kevin Marshall7273edd2017-06-20 22:19:36413TEST(RefCountedUnitTest, MoveAssignmentSelfMove) {
414 ScopedRefPtrCountBase::reset_count();
415
416 {
417 ScopedRefPtrCountBase* raw = new ScopedRefPtrCountBase;
418 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
419 scoped_refptr<ScopedRefPtrCountBase>& p1_ref = p1;
420
421 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
422 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
423
424 p1 = std::move(p1_ref);
425
426 // |p1| is "valid but unspecified", so don't bother inspecting its
427 // contents, just ensure that we don't crash.
428 }
429
430 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
431 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
432}
433
kkimlabsaa3927982015-04-13 20:49:43434TEST(RefCountedUnitTest, MoveAssignmentDerived) {
435 ScopedRefPtrCountBase::reset_count();
436 ScopedRefPtrCountDerived::reset_count();
437
438 {
439 ScopedRefPtrCountBase *raw1 = new ScopedRefPtrCountBase();
440 scoped_refptr<ScopedRefPtrCountBase> p1(raw1);
441 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
442 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
443 EXPECT_EQ(0, ScopedRefPtrCountDerived::constructor_count());
444 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
445
446 {
447 ScopedRefPtrCountDerived *raw2 = new ScopedRefPtrCountDerived();
448 scoped_refptr<ScopedRefPtrCountDerived> p2(raw2);
449 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
450 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
451 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
452 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
453
danakj0c8d4aa2015-11-25 05:29:58454 p1 = std::move(p2);
kkimlabsaa3927982015-04-13 20:49:43455 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
456 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
457 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
458 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
459 EXPECT_EQ(raw2, p1.get());
460 EXPECT_EQ(nullptr, p2.get());
461
462 // p2 goes out of scope.
463 }
464 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
465 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
466 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
467 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
468
469 // p1 goes out of scope.
470 }
471 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
472 EXPECT_EQ(2, ScopedRefPtrCountBase::destructor_count());
473 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
474 EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count());
475}
476
477TEST(RefCountedUnitTest, MoveConstructor) {
478 ScopedRefPtrCountBase::reset_count();
479
480 {
481 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
482 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
483 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
484 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
485
486 {
danakj0c8d4aa2015-11-25 05:29:58487 scoped_refptr<ScopedRefPtrCountBase> p2(std::move(p1));
kkimlabsaa3927982015-04-13 20:49:43488 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
489 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
490 EXPECT_EQ(nullptr, p1.get());
491 EXPECT_EQ(raw, p2.get());
492
493 // p2 goes out of scope.
494 }
495 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
496 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
497
498 // p1 goes out of scope.
499 }
500 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
501 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
502}
503
504TEST(RefCountedUnitTest, MoveConstructorDerived) {
505 ScopedRefPtrCountBase::reset_count();
506 ScopedRefPtrCountDerived::reset_count();
507
508 {
509 ScopedRefPtrCountDerived *raw1 = new ScopedRefPtrCountDerived();
510 scoped_refptr<ScopedRefPtrCountDerived> p1(raw1);
511 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
512 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
513 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
514 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
515
516 {
danakj0c8d4aa2015-11-25 05:29:58517 scoped_refptr<ScopedRefPtrCountBase> p2(std::move(p1));
kkimlabsaa3927982015-04-13 20:49:43518 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
519 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
520 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
521 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
522 EXPECT_EQ(nullptr, p1.get());
523 EXPECT_EQ(raw1, p2.get());
524
525 // p2 goes out of scope.
526 }
527 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
528 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
529 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
530 EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count());
531
532 // p1 goes out of scope.
533 }
534 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
535 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
536 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
537 EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count());
538}
539
piman53130922016-04-20 01:04:40540TEST(RefCountedUnitTest, TestOverloadResolutionCopy) {
François Degros017f0ce2017-12-14 05:29:05541 const scoped_refptr<Derived> derived(new Derived);
542 const scoped_refptr<SelfAssign> expected(derived);
piman53130922016-04-20 01:04:40543 EXPECT_EQ(expected, Overloaded(derived));
544
François Degros017f0ce2017-12-14 05:29:05545 const scoped_refptr<Other> other(new Other);
piman53130922016-04-20 01:04:40546 EXPECT_EQ(other, Overloaded(other));
547}
548
549TEST(RefCountedUnitTest, TestOverloadResolutionMove) {
550 scoped_refptr<Derived> derived(new Derived);
François Degros017f0ce2017-12-14 05:29:05551 const scoped_refptr<SelfAssign> expected(derived);
piman53130922016-04-20 01:04:40552 EXPECT_EQ(expected, Overloaded(std::move(derived)));
553
554 scoped_refptr<Other> other(new Other);
François Degros017f0ce2017-12-14 05:29:05555 const scoped_refptr<Other> other2(other);
piman53130922016-04-20 01:04:40556 EXPECT_EQ(other2, Overloaded(std::move(other)));
557}
tzik65f396932017-04-03 05:27:34558
Lei Zhang6cce3ba952017-11-17 05:05:46559TEST(RefCountedUnitTest, TestMakeRefCounted) {
560 scoped_refptr<Derived> derived = new Derived;
561 EXPECT_TRUE(derived->HasOneRef());
562 derived = nullptr;
563
564 scoped_refptr<Derived> derived2 = base::MakeRefCounted<Derived>();
565 EXPECT_TRUE(derived2->HasOneRef());
566 derived2 = nullptr;
567}
568
tzik65f396932017-04-03 05:27:34569TEST(RefCountedUnitTest, TestInitialRefCountIsOne) {
570 scoped_refptr<InitialRefCountIsOne> obj =
Taiju Tsuiki36c517d2017-05-18 06:45:43571 base::MakeRefCounted<InitialRefCountIsOne>();
tzik65f396932017-04-03 05:27:34572 EXPECT_TRUE(obj->HasOneRef());
573 obj = nullptr;
574
575 scoped_refptr<InitialRefCountIsOne> obj2 =
576 base::AdoptRef(new InitialRefCountIsOne);
577 EXPECT_TRUE(obj2->HasOneRef());
578 obj2 = nullptr;
579
Taiju Tsuiki36c517d2017-05-18 06:45:43580 scoped_refptr<Other> obj3 = base::MakeRefCounted<Other>();
tzik65f396932017-04-03 05:27:34581 EXPECT_TRUE(obj3->HasOneRef());
582 obj3 = nullptr;
583}
584
585TEST(RefCountedDeathTest, TestAdoptRef) {
kylechar973a0412017-09-26 18:40:29586 // Check that WrapRefCounted() DCHECKs if passed a type that defines
587 // REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE.
588 EXPECT_DCHECK_DEATH(base::WrapRefCounted(new InitialRefCountIsOne));
tzik65f396932017-04-03 05:27:34589
kylechar973a0412017-09-26 18:40:29590 // Check that AdoptRef() DCHECKs if passed a nullptr.
tzik65f396932017-04-03 05:27:34591 InitialRefCountIsOne* ptr = nullptr;
592 EXPECT_DCHECK_DEATH(base::AdoptRef(ptr));
593
kylechar973a0412017-09-26 18:40:29594 // Check that AdoptRef() DCHECKs if passed an object that doesn't need to be
595 // adopted.
tzik65f396932017-04-03 05:27:34596 scoped_refptr<InitialRefCountIsOne> obj =
Taiju Tsuiki36c517d2017-05-18 06:45:43597 base::MakeRefCounted<InitialRefCountIsOne>();
tzik65f396932017-04-03 05:27:34598 EXPECT_DCHECK_DEATH(base::AdoptRef(obj.get()));
599}
tzika52799b2017-09-27 17:21:41600
601TEST(RefCountedUnitTest, TestPrivateDestructorWithDeleter) {
602 // Ensure that RefCounted doesn't need the access to the pointee dtor when
603 // a custom deleter is given.
604 scoped_refptr<HasPrivateDestructorWithDeleter> obj =
605 base::MakeRefCounted<HasPrivateDestructorWithDeleter>();
606}