1 // Copyright 2016 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "core/fxcrt/maybe_owned.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "core/fxcrt/unowned_ptr.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "third_party/base/ptr_util.h"
13
14 namespace fxcrt {
15 namespace {
16
17 class PseudoDeletable {
18 public:
PseudoDeletable(int id,int * count_location)19 explicit PseudoDeletable(int id, int* count_location)
20 : id_(id), count_location_(count_location) {}
~PseudoDeletable()21 ~PseudoDeletable() { ++(*count_location_); }
GetID() const22 int GetID() const { return id_; }
23
24 private:
25 int id_;
26 int* count_location_;
27 };
28
29 } // namespace
30
TEST(MaybeOwned,Null)31 TEST(MaybeOwned, Null) {
32 MaybeOwned<PseudoDeletable> ptr1;
33 EXPECT_FALSE(ptr1.IsOwned());
34 EXPECT_FALSE(ptr1);
35 EXPECT_EQ(nullptr, ptr1.Get());
36
37 MaybeOwned<PseudoDeletable> ptr2;
38 EXPECT_TRUE(ptr1 == ptr2);
39 EXPECT_FALSE(ptr1 != ptr2);
40 }
41
TEST(MaybeOwned,NotOwned)42 TEST(MaybeOwned, NotOwned) {
43 int delete_count = 0;
44 PseudoDeletable thing1(100, &delete_count);
45 {
46 MaybeOwned<PseudoDeletable> ptr(&thing1);
47 EXPECT_FALSE(ptr.IsOwned());
48 EXPECT_EQ(ptr.Get(), &thing1);
49 EXPECT_EQ(100, ptr->GetID());
50 EXPECT_TRUE(ptr == &thing1);
51 EXPECT_FALSE(ptr != &thing1);
52
53 MaybeOwned<PseudoDeletable> empty;
54 EXPECT_FALSE(ptr == empty);
55 EXPECT_TRUE(ptr != empty);
56 }
57 EXPECT_EQ(0, delete_count);
58
59 delete_count = 0;
60 PseudoDeletable thing2(200, &delete_count);
61 {
62 MaybeOwned<PseudoDeletable> ptr(&thing1);
63 ptr = &thing2;
64 EXPECT_FALSE(ptr.IsOwned());
65 EXPECT_EQ(ptr.Get(), &thing2);
66 EXPECT_EQ(200, ptr->GetID());
67 }
68 EXPECT_EQ(0, delete_count);
69
70 delete_count = 0;
71 int owned_delete_count = 0;
72 {
73 MaybeOwned<PseudoDeletable> ptr(&thing1);
74 EXPECT_EQ(100, ptr->GetID());
75 ptr = pdfium::MakeUnique<PseudoDeletable>(300, &owned_delete_count);
76 EXPECT_TRUE(ptr.IsOwned());
77 EXPECT_EQ(300, ptr->GetID());
78 }
79 EXPECT_EQ(0, delete_count);
80 EXPECT_EQ(1, owned_delete_count);
81 }
82
TEST(MaybeOwned,UnownedPtr)83 TEST(MaybeOwned, UnownedPtr) {
84 int delete_count = 0;
85 PseudoDeletable thing1(100, &delete_count);
86 PseudoDeletable thing2(200, &delete_count);
87 UnownedPtr<PseudoDeletable> unowned1(&thing1);
88 UnownedPtr<PseudoDeletable> unowned2(&thing2);
89 {
90 MaybeOwned<PseudoDeletable> ptr1(unowned1);
91 MaybeOwned<PseudoDeletable> ptr2(unowned2);
92 ptr2 = unowned1;
93 ptr1 = unowned2;
94 }
95 EXPECT_EQ(0, delete_count);
96 }
97
TEST(MaybeOwned,Owned)98 TEST(MaybeOwned, Owned) {
99 int delete_count = 0;
100 {
101 MaybeOwned<PseudoDeletable> ptr(
102 pdfium::MakeUnique<PseudoDeletable>(100, &delete_count));
103 EXPECT_TRUE(ptr.IsOwned());
104 EXPECT_EQ(100, ptr->GetID());
105
106 MaybeOwned<PseudoDeletable> empty;
107 EXPECT_FALSE(ptr == empty);
108 EXPECT_TRUE(ptr != empty);
109 }
110 EXPECT_EQ(1, delete_count);
111
112 delete_count = 0;
113 {
114 MaybeOwned<PseudoDeletable> ptr(
115 pdfium::MakeUnique<PseudoDeletable>(200, &delete_count));
116 ptr = pdfium::MakeUnique<PseudoDeletable>(300, &delete_count);
117 EXPECT_TRUE(ptr.IsOwned());
118 EXPECT_EQ(300, ptr->GetID());
119 EXPECT_EQ(1, delete_count);
120 }
121 EXPECT_EQ(2, delete_count);
122
123 delete_count = 0;
124 int unowned_delete_count = 0;
125 PseudoDeletable thing2(400, &unowned_delete_count);
126 {
127 MaybeOwned<PseudoDeletable> ptr(
128 pdfium::MakeUnique<PseudoDeletable>(500, &delete_count));
129 ptr = &thing2;
130 EXPECT_FALSE(ptr.IsOwned());
131 EXPECT_EQ(400, ptr->GetID());
132 EXPECT_EQ(1, delete_count);
133 EXPECT_EQ(0, unowned_delete_count);
134 }
135 EXPECT_EQ(1, delete_count);
136 EXPECT_EQ(0, unowned_delete_count);
137 }
138
TEST(MaybeOwned,Release)139 TEST(MaybeOwned, Release) {
140 int delete_count = 0;
141 {
142 std::unique_ptr<PseudoDeletable> stolen;
143 {
144 MaybeOwned<PseudoDeletable> ptr(
145 pdfium::MakeUnique<PseudoDeletable>(100, &delete_count));
146 EXPECT_TRUE(ptr.IsOwned());
147 stolen = ptr.Release();
148 EXPECT_FALSE(ptr.IsOwned());
149 EXPECT_EQ(ptr, stolen);
150 EXPECT_EQ(0, delete_count);
151 }
152 EXPECT_EQ(0, delete_count);
153 }
154 EXPECT_EQ(1, delete_count);
155 }
156
TEST(MaybeOwned,Move)157 TEST(MaybeOwned, Move) {
158 int delete_count = 0;
159 PseudoDeletable thing1(100, &delete_count);
160 {
161 MaybeOwned<PseudoDeletable> ptr1(&thing1);
162 MaybeOwned<PseudoDeletable> ptr2(
163 pdfium::MakeUnique<PseudoDeletable>(200, &delete_count));
164 EXPECT_FALSE(ptr1.IsOwned());
165 EXPECT_TRUE(ptr2.IsOwned());
166
167 MaybeOwned<PseudoDeletable> ptr3(std::move(ptr1));
168 MaybeOwned<PseudoDeletable> ptr4(std::move(ptr2));
169 EXPECT_FALSE(ptr1.IsOwned());
170 EXPECT_FALSE(ptr2.IsOwned());
171 EXPECT_FALSE(ptr3.IsOwned());
172 EXPECT_TRUE(ptr4.IsOwned());
173 EXPECT_EQ(0, delete_count);
174 EXPECT_EQ(nullptr, ptr1.Get());
175 EXPECT_EQ(nullptr, ptr2.Get());
176 EXPECT_EQ(100, ptr3->GetID());
177 EXPECT_EQ(200, ptr4->GetID());
178
179 MaybeOwned<PseudoDeletable> ptr5;
180 MaybeOwned<PseudoDeletable> ptr6;
181 ptr5 = std::move(ptr3);
182 ptr6 = std::move(ptr4);
183 EXPECT_FALSE(ptr3.IsOwned());
184 EXPECT_FALSE(ptr4.IsOwned());
185 EXPECT_FALSE(ptr5.IsOwned());
186 EXPECT_TRUE(ptr6.IsOwned());
187 EXPECT_EQ(0, delete_count);
188 EXPECT_EQ(nullptr, ptr3.Get());
189 EXPECT_EQ(nullptr, ptr4.Get());
190 EXPECT_EQ(100, ptr5->GetID());
191 EXPECT_EQ(200, ptr6->GetID());
192 }
193 EXPECT_EQ(1, delete_count);
194 }
195
196 } // namespace fxcrt
197