Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(280)

Side by Side Diff: third_party/base/nonstd_unique_ptr_unittest.cpp

Issue 1351383004: Change nonstd::unique_ptr to take a custom deleter. (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: address comments Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 <sstream>
6
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "macros.h"
9 #include "nonstd_unique_ptr.h"
10
11 using nonstd::unique_ptr;
12
13 namespace {
14
15 // Used to test depth subtyping.
16 class ConDecLoggerParent {
17 public:
18 virtual ~ConDecLoggerParent() {}
19
20 virtual void SetPtr(int* ptr) = 0;
21
22 virtual int SomeMeth(int x) const = 0;
23 };
24
25 class ConDecLogger : public ConDecLoggerParent {
Tom Sepez 2015/09/22 17:36:20 Actually, I want to steal this file to test nonstd
Lei Zhang 2015/09/23 00:38:56 All yours.
26 public:
27 ConDecLogger() : ptr_(nullptr) {}
28 explicit ConDecLogger(int* ptr) { SetPtr(ptr); }
29 ~ConDecLogger() override { --*ptr_; }
Jeffrey Yasskin 2015/09/19 00:00:48 Is "Dec" an abbreviation for "Destruction"?
Lei Zhang 2015/09/23 00:38:56 Tom renamed this in his CL.
30
31 void SetPtr(int* ptr) override {
32 ptr_ = ptr;
33 ++*ptr_;
34 }
35
36 int SomeMeth(int x) const override { return x; }
37
38 private:
39 int* ptr_;
40
41 // Disallow evil constructors.
42 ConDecLogger(const ConDecLogger&) = delete;
43 void operator=(const ConDecLogger&) = delete;
44 };
45
46 struct CountingDeleter {
47 explicit CountingDeleter(int* count) : count_(count) {}
48 inline void operator()(double* ptr) const { (*count_)++; }
49 int* count_;
50 };
51
52 // Do not delete this function! It's existence is to test that you can
53 // return a temporarily constructed version of the scoper.
54 unique_ptr<ConDecLogger> TestReturnOfType(int* constructed) {
55 return unique_ptr<ConDecLogger>(new ConDecLogger(constructed));
56 }
57
58 } // namespace
59
60 TEST(UniquePtrTest, UniquePtr) {
61 int constructed = 0;
62
63 // Ensure size of unique_ptr<> doesn't increase unexpectedly.
64 static_assert(sizeof(int*) >= sizeof(unique_ptr<int>),
65 "unique_ptr_larger_than_raw_ptr");
66
67 {
68 unique_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
69 EXPECT_EQ(1, constructed);
70 EXPECT_TRUE(scoper.get());
71
72 EXPECT_EQ(10, scoper->SomeMeth(10));
73 EXPECT_EQ(10, scoper.get()->SomeMeth(10));
74 EXPECT_EQ(10, (*scoper).SomeMeth(10));
75 }
76 EXPECT_EQ(0, constructed);
77
78 // Test reset() and release()
79 {
80 unique_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
81 EXPECT_EQ(1, constructed);
82 EXPECT_TRUE(scoper.get());
83
84 scoper.reset(new ConDecLogger(&constructed));
85 EXPECT_EQ(1, constructed);
86 EXPECT_TRUE(scoper.get());
87
88 scoper.reset();
89 EXPECT_EQ(0, constructed);
90 EXPECT_FALSE(scoper.get());
91
92 scoper.reset(new ConDecLogger(&constructed));
93 EXPECT_EQ(1, constructed);
94 EXPECT_TRUE(scoper.get());
95
96 ConDecLogger* take = scoper.release();
97 EXPECT_EQ(1, constructed);
98 EXPECT_FALSE(scoper.get());
99 delete take;
100 EXPECT_EQ(0, constructed);
101
102 scoper.reset(new ConDecLogger(&constructed));
103 EXPECT_EQ(1, constructed);
104 EXPECT_TRUE(scoper.get());
105 }
106 EXPECT_EQ(0, constructed);
107
108 // Test swap(), == and !=
109 {
110 unique_ptr<ConDecLogger> scoper1;
111 unique_ptr<ConDecLogger> scoper2;
112 EXPECT_TRUE(scoper1 == scoper2.get());
113 EXPECT_FALSE(scoper1 != scoper2.get());
114
115 ConDecLogger* logger = new ConDecLogger(&constructed);
116 scoper1.reset(logger);
117 EXPECT_EQ(logger, scoper1.get());
118 EXPECT_FALSE(scoper2.get());
119 EXPECT_FALSE(scoper1 == scoper2.get());
120 EXPECT_TRUE(scoper1 != scoper2.get());
121
122 scoper2.swap(scoper1);
123 EXPECT_EQ(logger, scoper2.get());
124 EXPECT_FALSE(scoper1.get());
125 EXPECT_FALSE(scoper1 == scoper2.get());
126 EXPECT_TRUE(scoper1 != scoper2.get());
127 }
128 EXPECT_EQ(0, constructed);
129 }
130
131 TEST(UniquePtrTest, UniquePtrWithArray) {
132 static const int kNumLoggers = 12;
133
134 int constructed = 0;
135
136 {
137 unique_ptr<ConDecLogger[]> scoper(new ConDecLogger[kNumLoggers]);
138 EXPECT_TRUE(scoper);
139 EXPECT_EQ(&scoper[0], scoper.get());
140 for (int i = 0; i < kNumLoggers; ++i) {
141 scoper[i].SetPtr(&constructed);
142 }
143 EXPECT_EQ(12, constructed);
144
145 EXPECT_EQ(10, scoper.get()->SomeMeth(10));
146 EXPECT_EQ(10, scoper[2].SomeMeth(10));
147 }
148 EXPECT_EQ(0, constructed);
149
150 // Test reset() and release()
151 {
152 unique_ptr<ConDecLogger[]> scoper;
153 EXPECT_FALSE(scoper.get());
154 EXPECT_FALSE(scoper.release());
155 EXPECT_FALSE(scoper.get());
156 scoper.reset();
157 EXPECT_FALSE(scoper.get());
158
159 scoper.reset(new ConDecLogger[kNumLoggers]);
160 for (int i = 0; i < kNumLoggers; ++i) {
161 scoper[i].SetPtr(&constructed);
162 }
163 EXPECT_EQ(12, constructed);
164 scoper.reset();
165 EXPECT_EQ(0, constructed);
166
167 scoper.reset(new ConDecLogger[kNumLoggers]);
168 for (int i = 0; i < kNumLoggers; ++i) {
169 scoper[i].SetPtr(&constructed);
170 }
171 EXPECT_EQ(12, constructed);
172 ConDecLogger* ptr = scoper.release();
173 EXPECT_EQ(12, constructed);
174 delete[] ptr;
175 EXPECT_EQ(0, constructed);
176 }
177 EXPECT_EQ(0, constructed);
178
179 // Test swap(), ==, !=, and type-safe Boolean.
180 {
181 unique_ptr<ConDecLogger[]> scoper1;
182 unique_ptr<ConDecLogger[]> scoper2;
183 EXPECT_TRUE(scoper1 == scoper2.get());
184 EXPECT_FALSE(scoper1 != scoper2.get());
185
186 ConDecLogger* loggers = new ConDecLogger[kNumLoggers];
187 for (int i = 0; i < kNumLoggers; ++i) {
188 loggers[i].SetPtr(&constructed);
189 }
190 scoper1.reset(loggers);
191 EXPECT_TRUE(scoper1);
192 EXPECT_EQ(loggers, scoper1.get());
193 EXPECT_FALSE(scoper2);
194 EXPECT_FALSE(scoper2.get());
195 EXPECT_FALSE(scoper1 == scoper2.get());
196 EXPECT_TRUE(scoper1 != scoper2.get());
197
198 scoper2.swap(scoper1);
199 EXPECT_EQ(loggers, scoper2.get());
200 EXPECT_FALSE(scoper1.get());
201 EXPECT_FALSE(scoper1 == scoper2.get());
202 EXPECT_TRUE(scoper1 != scoper2.get());
203 }
204 EXPECT_EQ(0, constructed);
205 }
206
207 TEST(UniquePtrTest, ReturnTypeBehavior) {
208 int constructed = 0;
209
210 // Test that we can return a unique_ptr.
211 {
212 ConDecLogger* logger = new ConDecLogger(&constructed);
213 unique_ptr<ConDecLogger> scoper(logger);
214 EXPECT_EQ(1, constructed);
215 }
216 EXPECT_EQ(0, constructed);
217
218 // Test uncaught return type not leak.
219 {
220 ConDecLogger* logger = new ConDecLogger(&constructed);
221 unique_ptr<ConDecLogger> scoper(logger);
222 EXPECT_EQ(1, constructed);
223 }
224 EXPECT_EQ(0, constructed);
225
226 // Call TestReturnOfType() so the compiler doesn't warn for an unused
227 // function.
228 { TestReturnOfType(&constructed); }
229 EXPECT_EQ(0, constructed);
230 }
231
232 TEST(UniquePtrTest, CustomDeleter) {
233 double dummy_value; // Custom deleter never touches this value.
234 int deletes = 0;
235 int alternate_deletes = 0;
236
237 // Normal delete support.
238 {
239 deletes = 0;
240 unique_ptr<double, CountingDeleter> scoper(&dummy_value,
241 CountingDeleter(&deletes));
242 EXPECT_EQ(0, deletes);
243 EXPECT_TRUE(scoper.get());
244 }
245 EXPECT_EQ(1, deletes);
246
247 // Test reset() and release().
248 deletes = 0;
249 {
250 unique_ptr<double, CountingDeleter> scoper(nullptr,
251 CountingDeleter(&deletes));
252 EXPECT_FALSE(scoper.get());
253 EXPECT_FALSE(scoper.release());
254 EXPECT_FALSE(scoper.get());
255 scoper.reset();
256 EXPECT_FALSE(scoper.get());
257 EXPECT_EQ(0, deletes);
258
259 scoper.reset(&dummy_value);
260 scoper.reset();
261 EXPECT_EQ(1, deletes);
262
263 scoper.reset(&dummy_value);
264 EXPECT_EQ(&dummy_value, scoper.release());
265 }
266 EXPECT_EQ(1, deletes);
267
268 // Test get_deleter().
269 deletes = 0;
270 alternate_deletes = 0;
271 {
272 unique_ptr<double, CountingDeleter> scoper(&dummy_value,
273 CountingDeleter(&deletes));
274 // Call deleter manually.
275 EXPECT_EQ(0, deletes);
276 scoper.get_deleter()(&dummy_value);
277 EXPECT_EQ(1, deletes);
278
279 // Deleter is still there after reset.
280 scoper.reset();
281 EXPECT_EQ(2, deletes);
282 scoper.get_deleter()(&dummy_value);
283 EXPECT_EQ(3, deletes);
284
285 // Deleter can be assigned into (matches C++11 unique_ptr<> spec).
286 scoper.get_deleter() = CountingDeleter(&alternate_deletes);
287 scoper.reset(&dummy_value);
288 EXPECT_EQ(0, alternate_deletes);
289 }
290 EXPECT_EQ(3, deletes);
291 EXPECT_EQ(1, alternate_deletes);
292
293 // Test swap(), ==, !=, and type-safe Boolean.
294 {
295 unique_ptr<double, CountingDeleter> scoper1(nullptr,
296 CountingDeleter(&deletes));
297 unique_ptr<double, CountingDeleter> scoper2(nullptr,
298 CountingDeleter(&deletes));
299 EXPECT_TRUE(scoper1 == scoper2.get());
300 EXPECT_FALSE(scoper1 != scoper2.get());
301
302 scoper1.reset(&dummy_value);
303 EXPECT_TRUE(scoper1);
304 EXPECT_EQ(&dummy_value, scoper1.get());
305 EXPECT_FALSE(scoper2);
306 EXPECT_FALSE(scoper2.get());
307 EXPECT_FALSE(scoper1 == scoper2.get());
308 EXPECT_TRUE(scoper1 != scoper2.get());
309
310 scoper2.swap(scoper1);
311 EXPECT_EQ(&dummy_value, scoper2.get());
312 EXPECT_FALSE(scoper1.get());
313 EXPECT_FALSE(scoper1 == scoper2.get());
314 EXPECT_TRUE(scoper1 != scoper2.get());
315 }
316 }
317
318 unique_ptr<int> NullIntReturn() {
319 return nullptr;
320 }
321
322 TEST(UniquePtrTest, Nullptr) {
323 unique_ptr<int> scoper1(nullptr);
324 unique_ptr<int> scoper2(new int);
325 scoper2 = nullptr;
326 unique_ptr<int> scoper3(NullIntReturn());
327 unique_ptr<int> scoper4 = NullIntReturn();
328 EXPECT_EQ(nullptr, scoper1.get());
329 EXPECT_EQ(nullptr, scoper2.get());
330 EXPECT_EQ(nullptr, scoper3.get());
331 EXPECT_EQ(nullptr, scoper4.get());
332 }
333
334 unique_ptr<int[]> NullIntArrayReturn() {
335 return nullptr;
336 }
337
338 TEST(UniquePtrTest, NullptrArray) {
339 unique_ptr<int[]> scoper1(nullptr);
340 unique_ptr<int[]> scoper2(new int[3]);
341 scoper2 = nullptr;
342 unique_ptr<int[]> scoper3(NullIntArrayReturn());
343 unique_ptr<int[]> scoper4 = NullIntArrayReturn();
344 EXPECT_EQ(nullptr, scoper1.get());
345 EXPECT_EQ(nullptr, scoper2.get());
346 EXPECT_EQ(nullptr, scoper3.get());
347 EXPECT_EQ(nullptr, scoper4.get());
348 }
349
350 // Logging a unique_ptr<T> to an ostream shouldn't convert it to a boolean
351 // value first.
352 TEST(ScopedPtrTest, LoggingDoesntConvertToBoolean) {
353 unique_ptr<int> x(new int);
354 std::stringstream s1;
355 s1 << x;
356
357 std::stringstream s2;
358 s2 << x.get();
359
360 EXPECT_EQ(s2.str(), s1.str());
361 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698