12#include "gtest/gtest.h"
17#define ALLOW_PESSIMIZING_MOVE(code_line) \
18 _Pragma("clang diagnostic push") \
19 _Pragma("clang diagnostic ignored \"-Wpessimizing-move\"") code_line; \
20 _Pragma("clang diagnostic pop")
22#define ALLOW_PESSIMIZING_MOVE(code_line) code_line;
26#define ALLOW_SELF_MOVE(code_line) \
27 _Pragma("clang diagnostic push") \
28 _Pragma("clang diagnostic ignored \"-Wself-move\"") code_line; \
29 _Pragma("clang diagnostic pop")
31#define ALLOW_SELF_MOVE(code_line) code_line;
35#define ALLOW_SELF_ASSIGN_OVERLOADED(code_line) \
36 _Pragma("clang diagnostic push") \
37 _Pragma("clang diagnostic ignored \"-Wself-assign-overloaded\"") \
39 _Pragma("clang diagnostic pop")
41#define ALLOW_SELF_ASSIGN_OVERLOADED(code_line) code_line;
47class MyClass :
public RefCountedThreadSafe<MyClass> {
49 MyClass(MyClass** created,
bool* was_destroyed)
50 : was_destroyed_(was_destroyed) {
57 *was_destroyed_ =
true;
70class MySubclass final :
public MyClass {
75 MySubclass(MySubclass** created,
bool* was_destroyed)
76 : MyClass(
nullptr, was_destroyed) {
81 ~MySubclass()
override {}
86TEST(RefCountedTest, Constructors) {
92 EXPECT_TRUE(r.get() ==
nullptr);
98 RefPtr<MyClass> r(
nullptr);
99 EXPECT_TRUE(r.get() ==
nullptr);
104 MyClass* created =
nullptr;
105 was_destroyed =
false;
107 RefPtr<MyClass> r(MakeRefCounted<MyClass>(&created, &was_destroyed));
108 EXPECT_TRUE(created);
109 EXPECT_EQ(created, r.get());
111 EXPECT_FALSE(was_destroyed);
113 EXPECT_TRUE(was_destroyed);
116 MyClass* created =
nullptr;
117 was_destroyed =
false;
120 std::move(MakeRefCounted<MyClass>(&created, &was_destroyed))))
121 EXPECT_TRUE(created);
122 EXPECT_EQ(created, r.get());
124 EXPECT_FALSE(was_destroyed);
126 EXPECT_TRUE(was_destroyed);
129 MyClass* created =
nullptr;
130 was_destroyed =
false;
131 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(&created, &was_destroyed));
134 RefPtr<MyClass> r2(r1);
135 EXPECT_TRUE(created);
136 EXPECT_EQ(created, r1.get());
137 EXPECT_EQ(created, r2.get());
140 EXPECT_FALSE(was_destroyed);
142 EXPECT_TRUE(was_destroyed);
145 MyClass* created =
nullptr;
146 was_destroyed =
false;
147 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(&created, &was_destroyed));
149 RefPtr<MyClass> r2(created);
150 EXPECT_TRUE(created);
151 EXPECT_EQ(created, r1.get());
152 EXPECT_EQ(created, r2.get());
155 EXPECT_FALSE(was_destroyed);
157 EXPECT_TRUE(was_destroyed);
160 MySubclass* created =
nullptr;
161 was_destroyed =
false;
163 RefPtr<MyClass> r(MakeRefCounted<MySubclass>(&created, &was_destroyed));
164 EXPECT_TRUE(created);
165 EXPECT_EQ(
static_cast<MyClass*
>(created), r.get());
167 EXPECT_FALSE(was_destroyed);
169 EXPECT_TRUE(was_destroyed);
172 MySubclass* created =
nullptr;
173 was_destroyed =
false;
176 std::move(MakeRefCounted<MySubclass>(&created, &was_destroyed))))
177 EXPECT_TRUE(created);
178 EXPECT_EQ(
static_cast<MyClass*
>(created), r.get());
180 EXPECT_FALSE(was_destroyed);
182 EXPECT_TRUE(was_destroyed);
185 MySubclass* created =
nullptr;
186 was_destroyed =
false;
187 RefPtr<MySubclass> r1(MakeRefCounted<MySubclass>(&created, &was_destroyed));
189 RefPtr<MyClass> r2(r1);
190 EXPECT_TRUE(created);
191 EXPECT_EQ(
static_cast<MyClass*
>(created), r1.get());
192 EXPECT_EQ(
static_cast<MyClass*
>(created), r2.get());
195 EXPECT_FALSE(was_destroyed);
197 EXPECT_TRUE(was_destroyed);
200 MySubclass* created =
nullptr;
201 was_destroyed =
false;
202 RefPtr<MySubclass> r1(MakeRefCounted<MySubclass>(&created, &was_destroyed));
204 RefPtr<MyClass> r2(created);
205 EXPECT_TRUE(created);
206 EXPECT_EQ(
static_cast<MyClass*
>(created), r1.get());
207 EXPECT_EQ(
static_cast<MyClass*
>(created), r2.get());
210 EXPECT_FALSE(was_destroyed);
212 EXPECT_TRUE(was_destroyed);
215TEST(RefCountedTest, NullAssignmentToNull) {
219 EXPECT_TRUE(r1.get() ==
nullptr);
225 EXPECT_TRUE(r1.get() ==
nullptr);
226 EXPECT_TRUE(r2.get() ==
nullptr);
232 EXPECT_TRUE(r1.get() ==
nullptr);
235 EXPECT_TRUE(r2.get() ==
nullptr);
240 RefPtr<MySubclass> r3;
243 EXPECT_TRUE(r1.get() ==
nullptr);
244 EXPECT_TRUE(r3.get() ==
nullptr);
250 EXPECT_TRUE(r1.get() ==
nullptr);
251 EXPECT_TRUE(r3.get() ==
nullptr);
256TEST(RefCountedTest, NonNullAssignmentToNull) {
260 MyClass* created =
nullptr;
261 was_destroyed =
false;
262 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(&created, &was_destroyed));
266 EXPECT_EQ(created, r1.get());
267 EXPECT_EQ(created, r2.get());
270 EXPECT_FALSE(was_destroyed);
272 EXPECT_TRUE(was_destroyed);
275 MyClass* created =
nullptr;
276 was_destroyed =
false;
277 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(&created, &was_destroyed));
283 EXPECT_TRUE(r1.get() ==
nullptr);
285 EXPECT_EQ(created, r2.get());
288 EXPECT_FALSE(was_destroyed);
290 EXPECT_TRUE(was_destroyed);
293 MySubclass* created =
nullptr;
294 was_destroyed =
false;
295 RefPtr<MySubclass> r1(MakeRefCounted<MySubclass>(&created, &was_destroyed));
299 EXPECT_EQ(created, r1.get());
300 EXPECT_EQ(
static_cast<MyClass*
>(created), r2.get());
303 EXPECT_FALSE(was_destroyed);
305 EXPECT_TRUE(was_destroyed);
308 MySubclass* created =
nullptr;
309 was_destroyed =
false;
310 RefPtr<MySubclass> r1(MakeRefCounted<MySubclass>(&created, &was_destroyed));
314 EXPECT_TRUE(r1.get() ==
nullptr);
315 EXPECT_EQ(
static_cast<MyClass*
>(created), r2.get());
318 EXPECT_FALSE(was_destroyed);
320 EXPECT_TRUE(was_destroyed);
323TEST(RefCountedTest, NullAssignmentToNonNull) {
324 bool was_destroyed =
false;
325 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(
nullptr, &was_destroyed));
328 EXPECT_TRUE(r1.get() ==
nullptr);
330 EXPECT_TRUE(was_destroyed);
332 was_destroyed =
false;
333 r1 = MakeRefCounted<MyClass>(
nullptr, &was_destroyed);
337 EXPECT_TRUE(r1.get() ==
nullptr);
338 EXPECT_TRUE(r2.get() ==
nullptr);
341 EXPECT_TRUE(was_destroyed);
343 was_destroyed =
false;
344 r1 = MakeRefCounted<MyClass>(
nullptr, &was_destroyed);
347 EXPECT_TRUE(r1.get() ==
nullptr);
350 EXPECT_TRUE(r2.get() ==
nullptr);
354 EXPECT_TRUE(was_destroyed);
356 was_destroyed =
false;
357 r1 = MakeRefCounted<MyClass>(
nullptr, &was_destroyed);
358 RefPtr<MySubclass> r3;
361 EXPECT_TRUE(r1.get() ==
nullptr);
362 EXPECT_TRUE(r3.get() ==
nullptr);
365 EXPECT_TRUE(was_destroyed);
367 was_destroyed =
false;
368 r1 = MakeRefCounted<MyClass>(
nullptr, &was_destroyed);
371 EXPECT_TRUE(r1.get() ==
nullptr);
372 EXPECT_TRUE(r3.get() ==
nullptr);
375 EXPECT_TRUE(was_destroyed);
378TEST(RefCountedTest, NonNullAssignmentToNonNull) {
383 was_destroyed1 =
false;
384 was_destroyed2 =
false;
385 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(
nullptr, &was_destroyed1));
386 RefPtr<MyClass> r2(MakeRefCounted<MyClass>(
nullptr, &was_destroyed2));
389 EXPECT_EQ(r1.get(), r2.get());
392 EXPECT_FALSE(was_destroyed1);
393 EXPECT_TRUE(was_destroyed2);
395 EXPECT_TRUE(was_destroyed1);
398 was_destroyed1 =
false;
399 was_destroyed2 =
false;
400 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(
nullptr, &was_destroyed1));
401 RefPtr<MyClass> r2(MakeRefCounted<MyClass>(
nullptr, &was_destroyed2));
406 EXPECT_TRUE(r1.get() ==
nullptr);
408 EXPECT_FALSE(r2.get() ==
nullptr);
411 EXPECT_FALSE(was_destroyed1);
412 EXPECT_TRUE(was_destroyed2);
414 EXPECT_TRUE(was_destroyed1);
417 was_destroyed1 =
false;
418 was_destroyed2 =
false;
419 RefPtr<MySubclass> r1(MakeRefCounted<MySubclass>(
nullptr, &was_destroyed1));
420 RefPtr<MyClass> r2(MakeRefCounted<MyClass>(
nullptr, &was_destroyed2));
423 EXPECT_EQ(r1.get(), r2.get());
426 EXPECT_FALSE(was_destroyed1);
427 EXPECT_TRUE(was_destroyed2);
429 EXPECT_TRUE(was_destroyed1);
432 was_destroyed1 =
false;
433 was_destroyed2 =
false;
434 RefPtr<MySubclass> r1(MakeRefCounted<MySubclass>(
nullptr, &was_destroyed1));
435 RefPtr<MyClass> r2(MakeRefCounted<MyClass>(
nullptr, &was_destroyed2));
438 EXPECT_TRUE(r1.get() ==
nullptr);
439 EXPECT_FALSE(r2.get() ==
nullptr);
442 EXPECT_FALSE(was_destroyed1);
443 EXPECT_TRUE(was_destroyed2);
445 EXPECT_TRUE(was_destroyed1);
448TEST(RefCountedTest, SelfAssignment) {
452 MyClass* created =
nullptr;
453 was_destroyed =
false;
459 RefPtr<MyClass> r(MakeRefCounted<MyClass>(
460 &created, &was_destroyed));
463 EXPECT_EQ(created, r.get());
464 EXPECT_FALSE(was_destroyed);
466 EXPECT_TRUE(was_destroyed);
469 MyClass* created =
nullptr;
470 was_destroyed =
false;
471 RefPtr<MyClass> r(MakeRefCounted<MyClass>(&created, &was_destroyed));
474 EXPECT_EQ(created, r.get());
475 EXPECT_FALSE(was_destroyed);
477 EXPECT_TRUE(was_destroyed);
480TEST(RefCountedTest, Swap) {
481 MyClass* created1 =
nullptr;
482 static bool was_destroyed1;
483 was_destroyed1 =
false;
484 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(&created1, &was_destroyed1));
485 EXPECT_TRUE(created1);
486 EXPECT_EQ(created1, r1.get());
488 MyClass* created2 =
nullptr;
489 static bool was_destroyed2;
490 was_destroyed2 =
false;
491 RefPtr<MyClass> r2(MakeRefCounted<MyClass>(&created2, &was_destroyed2));
492 EXPECT_TRUE(created2);
493 EXPECT_EQ(created2, r2.get());
494 EXPECT_NE(created1, created2);
497 EXPECT_EQ(created2, r1.get());
498 EXPECT_EQ(created1, r2.get());
501TEST(RefCountedTest, GetAndDereferenceOperators) {
505 MyClass* created =
nullptr;
506 const RefPtr<MyClass> r(MakeRefCounted<MyClass>(&created,
nullptr));
507 MyClass* ptr = r.get();
508 EXPECT_EQ(created, ptr);
509 ptr = r.operator->();
510 EXPECT_EQ(created, ptr);
512 EXPECT_EQ(created, &ref);
516TEST(RefCountedTest, AddRefRelease) {
517 MyClass* created =
nullptr;
518 bool was_destroyed =
false;
520 RefPtr<MyClass> r(MakeRefCounted<MyClass>(&created, &was_destroyed));
521 EXPECT_EQ(created, r.get());
524 EXPECT_FALSE(was_destroyed);
526 EXPECT_TRUE(was_destroyed);
529TEST(RefCountedTest, Mix) {
530 MySubclass* created =
nullptr;
531 bool was_destroyed =
false;
532 RefPtr<MySubclass> r1(MakeRefCounted<MySubclass>(&created, &was_destroyed));
533 ASSERT_FALSE(was_destroyed);
534 EXPECT_TRUE(created->HasOneRef());
535 created->AssertHasOneRef();
537 RefPtr<MySubclass> r2 = r1;
538 ASSERT_FALSE(was_destroyed);
539 EXPECT_FALSE(created->HasOneRef());
542 ASSERT_FALSE(was_destroyed);
543 created->AssertHasOneRef();
546 RefPtr<MyClass> r3 = r2;
547 EXPECT_FALSE(created->HasOneRef());
550 RefPtr<MyClass> r4(r3);
552 ASSERT_FALSE(was_destroyed);
553 EXPECT_FALSE(created->HasOneRef());
555 ASSERT_FALSE(was_destroyed);
556 EXPECT_TRUE(created->HasOneRef());
557 created->AssertHasOneRef();
559 r1 = RefPtr<MySubclass>(
static_cast<MySubclass*
>(r3.get()));
560 ASSERT_FALSE(was_destroyed);
561 EXPECT_FALSE(created->HasOneRef());
563 ASSERT_FALSE(was_destroyed);
564 EXPECT_TRUE(created->HasOneRef());
565 created->AssertHasOneRef();
567 EXPECT_EQ(created, r1.get());
570 EXPECT_TRUE(was_destroyed);
573class MyPublicClass :
public RefCountedThreadSafe<MyPublicClass> {
576 MyPublicClass() : has_num_(
false), num_(0) {}
577 explicit MyPublicClass(
int num) : has_num_(
true), num_(num) {}
581 bool has_num()
const {
return has_num_; }
582 int num()
const {
return num_; }
593TEST(RefCountedTest, PublicCtorAndDtor) {
594 RefPtr<MyPublicClass> r1 = MakeRefCounted<MyPublicClass>();
596 EXPECT_FALSE(r1->has_num());
598 RefPtr<MyPublicClass> r2 = MakeRefCounted<MyPublicClass>(123);
600 EXPECT_TRUE(r2->has_num());
601 EXPECT_EQ(123, r2->num());
602 EXPECT_NE(r1.get(), r2.get());
605 EXPECT_TRUE(r1->has_num());
606 EXPECT_EQ(123, r1->num());
607 EXPECT_EQ(r1.get(), r2.get());
611 EXPECT_TRUE(r1->has_num());
612 EXPECT_EQ(123, r1->num());
622TEST(RefCountedTest, DebugChecks) {
624 MyPublicClass* p =
new MyPublicClass();
625 EXPECT_DEATH_IF_SUPPORTED(
626 delete p,
"!adoption_required_");
630 MyPublicClass* p =
new MyPublicClass();
631 EXPECT_DEATH_IF_SUPPORTED(
632 RefPtr<MyPublicClass> r(p),
"!adoption_required_");
636 RefPtr<MyPublicClass> r(MakeRefCounted<MyPublicClass>());
637 EXPECT_DEATH_IF_SUPPORTED(
delete r.get(),
"destruction_started_");
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
TEST(MallocMapping, EmptyContructor)
#define FML_FRIEND_REF_COUNTED_THREAD_SAFE(T)
#define FML_FRIEND_MAKE_REF_COUNTED(T)
#define ALLOW_PESSIMIZING_MOVE(code_line)
#define ALLOW_SELF_ASSIGN_OVERLOADED(code_line)
#define ALLOW_SELF_MOVE(code_line)