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

Side by Side Diff: base/memory/ref_counted_unittest.cc

Issue 1076953002: Add move support for scoped_refptr. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add comment for check->self_ptr_ = scoped_refptr<ScopedRefPtrToSelf>(); test Created 5 years, 8 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
« no previous file with comments | « base/memory/ref_counted.h ('k') | base/move.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 // Releasing |check->self_ptr_| will delete |check|.
136 // The move assignment operator must assign |check->self_ptr_| first then
137 // release |check->self_ptr_|.
138 check->self_ptr_ = scoped_refptr<ScopedRefPtrToSelf>();
139 EXPECT_TRUE(ScopedRefPtrToSelf::was_destroyed());
140 }
141
76 TEST(RefCountedUnitTest, ScopedRefPtrToOpaque) { 142 TEST(RefCountedUnitTest, ScopedRefPtrToOpaque) {
77 scoped_refptr<base::OpaqueRefCounted> p = base::MakeOpaqueRefCounted(); 143 scoped_refptr<base::OpaqueRefCounted> p = base::MakeOpaqueRefCounted();
78 base::TestOpaqueRefCounted(p); 144 base::TestOpaqueRefCounted(p);
79 145
80 scoped_refptr<base::OpaqueRefCounted> q; 146 scoped_refptr<base::OpaqueRefCounted> q;
81 q = p; 147 q = p;
82 base::TestOpaqueRefCounted(p); 148 base::TestOpaqueRefCounted(p);
83 base::TestOpaqueRefCounted(q); 149 base::TestOpaqueRefCounted(q);
84 } 150 }
85 151
(...skipping 20 matching lines...) Expand all
106 scoped_refptr<SelfAssign> p2; 172 scoped_refptr<SelfAssign> p2;
107 173
108 EXPECT_NE(p1, p2); 174 EXPECT_NE(p1, p2);
109 EXPECT_NE(p2, p1); 175 EXPECT_NE(p2, p1);
110 176
111 p2 = p1; 177 p2 = p1;
112 178
113 EXPECT_EQ(p1, p2); 179 EXPECT_EQ(p1, p2);
114 EXPECT_EQ(p2, p1); 180 EXPECT_EQ(p2, p1);
115 } 181 }
182
183 TEST(RefCountedUnitTest, SelfMoveAssignment) {
184 ScopedRefPtrCountBase::reset_count();
185
186 {
187 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
188 scoped_refptr<ScopedRefPtrCountBase> p(raw);
189 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
190 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
191
192 p = p.Pass();
193 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
194 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
195 EXPECT_EQ(raw, p.get());
196
197 // p goes out of scope.
198 }
199 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
200 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
201 }
202
203 TEST(RefCountedUnitTest, MoveAssignment1) {
204 ScopedRefPtrCountBase::reset_count();
205
206 {
207 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
208 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
209 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
210 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
211
212 {
213 scoped_refptr<ScopedRefPtrCountBase> p2;
214
215 p2 = p1.Pass();
216 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
217 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
218 EXPECT_EQ(nullptr, p1.get());
219 EXPECT_EQ(raw, p2.get());
220
221 // p2 goes out of scope.
222 }
223 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
224 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
225
226 // p1 goes out of scope.
227 }
228 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
229 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
230 }
231
232 TEST(RefCountedUnitTest, MoveAssignment2) {
233 ScopedRefPtrCountBase::reset_count();
234
235 {
236 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
237 scoped_refptr<ScopedRefPtrCountBase> p1;
238 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
239 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
240
241 {
242 scoped_refptr<ScopedRefPtrCountBase> p2(raw);
243 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
244 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
245
246 p1 = p2.Pass();
247 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
248 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
249 EXPECT_EQ(raw, p1.get());
250 EXPECT_EQ(nullptr, p2.get());
251
252 // p2 goes out of scope.
253 }
254 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
255 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
256
257 // p1 goes out of scope.
258 }
259 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
260 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
261 }
262
263 TEST(RefCountedUnitTest, MoveAssignmentSameInstance1) {
264 ScopedRefPtrCountBase::reset_count();
265
266 {
267 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
268 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
269 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
270 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
271
272 {
273 scoped_refptr<ScopedRefPtrCountBase> p2(p1);
274 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
275 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
276
277 p1 = p2.Pass();
278 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
279 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
280 EXPECT_EQ(raw, p1.get());
281 EXPECT_EQ(nullptr, p2.get());
282
283 // p2 goes out of scope.
284 }
285 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
286 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
287
288 // p1 goes out of scope.
289 }
290 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
291 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
292 }
293
294 TEST(RefCountedUnitTest, MoveAssignmentSameInstance2) {
295 ScopedRefPtrCountBase::reset_count();
296
297 {
298 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
299 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
300 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
301 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
302
303 {
304 scoped_refptr<ScopedRefPtrCountBase> p2(p1);
305 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
306 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
307
308 p2 = p1.Pass();
309 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
310 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
311 EXPECT_EQ(nullptr, p1.get());
312 EXPECT_EQ(raw, p2.get());
313
314 // p2 goes out of scope.
315 }
316 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
317 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
318
319 // p1 goes out of scope.
320 }
321 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
322 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
323 }
324
325 TEST(RefCountedUnitTest, MoveAssignmentDifferentInstances) {
326 ScopedRefPtrCountBase::reset_count();
327
328 {
329 ScopedRefPtrCountBase *raw1 = new ScopedRefPtrCountBase();
330 scoped_refptr<ScopedRefPtrCountBase> p1(raw1);
331 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
332 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
333
334 {
335 ScopedRefPtrCountBase *raw2 = new ScopedRefPtrCountBase();
336 scoped_refptr<ScopedRefPtrCountBase> p2(raw2);
337 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
338 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
339
340 p1 = p2.Pass();
341 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
342 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
343 EXPECT_EQ(raw2, p1.get());
344 EXPECT_EQ(nullptr, p2.get());
345
346 // p2 goes out of scope.
347 }
348 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
349 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
350
351 // p1 goes out of scope.
352 }
353 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
354 EXPECT_EQ(2, ScopedRefPtrCountBase::destructor_count());
355 }
356
357 TEST(RefCountedUnitTest, MoveAssignmentDerived) {
358 ScopedRefPtrCountBase::reset_count();
359 ScopedRefPtrCountDerived::reset_count();
360
361 {
362 ScopedRefPtrCountBase *raw1 = new ScopedRefPtrCountBase();
363 scoped_refptr<ScopedRefPtrCountBase> p1(raw1);
364 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
365 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
366 EXPECT_EQ(0, ScopedRefPtrCountDerived::constructor_count());
367 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
368
369 {
370 ScopedRefPtrCountDerived *raw2 = new ScopedRefPtrCountDerived();
371 scoped_refptr<ScopedRefPtrCountDerived> p2(raw2);
372 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
373 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
374 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
375 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
376
377 p1 = p2.Pass();
378 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
379 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
380 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
381 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
382 EXPECT_EQ(raw2, p1.get());
383 EXPECT_EQ(nullptr, p2.get());
384
385 // p2 goes out of scope.
386 }
387 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
388 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
389 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
390 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
391
392 // p1 goes out of scope.
393 }
394 EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
395 EXPECT_EQ(2, ScopedRefPtrCountBase::destructor_count());
396 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
397 EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count());
398 }
399
400 TEST(RefCountedUnitTest, MoveConstructor) {
401 ScopedRefPtrCountBase::reset_count();
402
403 {
404 ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
405 scoped_refptr<ScopedRefPtrCountBase> p1(raw);
406 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
407 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
408
409 {
410 scoped_refptr<ScopedRefPtrCountBase> p2(p1.Pass());
411 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
412 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
413 EXPECT_EQ(nullptr, p1.get());
414 EXPECT_EQ(raw, p2.get());
415
416 // p2 goes out of scope.
417 }
418 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
419 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
420
421 // p1 goes out of scope.
422 }
423 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
424 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
425 }
426
427 TEST(RefCountedUnitTest, MoveConstructorDerived) {
428 ScopedRefPtrCountBase::reset_count();
429 ScopedRefPtrCountDerived::reset_count();
430
431 {
432 ScopedRefPtrCountDerived *raw1 = new ScopedRefPtrCountDerived();
433 scoped_refptr<ScopedRefPtrCountDerived> p1(raw1);
434 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
435 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
436 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
437 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
438
439 {
440 scoped_refptr<ScopedRefPtrCountBase> p2(p1.Pass());
441 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
442 EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
443 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
444 EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
445 EXPECT_EQ(nullptr, p1.get());
446 EXPECT_EQ(raw1, p2.get());
447
448 // p2 goes out of scope.
449 }
450 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
451 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
452 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
453 EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count());
454
455 // p1 goes out of scope.
456 }
457 EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
458 EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
459 EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
460 EXPECT_EQ(1, ScopedRefPtrCountDerived::destructor_count());
461 }
462
OLDNEW
« no previous file with comments | « base/memory/ref_counted.h ('k') | base/move.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698