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

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: reverted to |scoped_refptr<T>(r.Pass()).swap(*this);| and added a test case for ScopedRefPtrToSelf 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 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
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
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