9#include "flutter/fml/memory/ref_counted.h"
11#include "flutter/fml/macros.h"
12#include "gtest/gtest.h"
15#define ALLOW_PESSIMIZING_MOVE(code_line) \
16 _Pragma("clang diagnostic push") \
17 _Pragma("clang diagnostic ignored \"-Wpessimizing-move\"") code_line; \
18 _Pragma("clang diagnostic pop")
20#define ALLOW_PESSIMIZING_MOVE(code_line) code_line;
24#define ALLOW_SELF_MOVE(code_line) \
25 _Pragma("clang diagnostic push") \
26 _Pragma("clang diagnostic ignored \"-Wself-move\"") code_line; \
27 _Pragma("clang diagnostic pop")
29#define ALLOW_SELF_MOVE(code_line) code_line;
33#define ALLOW_SELF_ASSIGN_OVERLOADED(code_line) \
34 _Pragma("clang diagnostic push") \
35 _Pragma("clang diagnostic ignored \"-Wself-assign-overloaded\"") \
37 _Pragma("clang diagnostic pop")
39#define ALLOW_SELF_ASSIGN_OVERLOADED(code_line) code_line;
45class MyClass :
public RefCountedThreadSafe<MyClass> {
47 MyClass(MyClass** created,
bool* was_destroyed)
48 : was_destroyed_(was_destroyed) {
55 *was_destroyed_ =
true;
68class MySubclass final :
public MyClass {
73 MySubclass(MySubclass** created,
bool* was_destroyed)
74 : MyClass(
nullptr, was_destroyed) {
79 ~MySubclass()
override {}
84TEST(RefCountedTest, Constructors) {
96 RefPtr<MyClass> r(
nullptr);
102 MyClass* created =
nullptr;
103 was_destroyed =
false;
105 RefPtr<MyClass> r(MakeRefCounted<MyClass>(&created, &was_destroyed));
107 EXPECT_EQ(created, r.get());
109 EXPECT_FALSE(was_destroyed);
114 MyClass* created =
nullptr;
115 was_destroyed =
false;
118 std::move(MakeRefCounted<MyClass>(&created, &was_destroyed))))
120 EXPECT_EQ(created, r.get());
122 EXPECT_FALSE(was_destroyed);
127 MyClass* created =
nullptr;
128 was_destroyed =
false;
129 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(&created, &was_destroyed));
132 RefPtr<MyClass> r2(r1);
134 EXPECT_EQ(created, r1.get());
135 EXPECT_EQ(created, r2.get());
138 EXPECT_FALSE(was_destroyed);
143 MyClass* created =
nullptr;
144 was_destroyed =
false;
145 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(&created, &was_destroyed));
147 RefPtr<MyClass> r2(created);
149 EXPECT_EQ(created, r1.get());
150 EXPECT_EQ(created, r2.get());
153 EXPECT_FALSE(was_destroyed);
158 MySubclass* created =
nullptr;
159 was_destroyed =
false;
161 RefPtr<MyClass> r(MakeRefCounted<MySubclass>(&created, &was_destroyed));
163 EXPECT_EQ(
static_cast<MyClass*
>(created), r.get());
165 EXPECT_FALSE(was_destroyed);
170 MySubclass* created =
nullptr;
171 was_destroyed =
false;
174 std::move(MakeRefCounted<MySubclass>(&created, &was_destroyed))))
176 EXPECT_EQ(
static_cast<MyClass*
>(created), r.get());
178 EXPECT_FALSE(was_destroyed);
183 MySubclass* created =
nullptr;
184 was_destroyed =
false;
185 RefPtr<MySubclass> r1(MakeRefCounted<MySubclass>(&created, &was_destroyed));
187 RefPtr<MyClass> r2(r1);
189 EXPECT_EQ(
static_cast<MyClass*
>(created), r1.get());
190 EXPECT_EQ(
static_cast<MyClass*
>(created), r2.get());
193 EXPECT_FALSE(was_destroyed);
198 MySubclass* created =
nullptr;
199 was_destroyed =
false;
200 RefPtr<MySubclass> r1(MakeRefCounted<MySubclass>(&created, &was_destroyed));
202 RefPtr<MyClass> r2(created);
204 EXPECT_EQ(
static_cast<MyClass*
>(created), r1.get());
205 EXPECT_EQ(
static_cast<MyClass*
>(created), r2.get());
208 EXPECT_FALSE(was_destroyed);
213TEST(RefCountedTest, NullAssignmentToNull) {
238 RefPtr<MySubclass> r3;
254TEST(RefCountedTest, NonNullAssignmentToNull) {
258 MyClass* created =
nullptr;
259 was_destroyed =
false;
260 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(&created, &was_destroyed));
264 EXPECT_EQ(created, r1.get());
265 EXPECT_EQ(created, r2.get());
268 EXPECT_FALSE(was_destroyed);
273 MyClass* created =
nullptr;
274 was_destroyed =
false;
275 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(&created, &was_destroyed));
283 EXPECT_EQ(created, r2.get());
286 EXPECT_FALSE(was_destroyed);
291 MySubclass* created =
nullptr;
292 was_destroyed =
false;
293 RefPtr<MySubclass> r1(MakeRefCounted<MySubclass>(&created, &was_destroyed));
297 EXPECT_EQ(created, r1.get());
298 EXPECT_EQ(
static_cast<MyClass*
>(created), r2.get());
301 EXPECT_FALSE(was_destroyed);
306 MySubclass* created =
nullptr;
307 was_destroyed =
false;
308 RefPtr<MySubclass> r1(MakeRefCounted<MySubclass>(&created, &was_destroyed));
313 EXPECT_EQ(
static_cast<MyClass*
>(created), r2.get());
316 EXPECT_FALSE(was_destroyed);
321TEST(RefCountedTest, NullAssignmentToNonNull) {
322 bool was_destroyed =
false;
323 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(
nullptr, &was_destroyed));
330 was_destroyed =
false;
331 r1 = MakeRefCounted<MyClass>(
nullptr, &was_destroyed);
341 was_destroyed =
false;
342 r1 = MakeRefCounted<MyClass>(
nullptr, &was_destroyed);
354 was_destroyed =
false;
355 r1 = MakeRefCounted<MyClass>(
nullptr, &was_destroyed);
356 RefPtr<MySubclass> r3;
365 was_destroyed =
false;
366 r1 = MakeRefCounted<MyClass>(
nullptr, &was_destroyed);
376TEST(RefCountedTest, NonNullAssignmentToNonNull) {
381 was_destroyed1 =
false;
382 was_destroyed2 =
false;
383 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(
nullptr, &was_destroyed1));
384 RefPtr<MyClass> r2(MakeRefCounted<MyClass>(
nullptr, &was_destroyed2));
387 EXPECT_EQ(r1.get(), r2.get());
390 EXPECT_FALSE(was_destroyed1);
396 was_destroyed1 =
false;
397 was_destroyed2 =
false;
398 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(
nullptr, &was_destroyed1));
399 RefPtr<MyClass> r2(MakeRefCounted<MyClass>(
nullptr, &was_destroyed2));
406 EXPECT_FALSE(r2.get() ==
nullptr);
409 EXPECT_FALSE(was_destroyed1);
415 was_destroyed1 =
false;
416 was_destroyed2 =
false;
417 RefPtr<MySubclass> r1(MakeRefCounted<MySubclass>(
nullptr, &was_destroyed1));
418 RefPtr<MyClass> r2(MakeRefCounted<MyClass>(
nullptr, &was_destroyed2));
421 EXPECT_EQ(r1.get(), r2.get());
424 EXPECT_FALSE(was_destroyed1);
430 was_destroyed1 =
false;
431 was_destroyed2 =
false;
432 RefPtr<MySubclass> r1(MakeRefCounted<MySubclass>(
nullptr, &was_destroyed1));
433 RefPtr<MyClass> r2(MakeRefCounted<MyClass>(
nullptr, &was_destroyed2));
437 EXPECT_FALSE(r2.get() ==
nullptr);
440 EXPECT_FALSE(was_destroyed1);
446TEST(RefCountedTest, SelfAssignment) {
450 MyClass* created =
nullptr;
451 was_destroyed =
false;
457 RefPtr<MyClass> r(MakeRefCounted<MyClass>(
458 &created, &was_destroyed));
461 EXPECT_EQ(created, r.get());
462 EXPECT_FALSE(was_destroyed);
467 MyClass* created =
nullptr;
468 was_destroyed =
false;
469 RefPtr<MyClass> r(MakeRefCounted<MyClass>(&created, &was_destroyed));
472 EXPECT_EQ(created, r.get());
473 EXPECT_FALSE(was_destroyed);
478TEST(RefCountedTest, Swap) {
479 MyClass* created1 =
nullptr;
480 static bool was_destroyed1;
481 was_destroyed1 =
false;
482 RefPtr<MyClass> r1(MakeRefCounted<MyClass>(&created1, &was_destroyed1));
484 EXPECT_EQ(created1, r1.get());
486 MyClass* created2 =
nullptr;
487 static bool was_destroyed2;
488 was_destroyed2 =
false;
489 RefPtr<MyClass> r2(MakeRefCounted<MyClass>(&created2, &was_destroyed2));
491 EXPECT_EQ(created2, r2.get());
492 EXPECT_NE(created1, created2);
495 EXPECT_EQ(created2, r1.get());
496 EXPECT_EQ(created1, r2.get());
499TEST(RefCountedTest, GetAndDereferenceOperators) {
503 MyClass* created =
nullptr;
504 const RefPtr<MyClass> r(MakeRefCounted<MyClass>(&created,
nullptr));
505 MyClass* ptr = r.get();
506 EXPECT_EQ(created, ptr);
507 ptr = r.operator->();
508 EXPECT_EQ(created, ptr);
510 EXPECT_EQ(created, &ref);
514TEST(RefCountedTest, AddRefRelease) {
515 MyClass* created =
nullptr;
516 bool was_destroyed =
false;
518 RefPtr<MyClass> r(MakeRefCounted<MyClass>(&created, &was_destroyed));
519 EXPECT_EQ(created, r.get());
522 EXPECT_FALSE(was_destroyed);
528 MySubclass* created =
nullptr;
529 bool was_destroyed =
false;
530 RefPtr<MySubclass> r1(MakeRefCounted<MySubclass>(&created, &was_destroyed));
531 ASSERT_FALSE(was_destroyed);
533 created->AssertHasOneRef();
535 RefPtr<MySubclass> r2 = r1;
536 ASSERT_FALSE(was_destroyed);
537 EXPECT_FALSE(created->HasOneRef());
540 ASSERT_FALSE(was_destroyed);
541 created->AssertHasOneRef();
544 RefPtr<MyClass> r3 = r2;
545 EXPECT_FALSE(created->HasOneRef());
548 RefPtr<MyClass> r4(r3);
550 ASSERT_FALSE(was_destroyed);
551 EXPECT_FALSE(created->HasOneRef());
553 ASSERT_FALSE(was_destroyed);
555 created->AssertHasOneRef();
557 r1 = RefPtr<MySubclass>(
static_cast<MySubclass*
>(r3.get()));
558 ASSERT_FALSE(was_destroyed);
559 EXPECT_FALSE(created->HasOneRef());
561 ASSERT_FALSE(was_destroyed);
563 created->AssertHasOneRef();
565 EXPECT_EQ(created, r1.get());
571class MyPublicClass :
public RefCountedThreadSafe<MyPublicClass> {
574 MyPublicClass() : has_num_(
false), num_(0) {}
575 explicit MyPublicClass(
int num) : has_num_(
true), num_(num) {}
579 bool has_num()
const {
return has_num_; }
580 int num()
const {
return num_; }
591TEST(RefCountedTest, PublicCtorAndDtor) {
592 RefPtr<MyPublicClass> r1 = MakeRefCounted<MyPublicClass>();
594 EXPECT_FALSE(r1->has_num());
596 RefPtr<MyPublicClass> r2 = MakeRefCounted<MyPublicClass>(123);
599 EXPECT_EQ(123, r2->num());
600 EXPECT_NE(r1.get(), r2.get());
604 EXPECT_EQ(123, r1->num());
605 EXPECT_EQ(r1.get(), r2.get());
610 EXPECT_EQ(123, r1->num());
620TEST(RefCountedTest, DebugChecks) {
622 MyPublicClass*
p =
new MyPublicClass();
623 EXPECT_DEATH_IF_SUPPORTED(
624 delete p,
"!adoption_required_");
628 MyPublicClass*
p =
new MyPublicClass();
629 EXPECT_DEATH_IF_SUPPORTED(
630 RefPtr<MyPublicClass> r(
p),
"!adoption_required_");
634 RefPtr<MyPublicClass> r(MakeRefCounted<MyPublicClass>());
635 EXPECT_DEATH_IF_SUPPORTED(
delete r.get(),
"destruction_started_");
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
static uint32_t Mix(uint32_t hash)
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)
#define EXPECT_TRUE(handle)