OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/memory/ref_counted.h" | 5 #include "base/memory/ref_counted.h" |
6 | 6 |
7 #include "base/test/opaque_ref_counted.h" | 7 #include "base/test/opaque_ref_counted.h" |
8 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
9 | 9 |
10 namespace { | 10 namespace { |
(...skipping 22 matching lines...) Expand all Loading... | |
33 EXPECT_EQ(*pptr, ptr_); | 33 EXPECT_EQ(*pptr, ptr_); |
34 } | 34 } |
35 }; | 35 }; |
36 | 36 |
37 class ScopedRefPtrToSelf : public base::RefCounted<ScopedRefPtrToSelf> { | 37 class ScopedRefPtrToSelf : public base::RefCounted<ScopedRefPtrToSelf> { |
38 public: | 38 public: |
39 ScopedRefPtrToSelf() : self_ptr_(this) {} | 39 ScopedRefPtrToSelf() : self_ptr_(this) {} |
40 | 40 |
41 static bool was_destroyed() { return was_destroyed_; } | 41 static bool was_destroyed() { return was_destroyed_; } |
42 | 42 |
43 void SelfDestruct() { self_ptr_ = NULL; } | 43 static void reset_was_destroyed() { was_destroyed_ = false; } |
44 | |
45 scoped_refptr<ScopedRefPtrToSelf> self_ptr_; | |
44 | 46 |
45 private: | 47 private: |
46 friend class base::RefCounted<ScopedRefPtrToSelf>; | 48 friend class base::RefCounted<ScopedRefPtrToSelf>; |
47 ~ScopedRefPtrToSelf() { was_destroyed_ = true; } | 49 ~ScopedRefPtrToSelf() { was_destroyed_ = true; } |
48 | 50 |
49 static bool was_destroyed_; | 51 static bool was_destroyed_; |
50 | |
51 scoped_refptr<ScopedRefPtrToSelf> self_ptr_; | |
52 }; | 52 }; |
53 | 53 |
54 bool ScopedRefPtrToSelf::was_destroyed_ = false; | 54 bool ScopedRefPtrToSelf::was_destroyed_ = false; |
55 | 55 |
56 class ScopedRefPtrCountBase : public base::RefCounted<ScopedRefPtrCountBase> { | |
57 public: | |
58 ScopedRefPtrCountBase() { ++constructor_count_; } | |
59 | |
60 static int constructor_count() { return constructor_count_; } | |
61 | |
62 static int destructor_count() { return destructor_count_; } | |
63 | |
64 static void reset_count() { | |
65 constructor_count_ = 0; | |
66 destructor_count_ = 0; | |
67 } | |
68 | |
69 protected: | |
70 virtual ~ScopedRefPtrCountBase() { ++destructor_count_; } | |
71 | |
72 private: | |
73 friend class base::RefCounted<ScopedRefPtrCountBase>; | |
74 | |
75 static int constructor_count_; | |
76 static int destructor_count_; | |
77 }; | |
78 | |
79 int ScopedRefPtrCountBase::constructor_count_ = 0; | |
80 int ScopedRefPtrCountBase::destructor_count_ = 0; | |
81 | |
82 class ScopedRefPtrCountDerived : public ScopedRefPtrCountBase { | |
83 public: | |
84 ScopedRefPtrCountDerived() { ++constructor_count_; } | |
85 | |
86 static int constructor_count() { return constructor_count_; } | |
87 | |
88 static int destructor_count() { return destructor_count_; } | |
89 | |
90 static void reset_count() { | |
91 constructor_count_ = 0; | |
92 destructor_count_ = 0; | |
93 } | |
94 | |
95 protected: | |
96 ~ScopedRefPtrCountDerived() override { ++destructor_count_; } | |
97 | |
98 private: | |
99 friend class base::RefCounted<ScopedRefPtrCountDerived>; | |
100 | |
101 static int constructor_count_; | |
102 static int destructor_count_; | |
103 }; | |
104 | |
105 int ScopedRefPtrCountDerived::constructor_count_ = 0; | |
106 int ScopedRefPtrCountDerived::destructor_count_ = 0; | |
107 | |
56 } // end namespace | 108 } // end namespace |
57 | 109 |
58 TEST(RefCountedUnitTest, TestSelfAssignment) { | 110 TEST(RefCountedUnitTest, TestSelfAssignment) { |
59 SelfAssign* p = new SelfAssign; | 111 SelfAssign* p = new SelfAssign; |
60 scoped_refptr<SelfAssign> var(p); | 112 scoped_refptr<SelfAssign> var(p); |
61 var = var; | 113 var = var; |
62 EXPECT_EQ(var.get(), p); | 114 EXPECT_EQ(var.get(), p); |
63 } | 115 } |
64 | 116 |
65 TEST(RefCountedUnitTest, ScopedRefPtrMemberAccess) { | 117 TEST(RefCountedUnitTest, ScopedRefPtrMemberAccess) { |
66 CheckDerivedMemberAccess check; | 118 CheckDerivedMemberAccess check; |
67 } | 119 } |
68 | 120 |
69 TEST(RefCountedUnitTest, ScopedRefPtrToSelf) { | 121 TEST(RefCountedUnitTest, ScopedRefPtrToSelfPointerAssignment) { |
122 ScopedRefPtrToSelf::reset_was_destroyed(); | |
123 | |
70 ScopedRefPtrToSelf* check = new ScopedRefPtrToSelf(); | 124 ScopedRefPtrToSelf* check = new ScopedRefPtrToSelf(); |
71 EXPECT_FALSE(ScopedRefPtrToSelf::was_destroyed()); | 125 EXPECT_FALSE(ScopedRefPtrToSelf::was_destroyed()); |
72 check->SelfDestruct(); | 126 check->self_ptr_ = nullptr; |
73 EXPECT_TRUE(ScopedRefPtrToSelf::was_destroyed()); | 127 EXPECT_TRUE(ScopedRefPtrToSelf::was_destroyed()); |
74 } | 128 } |
75 | 129 |
130 TEST(RefCountedUnitTest, ScopedRefPtrToSelfMoveAssignment) { | |
131 ScopedRefPtrToSelf::reset_was_destroyed(); | |
132 | |
133 ScopedRefPtrToSelf* check = new ScopedRefPtrToSelf(); | |
134 EXPECT_FALSE(ScopedRefPtrToSelf::was_destroyed()); | |
135 check->self_ptr_ = scoped_refptr<ScopedRefPtrToSelf>(); | |
danakj
2015/04/13 16:13:23
can you leave a comment explaining that if operato
Kibeom Kim (inactive)
2015/04/13 18:37:58
Done.
| |
136 EXPECT_TRUE(ScopedRefPtrToSelf::was_destroyed()); | |
137 } | |
138 | |
76 TEST(RefCountedUnitTest, ScopedRefPtrToOpaque) { | 139 TEST(RefCountedUnitTest, ScopedRefPtrToOpaque) { |
77 scoped_refptr<base::OpaqueRefCounted> p = base::MakeOpaqueRefCounted(); | 140 scoped_refptr<base::OpaqueRefCounted> p = base::MakeOpaqueRefCounted(); |
78 base::TestOpaqueRefCounted(p); | 141 base::TestOpaqueRefCounted(p); |
79 | 142 |
80 scoped_refptr<base::OpaqueRefCounted> q; | 143 scoped_refptr<base::OpaqueRefCounted> q; |
81 q = p; | 144 q = p; |
82 base::TestOpaqueRefCounted(p); | 145 base::TestOpaqueRefCounted(p); |
83 base::TestOpaqueRefCounted(q); | 146 base::TestOpaqueRefCounted(q); |
84 } | 147 } |
85 | 148 |
(...skipping 20 matching lines...) Expand all Loading... | |
106 scoped_refptr<SelfAssign> p2; | 169 scoped_refptr<SelfAssign> p2; |
107 | 170 |
108 EXPECT_NE(p1, p2); | 171 EXPECT_NE(p1, p2); |
109 EXPECT_NE(p2, p1); | 172 EXPECT_NE(p2, p1); |
110 | 173 |
111 p2 = p1; | 174 p2 = p1; |
112 | 175 |
113 EXPECT_EQ(p1, p2); | 176 EXPECT_EQ(p1, p2); |
114 EXPECT_EQ(p2, p1); | 177 EXPECT_EQ(p2, p1); |
115 } | 178 } |
179 | |
180 TEST(RefCountedUnitTest, SelfMoveAssignment) { | |
181 ScopedRefPtrCountBase::reset_count(); | |
182 | |
183 { | |
184 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase(); | |
185 scoped_refptr<ScopedRefPtrCountBase> p(raw); | |
186 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
187 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
188 | |
189 p = p.Pass(); | |
190 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
191 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
192 EXPECT_EQ(raw, p.get()); | |
193 | |
194 // p goes out of scope. | |
195 } | |
196 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
197 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count()); | |
198 } | |
199 | |
200 TEST(RefCountedUnitTest, MoveAssignment1) { | |
201 ScopedRefPtrCountBase::reset_count(); | |
202 | |
203 { | |
204 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase(); | |
205 scoped_refptr<ScopedRefPtrCountBase> p1(raw); | |
206 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
207 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
208 | |
209 { | |
210 scoped_refptr<ScopedRefPtrCountBase> p2; | |
211 | |
212 p2 = p1.Pass(); | |
213 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
214 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
215 EXPECT_EQ(nullptr, p1.get()); | |
216 EXPECT_EQ(raw, p2.get()); | |
217 | |
218 // p2 goes out of scope. | |
219 } | |
220 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
221 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count()); | |
222 | |
223 // p1 goes out of scope. | |
224 } | |
225 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
226 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count()); | |
227 } | |
228 | |
229 TEST(RefCountedUnitTest, MoveAssignment2) { | |
230 ScopedRefPtrCountBase::reset_count(); | |
231 | |
232 { | |
233 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase(); | |
234 scoped_refptr<ScopedRefPtrCountBase> p1; | |
235 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
236 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
237 | |
238 { | |
239 scoped_refptr<ScopedRefPtrCountBase> p2(raw); | |
240 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
241 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
242 | |
243 p1 = p2.Pass(); | |
244 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
245 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
246 EXPECT_EQ(raw, p1.get()); | |
247 EXPECT_EQ(nullptr, p2.get()); | |
248 | |
249 // p2 goes out of scope. | |
250 } | |
251 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
252 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
253 | |
254 // p1 goes out of scope. | |
255 } | |
256 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
257 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count()); | |
258 } | |
259 | |
260 TEST(RefCountedUnitTest, MoveAssignmentSameInstance1) { | |
261 ScopedRefPtrCountBase::reset_count(); | |
262 | |
263 { | |
264 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase(); | |
265 scoped_refptr<ScopedRefPtrCountBase> p1(raw); | |
266 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
267 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
268 | |
269 { | |
270 scoped_refptr<ScopedRefPtrCountBase> p2(p1); | |
271 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
272 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
273 | |
274 p1 = p2.Pass(); | |
275 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
276 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
277 EXPECT_EQ(raw, p1.get()); | |
278 EXPECT_EQ(nullptr, p2.get()); | |
279 | |
280 // p2 goes out of scope. | |
281 } | |
282 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
283 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
284 | |
285 // p1 goes out of scope. | |
286 } | |
287 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
288 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count()); | |
289 } | |
290 | |
291 TEST(RefCountedUnitTest, MoveAssignmentSameInstance2) { | |
292 ScopedRefPtrCountBase::reset_count(); | |
293 | |
294 { | |
295 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase(); | |
296 scoped_refptr<ScopedRefPtrCountBase> p1(raw); | |
297 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
298 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
299 | |
300 { | |
301 scoped_refptr<ScopedRefPtrCountBase> p2(p1); | |
302 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
303 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
304 | |
305 p2 = p1.Pass(); | |
306 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
307 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
308 EXPECT_EQ(nullptr, p1.get()); | |
309 EXPECT_EQ(raw, p2.get()); | |
310 | |
311 // p2 goes out of scope. | |
312 } | |
313 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
314 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count()); | |
315 | |
316 // p1 goes out of scope. | |
317 } | |
318 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
319 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count()); | |
320 } | |
321 | |
322 TEST(RefCountedUnitTest, MoveAssignmentDifferentInstances) { | |
323 ScopedRefPtrCountBase::reset_count(); | |
324 | |
325 { | |
326 ScopedRefPtrCountBase *raw1 = new ScopedRefPtrCountBase(); | |
327 scoped_refptr<ScopedRefPtrCountBase> p1(raw1); | |
328 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
329 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
330 | |
331 { | |
332 ScopedRefPtrCountBase *raw2 = new ScopedRefPtrCountBase(); | |
333 scoped_refptr<ScopedRefPtrCountBase> p2(raw2); | |
334 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count()); | |
335 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
336 | |
337 p1 = p2.Pass(); | |
338 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count()); | |
339 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count()); | |
340 EXPECT_EQ(raw2, p1.get()); | |
341 EXPECT_EQ(nullptr, p2.get()); | |
342 | |
343 // p2 goes out of scope. | |
344 } | |
345 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count()); | |
346 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count()); | |
347 | |
348 // p1 goes out of scope. | |
349 } | |
350 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count()); | |
351 EXPECT_EQ(2, ScopedRefPtrCountBase::destructor_count()); | |
352 } | |
353 | |
354 TEST(RefCountedUnitTest, MoveAssignmentDerived) { | |
355 ScopedRefPtrCountBase::reset_count(); | |
356 ScopedRefPtrCountDerived::reset_count(); | |
357 | |
358 { | |
359 ScopedRefPtrCountBase *raw1 = new ScopedRefPtrCountBase(); | |
360 scoped_refptr<ScopedRefPtrCountBase> p1(raw1); | |
361 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
362 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
363 EXPECT_EQ(0, ScopedRefPtrCountDerived::constructor_count()); | |
364 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count()); | |
365 | |
366 { | |
367 ScopedRefPtrCountDerived *raw2 = new ScopedRefPtrCountDerived(); | |
368 scoped_refptr<ScopedRefPtrCountDerived> p2(raw2); | |
369 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count()); | |
370 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
371 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count()); | |
372 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count()); | |
373 | |
374 p1 = p2.Pass(); | |
375 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count()); | |
376 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count()); | |
377 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count()); | |
378 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count()); | |
379 EXPECT_EQ(raw2, p1.get()); | |
380 EXPECT_EQ(nullptr, p2.get()); | |
381 | |
382 // p2 goes out of scope. | |
383 } | |
384 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count()); | |
385 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count()); | |
386 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count()); | |
387 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count()); | |
388 | |
389 // p1 goes out of scope. | |
390 } | |
391 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count()); | |
392 EXPECT_EQ(2, ScopedRefPtrCountBase::destructor_count()); | |
393 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count()); | |
394 EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count()); | |
395 } | |
396 | |
397 TEST(RefCountedUnitTest, MoveConstructor) { | |
398 ScopedRefPtrCountBase::reset_count(); | |
399 | |
400 { | |
401 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase(); | |
402 scoped_refptr<ScopedRefPtrCountBase> p1(raw); | |
403 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
404 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
405 | |
406 { | |
407 scoped_refptr<ScopedRefPtrCountBase> p2(p1.Pass()); | |
408 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
409 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
410 EXPECT_EQ(nullptr, p1.get()); | |
411 EXPECT_EQ(raw, p2.get()); | |
412 | |
413 // p2 goes out of scope. | |
414 } | |
415 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
416 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count()); | |
417 | |
418 // p1 goes out of scope. | |
419 } | |
420 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
421 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count()); | |
422 } | |
423 | |
424 TEST(RefCountedUnitTest, MoveConstructorDerived) { | |
425 ScopedRefPtrCountBase::reset_count(); | |
426 ScopedRefPtrCountDerived::reset_count(); | |
427 | |
428 { | |
429 ScopedRefPtrCountDerived *raw1 = new ScopedRefPtrCountDerived(); | |
430 scoped_refptr<ScopedRefPtrCountDerived> p1(raw1); | |
431 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
432 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
433 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count()); | |
434 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count()); | |
435 | |
436 { | |
437 scoped_refptr<ScopedRefPtrCountBase> p2(p1.Pass()); | |
438 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
439 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count()); | |
440 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count()); | |
441 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count()); | |
442 EXPECT_EQ(nullptr, p1.get()); | |
443 EXPECT_EQ(raw1, p2.get()); | |
444 | |
445 // p2 goes out of scope. | |
446 } | |
447 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
448 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count()); | |
449 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count()); | |
450 EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count()); | |
451 | |
452 // p1 goes out of scope. | |
453 } | |
454 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count()); | |
455 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count()); | |
456 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count()); | |
457 EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count()); | |
458 } | |
459 | |
OLD | NEW |