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/cfx_maybe_owned.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "core/fxcrt/fx_memory.h"
11 #include "testing/fx_string_testhelpers.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/base/ptr_util.h"
14
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(fxcrt,MaybeOwnedNull)31 TEST(fxcrt, MaybeOwnedNull) {
32 CFX_MaybeOwned<PseudoDeletable> ptr1;
33 EXPECT_FALSE(ptr1.IsOwned());
34 EXPECT_FALSE(ptr1);
35 EXPECT_EQ(nullptr, ptr1.Get());
36
37 CFX_MaybeOwned<PseudoDeletable> ptr2;
38 EXPECT_TRUE(ptr1 == ptr2);
39 EXPECT_FALSE(ptr1 != ptr2);
40 }
41
TEST(fxcrt,MaybeOwnedNotOwned)42 TEST(fxcrt, MaybeOwnedNotOwned) {
43 int delete_count = 0;
44 PseudoDeletable thing1(100, &delete_count);
45 {
46 CFX_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 CFX_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 CFX_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 CFX_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(fxcrt,MaybeOwnedOwned)83 TEST(fxcrt, MaybeOwnedOwned) {
84 int delete_count = 0;
85 {
86 CFX_MaybeOwned<PseudoDeletable> ptr(
87 pdfium::MakeUnique<PseudoDeletable>(100, &delete_count));
88 EXPECT_TRUE(ptr.IsOwned());
89 EXPECT_EQ(100, ptr->GetID());
90
91 CFX_MaybeOwned<PseudoDeletable> empty;
92 EXPECT_FALSE(ptr == empty);
93 EXPECT_TRUE(ptr != empty);
94 }
95 EXPECT_EQ(1, delete_count);
96
97 delete_count = 0;
98 {
99 CFX_MaybeOwned<PseudoDeletable> ptr(
100 pdfium::MakeUnique<PseudoDeletable>(200, &delete_count));
101 ptr = pdfium::MakeUnique<PseudoDeletable>(300, &delete_count);
102 EXPECT_TRUE(ptr.IsOwned());
103 EXPECT_EQ(300, ptr->GetID());
104 EXPECT_EQ(1, delete_count);
105 }
106 EXPECT_EQ(2, delete_count);
107
108 delete_count = 0;
109 int unowned_delete_count = 0;
110 PseudoDeletable thing2(400, &unowned_delete_count);
111 {
112 CFX_MaybeOwned<PseudoDeletable> ptr(
113 pdfium::MakeUnique<PseudoDeletable>(500, &delete_count));
114 ptr = &thing2;
115 EXPECT_FALSE(ptr.IsOwned());
116 EXPECT_EQ(400, ptr->GetID());
117 EXPECT_EQ(1, delete_count);
118 EXPECT_EQ(0, unowned_delete_count);
119 }
120 EXPECT_EQ(1, delete_count);
121 EXPECT_EQ(0, unowned_delete_count);
122 }
123
TEST(fxcrt,MaybeOwnedRelease)124 TEST(fxcrt, MaybeOwnedRelease) {
125 int delete_count = 0;
126 {
127 std::unique_ptr<PseudoDeletable> stolen;
128 {
129 CFX_MaybeOwned<PseudoDeletable> ptr(
130 pdfium::MakeUnique<PseudoDeletable>(100, &delete_count));
131 EXPECT_TRUE(ptr.IsOwned());
132 stolen = ptr.Release();
133 EXPECT_FALSE(ptr.IsOwned());
134 EXPECT_EQ(ptr, stolen);
135 EXPECT_EQ(0, delete_count);
136 }
137 EXPECT_EQ(0, delete_count);
138 }
139 EXPECT_EQ(1, delete_count);
140 }
141
TEST(fxcrt,MaybeOwnedMove)142 TEST(fxcrt, MaybeOwnedMove) {
143 int delete_count = 0;
144 PseudoDeletable thing1(100, &delete_count);
145 {
146 CFX_MaybeOwned<PseudoDeletable> ptr1(&thing1);
147 CFX_MaybeOwned<PseudoDeletable> ptr2(
148 pdfium::MakeUnique<PseudoDeletable>(200, &delete_count));
149 EXPECT_FALSE(ptr1.IsOwned());
150 EXPECT_TRUE(ptr2.IsOwned());
151
152 CFX_MaybeOwned<PseudoDeletable> ptr3(std::move(ptr1));
153 CFX_MaybeOwned<PseudoDeletable> ptr4(std::move(ptr2));
154 EXPECT_FALSE(ptr1.IsOwned());
155 EXPECT_FALSE(ptr2.IsOwned());
156 EXPECT_FALSE(ptr3.IsOwned());
157 EXPECT_TRUE(ptr4.IsOwned());
158 EXPECT_EQ(0, delete_count);
159 EXPECT_EQ(nullptr, ptr1.Get());
160 EXPECT_EQ(nullptr, ptr2.Get());
161 EXPECT_EQ(100, ptr3->GetID());
162 EXPECT_EQ(200, ptr4->GetID());
163
164 CFX_MaybeOwned<PseudoDeletable> ptr5;
165 CFX_MaybeOwned<PseudoDeletable> ptr6;
166 ptr5 = std::move(ptr3);
167 ptr6 = std::move(ptr4);
168 EXPECT_FALSE(ptr3.IsOwned());
169 EXPECT_FALSE(ptr4.IsOwned());
170 EXPECT_FALSE(ptr5.IsOwned());
171 EXPECT_TRUE(ptr6.IsOwned());
172 EXPECT_EQ(0, delete_count);
173 EXPECT_EQ(nullptr, ptr3.Get());
174 EXPECT_EQ(nullptr, ptr4.Get());
175 EXPECT_EQ(100, ptr5->GetID());
176 EXPECT_EQ(200, ptr6->GetID());
177 }
178 EXPECT_EQ(1, delete_count);
179 }
180