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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
46 friend class base::RefCounted<ScopedRefPtrToSelf>; | 46 friend class base::RefCounted<ScopedRefPtrToSelf>; |
47 ~ScopedRefPtrToSelf() { was_destroyed_ = true; } | 47 ~ScopedRefPtrToSelf() { was_destroyed_ = true; } |
48 | 48 |
49 static bool was_destroyed_; | 49 static bool was_destroyed_; |
50 | 50 |
51 scoped_refptr<ScopedRefPtrToSelf> self_ptr_; | 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 ScopedRefPtrCount : public base::RefCounted<ScopedRefPtrCount> { | |
57 public: | |
58 ScopedRefPtrCount() { ++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 private: | |
70 friend class base::RefCounted<ScopedRefPtrCount>; | |
71 ~ScopedRefPtrCount() { ++destructor_count_; } | |
72 | |
73 static int constructor_count_; | |
74 static int destructor_count_; | |
75 }; | |
76 | |
77 int ScopedRefPtrCount::constructor_count_ = 0; | |
78 int ScopedRefPtrCount::destructor_count_ = 0; | |
79 | |
56 } // end namespace | 80 } // end namespace |
57 | 81 |
58 TEST(RefCountedUnitTest, TestSelfAssignment) { | 82 TEST(RefCountedUnitTest, TestSelfAssignment) { |
59 SelfAssign* p = new SelfAssign; | 83 SelfAssign* p = new SelfAssign; |
60 scoped_refptr<SelfAssign> var(p); | 84 scoped_refptr<SelfAssign> var(p); |
61 var = var; | 85 var = var; |
62 EXPECT_EQ(var.get(), p); | 86 EXPECT_EQ(var.get(), p); |
63 } | 87 } |
64 | 88 |
65 TEST(RefCountedUnitTest, ScopedRefPtrMemberAccess) { | 89 TEST(RefCountedUnitTest, ScopedRefPtrMemberAccess) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
106 scoped_refptr<SelfAssign> p2; | 130 scoped_refptr<SelfAssign> p2; |
107 | 131 |
108 EXPECT_NE(p1, p2); | 132 EXPECT_NE(p1, p2); |
109 EXPECT_NE(p2, p1); | 133 EXPECT_NE(p2, p1); |
110 | 134 |
111 p2 = p1; | 135 p2 = p1; |
112 | 136 |
113 EXPECT_EQ(p1, p2); | 137 EXPECT_EQ(p1, p2); |
114 EXPECT_EQ(p2, p1); | 138 EXPECT_EQ(p2, p1); |
115 } | 139 } |
140 | |
141 TEST(RefCountedUnitTest, SelfMoveAssignment) { | |
142 ScopedRefPtrCount::reset_count(); | |
143 | |
144 { | |
145 ScopedRefPtrCount *raw = new ScopedRefPtrCount(); | |
146 scoped_refptr<ScopedRefPtrCount> p(raw); | |
147 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
148 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
149 | |
150 p = p.Pass(); | |
151 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
152 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
153 EXPECT_EQ(raw, p.get()); | |
154 | |
155 // p goes out of scope. | |
156 } | |
157 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
158 EXPECT_EQ(1, ScopedRefPtrCount::destructor_count()); | |
159 } | |
160 | |
161 TEST(RefCountedUnitTest, MoveAssignment1) { | |
162 ScopedRefPtrCount::reset_count(); | |
163 | |
164 { | |
165 ScopedRefPtrCount *raw = new ScopedRefPtrCount(); | |
166 scoped_refptr<ScopedRefPtrCount> p1(raw); | |
167 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
168 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
169 | |
170 { | |
171 scoped_refptr<ScopedRefPtrCount> p2; | |
172 | |
173 p2 = p1.Pass(); | |
174 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
175 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
176 EXPECT_EQ(nullptr, p1.get()); | |
177 EXPECT_EQ(raw, p2.get()); | |
178 | |
179 // p2 goes out of scope. | |
180 } | |
181 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
182 EXPECT_EQ(1, ScopedRefPtrCount::destructor_count()); | |
183 | |
184 // p1 goes out of scope. | |
185 } | |
186 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
187 EXPECT_EQ(1, ScopedRefPtrCount::destructor_count()); | |
188 } | |
189 | |
190 TEST(RefCountedUnitTest, MoveAssignment2) { | |
191 ScopedRefPtrCount::reset_count(); | |
192 | |
193 { | |
194 ScopedRefPtrCount *raw = new ScopedRefPtrCount(); | |
195 scoped_refptr<ScopedRefPtrCount> p1; | |
196 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
197 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
198 | |
199 { | |
200 scoped_refptr<ScopedRefPtrCount> p2(raw); | |
201 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
202 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
203 | |
204 p1 = p2.Pass(); | |
205 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
206 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
207 EXPECT_EQ(raw, p1.get()); | |
208 EXPECT_EQ(nullptr, p2.get()); | |
209 | |
210 // p2 goes out of scope. | |
211 } | |
212 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
213 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
214 | |
215 // p1 goes out of scope. | |
216 } | |
217 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
218 EXPECT_EQ(1, ScopedRefPtrCount::destructor_count()); | |
219 } | |
220 | |
221 TEST(RefCountedUnitTest, MoveAssignmentSameInstance1) { | |
222 ScopedRefPtrCount::reset_count(); | |
223 | |
224 { | |
225 ScopedRefPtrCount *raw = new ScopedRefPtrCount(); | |
226 scoped_refptr<ScopedRefPtrCount> p1(raw); | |
227 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
228 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
229 | |
230 { | |
231 scoped_refptr<ScopedRefPtrCount> p2(p1); | |
232 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
233 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
234 | |
235 p1 = p2.Pass(); | |
236 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
237 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
238 EXPECT_EQ(raw, p1.get()); | |
239 EXPECT_EQ(nullptr, p2.get()); | |
240 | |
241 // p2 goes out of scope. | |
242 } | |
243 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
244 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
245 | |
246 // p1 goes out of scope. | |
247 } | |
248 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
249 EXPECT_EQ(1, ScopedRefPtrCount::destructor_count()); | |
250 } | |
251 | |
252 TEST(RefCountedUnitTest, MoveAssignmentSameInstance2) { | |
253 ScopedRefPtrCount::reset_count(); | |
254 | |
255 { | |
256 ScopedRefPtrCount *raw = new ScopedRefPtrCount(); | |
257 scoped_refptr<ScopedRefPtrCount> p1(raw); | |
258 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
259 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
260 | |
261 { | |
262 scoped_refptr<ScopedRefPtrCount> p2(p1); | |
263 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
264 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
265 | |
266 p2 = p1.Pass(); | |
267 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
268 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
269 EXPECT_EQ(nullptr, p1.get()); | |
270 EXPECT_EQ(raw, p2.get()); | |
271 | |
272 // p2 goes out of scope. | |
273 } | |
274 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
275 EXPECT_EQ(1, ScopedRefPtrCount::destructor_count()); | |
276 | |
277 // p1 goes out of scope. | |
278 } | |
279 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
280 EXPECT_EQ(1, ScopedRefPtrCount::destructor_count()); | |
281 } | |
282 | |
283 TEST(RefCountedUnitTest, MoveAssignmentDifferentInstances) { | |
284 ScopedRefPtrCount::reset_count(); | |
285 | |
286 { | |
287 ScopedRefPtrCount *raw1 = new ScopedRefPtrCount(); | |
288 scoped_refptr<ScopedRefPtrCount> p1(raw1); | |
289 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
290 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
291 | |
292 { | |
293 ScopedRefPtrCount *raw2 = new ScopedRefPtrCount(); | |
294 scoped_refptr<ScopedRefPtrCount> p2(raw2); | |
295 EXPECT_EQ(2, ScopedRefPtrCount::constructor_count()); | |
296 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
297 | |
298 p1 = p2.Pass(); | |
299 EXPECT_EQ(2, ScopedRefPtrCount::constructor_count()); | |
300 EXPECT_EQ(1, ScopedRefPtrCount::destructor_count()); | |
301 EXPECT_EQ(raw2, p1.get()); | |
302 EXPECT_EQ(nullptr, p2.get()); | |
303 | |
304 // p2 goes out of scope. | |
305 } | |
306 EXPECT_EQ(2, ScopedRefPtrCount::constructor_count()); | |
307 EXPECT_EQ(1, ScopedRefPtrCount::destructor_count()); | |
308 | |
309 // p1 goes out of scope. | |
310 } | |
311 EXPECT_EQ(2, ScopedRefPtrCount::constructor_count()); | |
312 EXPECT_EQ(2, ScopedRefPtrCount::destructor_count()); | |
313 } | |
314 | |
315 TEST(RefCountedUnitTest, MoveConstructor) { | |
316 ScopedRefPtrCount::reset_count(); | |
317 | |
318 { | |
319 ScopedRefPtrCount *raw = new ScopedRefPtrCount(); | |
danakj
2015/04/10 20:14:32
Can you add some tests with conversion where T !=
Kibeom Kim (inactive)
2015/04/12 07:35:14
Done.
| |
320 scoped_refptr<ScopedRefPtrCount> p1(raw); | |
321 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
322 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
323 | |
324 { | |
325 scoped_refptr<ScopedRefPtrCount> p2(p1.Pass()); | |
326 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
327 EXPECT_EQ(0, ScopedRefPtrCount::destructor_count()); | |
328 EXPECT_EQ(nullptr, p1.get()); | |
329 EXPECT_EQ(raw, p2.get()); | |
330 | |
331 // p2 goes out of scope. | |
332 } | |
333 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
334 EXPECT_EQ(1, ScopedRefPtrCount::destructor_count()); | |
335 | |
336 // p1 goes out of scope. | |
337 } | |
338 EXPECT_EQ(1, ScopedRefPtrCount::constructor_count()); | |
339 EXPECT_EQ(1, ScopedRefPtrCount::destructor_count()); | |
340 } | |
OLD | NEW |