blob: 62ebd9de7c9028a7abcb0703a9d3a3a67c69fd5a [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
gab37af9ea62016-10-31 17:03:207#include <utility>
8
tzik65f396932017-04-03 05:27:349#include "base/test/gtest_util.h"
mdempsky3d16d9f62014-10-09 22:17:0910#include "base/test/opaque_ref_counted.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:
17 virtual ~SelfAssign() {}
[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:
25 ~Derived() override {}
26
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
115 ~Other() {}
116};
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:
127 HasPrivateDestructorWithDeleter() {}
128
129 private:
130 friend struct Deleter;
131 ~HasPrivateDestructorWithDeleter() {}
132};
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
150 InitialRefCountIsOne() {}
151
152 private:
153 friend class base::RefCounted<InitialRefCountIsOne>;
154 ~InitialRefCountIsOne() {}
155};
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);
initial.commitd7cae122008-07-26 21:49:38162 var = var;
163 EXPECT_EQ(var.get(), p);
164}
license.botbf09a502008-08-24 00:55:55165
[email protected]935f7762009-01-10 00:53:13166TEST(RefCountedUnitTest, ScopedRefPtrMemberAccess) {
167 CheckDerivedMemberAccess check;
168}
[email protected]e6130b272012-01-05 10:52:55169
kkimlabsaa3927982015-04-13 20:49:43170TEST(RefCountedUnitTest, ScopedRefPtrToSelfPointerAssignment) {
171 ScopedRefPtrToSelf::reset_was_destroyed();
172
[email protected]e6130b272012-01-05 10:52:55173 ScopedRefPtrToSelf* check = new ScopedRefPtrToSelf();
174 EXPECT_FALSE(ScopedRefPtrToSelf::was_destroyed());
kkimlabsaa3927982015-04-13 20:49:43175 check->self_ptr_ = nullptr;
176 EXPECT_TRUE(ScopedRefPtrToSelf::was_destroyed());
177}
178
179TEST(RefCountedUnitTest, ScopedRefPtrToSelfMoveAssignment) {
180 ScopedRefPtrToSelf::reset_was_destroyed();
181
182 ScopedRefPtrToSelf* check = new ScopedRefPtrToSelf();
183 EXPECT_FALSE(ScopedRefPtrToSelf::was_destroyed());
184 // Releasing |check->self_ptr_| will delete |check|.
185 // The move assignment operator must assign |check->self_ptr_| first then
186 // release |check->self_ptr_|.
187 check->self_ptr_ = scoped_refptr<ScopedRefPtrToSelf>();
[email protected]e6130b272012-01-05 10:52:55188 EXPECT_TRUE(ScopedRefPtrToSelf::was_destroyed());
189}
mdempsky3d16d9f62014-10-09 22:17:09190
191TEST(RefCountedUnitTest, ScopedRefPtrToOpaque) {
gab37af9ea62016-10-31 17:03:20192 scoped_refptr<base::OpaqueRefCounted> initial = base::MakeOpaqueRefCounted();
193 base::TestOpaqueRefCounted(initial);
mdempsky3d16d9f62014-10-09 22:17:09194
gab37af9ea62016-10-31 17:03:20195 scoped_refptr<base::OpaqueRefCounted> assigned;
196 assigned = initial;
197
198 scoped_refptr<base::OpaqueRefCounted> copied(initial);
199
200 scoped_refptr<base::OpaqueRefCounted> moved(std::move(initial));
201
202 scoped_refptr<base::OpaqueRefCounted> move_assigned;
203 move_assigned = std::move(moved);
204}
205
206TEST(RefCountedUnitTest, ScopedRefPtrToOpaqueThreadSafe) {
207 scoped_refptr<base::OpaqueRefCountedThreadSafe> initial =
208 base::MakeOpaqueRefCountedThreadSafe();
209 base::TestOpaqueRefCountedThreadSafe(initial);
210
211 scoped_refptr<base::OpaqueRefCountedThreadSafe> assigned;
212 assigned = initial;
213
214 scoped_refptr<base::OpaqueRefCountedThreadSafe> copied(initial);
215
216 scoped_refptr<base::OpaqueRefCountedThreadSafe> moved(std::move(initial));
217
218 scoped_refptr<base::OpaqueRefCountedThreadSafe> move_assigned;
219 move_assigned = std::move(moved);
mdempsky3d16d9f62014-10-09 22:17:09220}
dcheng5ab2ac72014-11-26 02:35:08221
222TEST(RefCountedUnitTest, BooleanTesting) {
scheib28aacfca2016-02-23 20:57:19223 scoped_refptr<SelfAssign> ptr_to_an_instance = new SelfAssign;
224 EXPECT_TRUE(ptr_to_an_instance);
225 EXPECT_FALSE(!ptr_to_an_instance);
226
227 if (ptr_to_an_instance) {
228 } else {
229 ADD_FAILURE() << "Pointer to an instance should result in true.";
230 }
231
232 if (!ptr_to_an_instance) { // check for operator!().
233 ADD_FAILURE() << "Pointer to an instance should result in !x being false.";
234 }
235
236 scoped_refptr<SelfAssign> null_ptr;
237 EXPECT_FALSE(null_ptr);
238 EXPECT_TRUE(!null_ptr);
239
240 if (null_ptr) {
241 ADD_FAILURE() << "Null pointer should result in false.";
242 }
243
244 if (!null_ptr) { // check for operator!().
245 } else {
246 ADD_FAILURE() << "Null pointer should result in !x being true.";
247 }
dcheng5ab2ac72014-11-26 02:35:08248}
249
250TEST(RefCountedUnitTest, Equality) {
251 scoped_refptr<SelfAssign> p1(new SelfAssign);
252 scoped_refptr<SelfAssign> p2(new SelfAssign);
253
254 EXPECT_EQ(p1, p1);
255 EXPECT_EQ(p2, p2);
256
257 EXPECT_NE(p1, p2);
258 EXPECT_NE(p2, p1);
259}
260
robpercival3d1a0002016-05-19 00:48:51261TEST(RefCountedUnitTest, NullptrEquality) {
262 scoped_refptr<SelfAssign> ptr_to_an_instance(new SelfAssign);
263 scoped_refptr<SelfAssign> ptr_to_nullptr;
264
265 EXPECT_NE(nullptr, ptr_to_an_instance);
266 EXPECT_NE(ptr_to_an_instance, nullptr);
267 EXPECT_EQ(nullptr, ptr_to_nullptr);
268 EXPECT_EQ(ptr_to_nullptr, nullptr);
269}
270
dcheng5ab2ac72014-11-26 02:35:08271TEST(RefCountedUnitTest, ConvertibleEquality) {
272 scoped_refptr<Derived> p1(new Derived);
273 scoped_refptr<SelfAssign> p2;
274
275 EXPECT_NE(p1, p2);
276 EXPECT_NE(p2, p1);
277
278 p2 = p1;
279
280 EXPECT_EQ(p1, p2);
281 EXPECT_EQ(p2, p1);
282}
kkimlabsaa3927982015-04-13 20:49:43283
kkimlabsaa3927982015-04-13 20:49:43284TEST(RefCountedUnitTest, MoveAssignment1) {
285 ScopedRefPtrCountBase::reset_count();
286
287 {
288 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
289 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
290 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
291 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
292
293 {
294 scoped_refptr<ScopedRefPtrCountBase> p2;
295
danakj0c8d4aa2015-11-25 05:29:58296 p2 = std::move(p1);
kkimlabsaa3927982015-04-13 20:49:43297 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
298 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
299 EXPECT_EQ(nullptr, p1.get());
300 EXPECT_EQ(raw, p2.get());
301
302 // p2 goes out of scope.
303 }
304 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
305 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
306
307 // p1 goes out of scope.
308 }
309 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
310 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
311}
312
313TEST(RefCountedUnitTest, MoveAssignment2) {
314 ScopedRefPtrCountBase::reset_count();
315
316 {
317 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
318 scoped_refptr<ScopedRefPtrCountBase> p1;
319 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
320 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
321
322 {
323 scoped_refptr<ScopedRefPtrCountBase> p2(raw);
324 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
325 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
326
danakj0c8d4aa2015-11-25 05:29:58327 p1 = std::move(p2);
kkimlabsaa3927982015-04-13 20:49:43328 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
329 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
330 EXPECT_EQ(raw, p1.get());
331 EXPECT_EQ(nullptr, p2.get());
332
333 // p2 goes out of scope.
334 }
335 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
336 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
337
338 // p1 goes out of scope.
339 }
340 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
341 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
342}
343
344TEST(RefCountedUnitTest, MoveAssignmentSameInstance1) {
345 ScopedRefPtrCountBase::reset_count();
346
347 {
348 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
349 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
350 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
351 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
352
353 {
354 scoped_refptr<ScopedRefPtrCountBase> p2(p1);
355 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
356 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
357
danakj0c8d4aa2015-11-25 05:29:58358 p1 = std::move(p2);
kkimlabsaa3927982015-04-13 20:49:43359 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
360 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
361 EXPECT_EQ(raw, p1.get());
362 EXPECT_EQ(nullptr, p2.get());
363
364 // p2 goes out of scope.
365 }
366 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
367 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
368
369 // p1 goes out of scope.
370 }
371 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
372 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
373}
374
375TEST(RefCountedUnitTest, MoveAssignmentSameInstance2) {
376 ScopedRefPtrCountBase::reset_count();
377
378 {
379 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
380 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
381 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
382 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
383
384 {
385 scoped_refptr<ScopedRefPtrCountBase> p2(p1);
386 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
387 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
388
danakj0c8d4aa2015-11-25 05:29:58389 p2 = std::move(p1);
kkimlabsaa3927982015-04-13 20:49:43390 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
391 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
392 EXPECT_EQ(nullptr, p1.get());
393 EXPECT_EQ(raw, p2.get());
394
395 // p2 goes out of scope.
396 }
397 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
398 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
399
400 // p1 goes out of scope.
401 }
402 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
403 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
404}
405
406TEST(RefCountedUnitTest, MoveAssignmentDifferentInstances) {
407 ScopedRefPtrCountBase::reset_count();
408
409 {
410 ScopedRefPtrCountBase *raw1 = new ScopedRefPtrCountBase();
411 scoped_refptr<ScopedRefPtrCountBase> p1(raw1);
412 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
413 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
414
415 {
416 ScopedRefPtrCountBase *raw2 = new ScopedRefPtrCountBase();
417 scoped_refptr<ScopedRefPtrCountBase> p2(raw2);
418 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
419 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
420
danakj0c8d4aa2015-11-25 05:29:58421 p1 = std::move(p2);
kkimlabsaa3927982015-04-13 20:49:43422 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
423 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
424 EXPECT_EQ(raw2, p1.get());
425 EXPECT_EQ(nullptr, p2.get());
426
427 // p2 goes out of scope.
428 }
429 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
430 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
431
432 // p1 goes out of scope.
433 }
434 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
435 EXPECT_EQ(2, ScopedRefPtrCountBase::destructor_count());
436}
437
Kevin Marshall7273edd2017-06-20 22:19:36438TEST(RefCountedUnitTest, MoveAssignmentSelfMove) {
439 ScopedRefPtrCountBase::reset_count();
440
441 {
442 ScopedRefPtrCountBase* raw = new ScopedRefPtrCountBase;
443 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
444 scoped_refptr<ScopedRefPtrCountBase>& p1_ref = p1;
445
446 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
447 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
448
449 p1 = std::move(p1_ref);
450
451 // |p1| is "valid but unspecified", so don't bother inspecting its
452 // contents, just ensure that we don't crash.
453 }
454
455 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
456 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
457}
458
kkimlabsaa3927982015-04-13 20:49:43459TEST(RefCountedUnitTest, MoveAssignmentDerived) {
460 ScopedRefPtrCountBase::reset_count();
461 ScopedRefPtrCountDerived::reset_count();
462
463 {
464 ScopedRefPtrCountBase *raw1 = new ScopedRefPtrCountBase();
465 scoped_refptr<ScopedRefPtrCountBase> p1(raw1);
466 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
467 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
468 EXPECT_EQ(0, ScopedRefPtrCountDerived::constructor_count());
469 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
470
471 {
472 ScopedRefPtrCountDerived *raw2 = new ScopedRefPtrCountDerived();
473 scoped_refptr<ScopedRefPtrCountDerived> p2(raw2);
474 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
475 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
476 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
477 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
478
danakj0c8d4aa2015-11-25 05:29:58479 p1 = std::move(p2);
kkimlabsaa3927982015-04-13 20:49:43480 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
481 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
482 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
483 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
484 EXPECT_EQ(raw2, p1.get());
485 EXPECT_EQ(nullptr, p2.get());
486
487 // p2 goes out of scope.
488 }
489 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
490 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
491 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
492 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
493
494 // p1 goes out of scope.
495 }
496 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
497 EXPECT_EQ(2, ScopedRefPtrCountBase::destructor_count());
498 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
499 EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count());
500}
501
502TEST(RefCountedUnitTest, MoveConstructor) {
503 ScopedRefPtrCountBase::reset_count();
504
505 {
506 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
507 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
508 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
509 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
510
511 {
danakj0c8d4aa2015-11-25 05:29:58512 scoped_refptr<ScopedRefPtrCountBase> p2(std::move(p1));
kkimlabsaa3927982015-04-13 20:49:43513 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
514 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
515 EXPECT_EQ(nullptr, p1.get());
516 EXPECT_EQ(raw, p2.get());
517
518 // p2 goes out of scope.
519 }
520 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
521 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
522
523 // p1 goes out of scope.
524 }
525 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
526 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
527}
528
529TEST(RefCountedUnitTest, MoveConstructorDerived) {
530 ScopedRefPtrCountBase::reset_count();
531 ScopedRefPtrCountDerived::reset_count();
532
533 {
534 ScopedRefPtrCountDerived *raw1 = new ScopedRefPtrCountDerived();
535 scoped_refptr<ScopedRefPtrCountDerived> p1(raw1);
536 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
537 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
538 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
539 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
540
541 {
danakj0c8d4aa2015-11-25 05:29:58542 scoped_refptr<ScopedRefPtrCountBase> p2(std::move(p1));
kkimlabsaa3927982015-04-13 20:49:43543 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
544 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
545 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
546 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
547 EXPECT_EQ(nullptr, p1.get());
548 EXPECT_EQ(raw1, p2.get());
549
550 // p2 goes out of scope.
551 }
552 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
553 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
554 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
555 EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count());
556
557 // p1 goes out of scope.
558 }
559 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
560 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
561 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
562 EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count());
563}
564
piman53130922016-04-20 01:04:40565TEST(RefCountedUnitTest, TestOverloadResolutionCopy) {
566 scoped_refptr<Derived> derived(new Derived);
567 scoped_refptr<SelfAssign> expected(derived);
568 EXPECT_EQ(expected, Overloaded(derived));
569
570 scoped_refptr<Other> other(new Other);
571 EXPECT_EQ(other, Overloaded(other));
572}
573
574TEST(RefCountedUnitTest, TestOverloadResolutionMove) {
575 scoped_refptr<Derived> derived(new Derived);
576 scoped_refptr<SelfAssign> expected(derived);
577 EXPECT_EQ(expected, Overloaded(std::move(derived)));
578
579 scoped_refptr<Other> other(new Other);
580 scoped_refptr<Other> other2(other);
581 EXPECT_EQ(other2, Overloaded(std::move(other)));
582}
tzik65f396932017-04-03 05:27:34583
584TEST(RefCountedUnitTest, TestInitialRefCountIsOne) {
585 scoped_refptr<InitialRefCountIsOne> obj =
Taiju Tsuiki36c517d2017-05-18 06:45:43586 base::MakeRefCounted<InitialRefCountIsOne>();
tzik65f396932017-04-03 05:27:34587 EXPECT_TRUE(obj->HasOneRef());
588 obj = nullptr;
589
590 scoped_refptr<InitialRefCountIsOne> obj2 =
591 base::AdoptRef(new InitialRefCountIsOne);
592 EXPECT_TRUE(obj2->HasOneRef());
593 obj2 = nullptr;
594
Taiju Tsuiki36c517d2017-05-18 06:45:43595 scoped_refptr<Other> obj3 = base::MakeRefCounted<Other>();
tzik65f396932017-04-03 05:27:34596 EXPECT_TRUE(obj3->HasOneRef());
597 obj3 = nullptr;
598}
599
600TEST(RefCountedDeathTest, TestAdoptRef) {
kylechar973a0412017-09-26 18:40:29601 // Check that WrapRefCounted() DCHECKs if passed a type that defines
602 // REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE.
603 EXPECT_DCHECK_DEATH(base::WrapRefCounted(new InitialRefCountIsOne));
tzik65f396932017-04-03 05:27:34604
kylechar973a0412017-09-26 18:40:29605 // Check that AdoptRef() DCHECKs if passed a nullptr.
tzik65f396932017-04-03 05:27:34606 InitialRefCountIsOne* ptr = nullptr;
607 EXPECT_DCHECK_DEATH(base::AdoptRef(ptr));
608
kylechar973a0412017-09-26 18:40:29609 // Check that AdoptRef() DCHECKs if passed an object that doesn't need to be
610 // adopted.
tzik65f396932017-04-03 05:27:34611 scoped_refptr<InitialRefCountIsOne> obj =
Taiju Tsuiki36c517d2017-05-18 06:45:43612 base::MakeRefCounted<InitialRefCountIsOne>();
tzik65f396932017-04-03 05:27:34613 EXPECT_DCHECK_DEATH(base::AdoptRef(obj.get()));
614}
tzika52799b2017-09-27 17:21:41615
616TEST(RefCountedUnitTest, TestPrivateDestructorWithDeleter) {
617 // Ensure that RefCounted doesn't need the access to the pointee dtor when
618 // a custom deleter is given.
619 scoped_refptr<HasPrivateDestructorWithDeleter> obj =
620 base::MakeRefCounted<HasPrivateDestructorWithDeleter>();
621}