1 | /* |
2 | * Copyright (C) 2015 Apple Inc. All rights reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
23 | * THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #include "config.h" |
27 | |
28 | #include "Test.h" |
29 | #include <wtf/HashSet.h> |
30 | #include <wtf/WeakHashSet.h> |
31 | #include <wtf/WeakPtr.h> |
32 | |
33 | static unsigned s_baseWeakReferences = 0; |
34 | |
35 | namespace TestWebKitAPI { |
36 | |
37 | class Base { |
38 | public: |
39 | Base() { } |
40 | |
41 | int foo() |
42 | { |
43 | return 0; |
44 | } |
45 | |
46 | auto& weakPtrFactory() const { return m_weakPtrFactory; } |
47 | |
48 | private: |
49 | WeakPtrFactory<Base> m_weakPtrFactory; |
50 | }; |
51 | |
52 | class Derived : public Base { |
53 | public: |
54 | Derived() { } |
55 | |
56 | int foo() |
57 | { |
58 | return 1; |
59 | } |
60 | }; |
61 | |
62 | } |
63 | |
64 | namespace WTF { |
65 | |
66 | template<> |
67 | WeakReference<TestWebKitAPI::Base>::WeakReference(TestWebKitAPI::Base* ptr) |
68 | : m_ptr(ptr) |
69 | { |
70 | ++s_baseWeakReferences; |
71 | } |
72 | template<> |
73 | WeakReference<TestWebKitAPI::Base>::~WeakReference() |
74 | { |
75 | --s_baseWeakReferences; |
76 | } |
77 | |
78 | } |
79 | |
80 | namespace TestWebKitAPI { |
81 | |
82 | TEST(WTF_WeakPtr, Basic) |
83 | { |
84 | int dummy = 5; |
85 | WeakPtrFactory<int>* factory = new WeakPtrFactory<int>(); |
86 | WeakPtr<int> weakPtr1 = factory->createWeakPtr(dummy); |
87 | WeakPtr<int> weakPtr2 = factory->createWeakPtr(dummy); |
88 | WeakPtr<int> weakPtr3 = factory->createWeakPtr(dummy); |
89 | EXPECT_EQ(weakPtr1.get(), &dummy); |
90 | EXPECT_EQ(weakPtr2.get(), &dummy); |
91 | EXPECT_EQ(weakPtr3.get(), &dummy); |
92 | EXPECT_TRUE(!!weakPtr1); |
93 | EXPECT_TRUE(!!weakPtr2); |
94 | EXPECT_TRUE(!!weakPtr3); |
95 | EXPECT_TRUE(weakPtr1 == weakPtr2); |
96 | EXPECT_TRUE(weakPtr1 == &dummy); |
97 | EXPECT_TRUE(&dummy == weakPtr2); |
98 | delete factory; |
99 | EXPECT_NULL(weakPtr1.get()); |
100 | EXPECT_NULL(weakPtr2.get()); |
101 | EXPECT_NULL(weakPtr3.get()); |
102 | EXPECT_FALSE(weakPtr1); |
103 | EXPECT_FALSE(weakPtr2); |
104 | EXPECT_FALSE(weakPtr3); |
105 | } |
106 | |
107 | TEST(WTF_WeakPtr, Assignment) |
108 | { |
109 | int dummy = 5; |
110 | WeakPtr<int> weakPtr; |
111 | { |
112 | WeakPtrFactory<int> factory; |
113 | EXPECT_NULL(weakPtr.get()); |
114 | weakPtr = factory.createWeakPtr(dummy); |
115 | EXPECT_EQ(weakPtr.get(), &dummy); |
116 | } |
117 | EXPECT_NULL(weakPtr.get()); |
118 | } |
119 | |
120 | TEST(WTF_WeakPtr, MultipleFactories) |
121 | { |
122 | int dummy1 = 5; |
123 | int dummy2 = 7; |
124 | WeakPtrFactory<int>* factory1 = new WeakPtrFactory<int>(); |
125 | WeakPtrFactory<int>* factory2 = new WeakPtrFactory<int>(); |
126 | WeakPtr<int> weakPtr1 = factory1->createWeakPtr(dummy1); |
127 | WeakPtr<int> weakPtr2 = factory2->createWeakPtr(dummy2); |
128 | EXPECT_EQ(weakPtr1.get(), &dummy1); |
129 | EXPECT_EQ(weakPtr2.get(), &dummy2); |
130 | EXPECT_TRUE(weakPtr1 != weakPtr2); |
131 | EXPECT_TRUE(weakPtr1 != &dummy2); |
132 | EXPECT_TRUE(&dummy1 != weakPtr2); |
133 | delete factory1; |
134 | EXPECT_NULL(weakPtr1.get()); |
135 | EXPECT_EQ(weakPtr2.get(), &dummy2); |
136 | delete factory2; |
137 | EXPECT_NULL(weakPtr2.get()); |
138 | } |
139 | |
140 | TEST(WTF_WeakPtr, RevokeAll) |
141 | { |
142 | int dummy = 5; |
143 | WeakPtrFactory<int> factory; |
144 | WeakPtr<int> weakPtr1 = factory.createWeakPtr(dummy); |
145 | WeakPtr<int> weakPtr2 = factory.createWeakPtr(dummy); |
146 | WeakPtr<int> weakPtr3 = factory.createWeakPtr(dummy); |
147 | EXPECT_EQ(weakPtr1.get(), &dummy); |
148 | EXPECT_EQ(weakPtr2.get(), &dummy); |
149 | EXPECT_EQ(weakPtr3.get(), &dummy); |
150 | factory.revokeAll(); |
151 | EXPECT_NULL(weakPtr1.get()); |
152 | EXPECT_NULL(weakPtr2.get()); |
153 | EXPECT_NULL(weakPtr3.get()); |
154 | } |
155 | |
156 | struct Foo { |
157 | void bar() { }; |
158 | }; |
159 | |
160 | TEST(WTF_WeakPtr, Dereference) |
161 | { |
162 | Foo f; |
163 | WeakPtrFactory<Foo> factory; |
164 | WeakPtr<Foo> weakPtr = factory.createWeakPtr(f); |
165 | weakPtr->bar(); |
166 | } |
167 | |
168 | TEST(WTF_WeakPtr, Operators) |
169 | { |
170 | Foo f; |
171 | WeakPtrFactory<Foo> factory; |
172 | WeakPtr<Foo> weakPtr = factory.createWeakPtr(f); |
173 | |
174 | WeakPtr<Foo> weakPtr2 = weakPtr; |
175 | EXPECT_EQ(weakPtr2.get(), &f); |
176 | |
177 | WeakPtr<Foo> weakPtr3; |
178 | weakPtr3 = weakPtr; |
179 | EXPECT_EQ(weakPtr3.get(), &f); |
180 | |
181 | WeakPtr<Foo> weakPtr4 = WTFMove(weakPtr); |
182 | EXPECT_EQ(weakPtr4.get(), &f); |
183 | EXPECT_FALSE(weakPtr); |
184 | } |
185 | |
186 | TEST(WTF_WeakPtr, Forget) |
187 | { |
188 | int dummy = 5; |
189 | int dummy2 = 7; |
190 | |
191 | WeakPtrFactory<int> outerFactory; |
192 | WeakPtr<int> weakPtr1, weakPtr2, weakPtr3, weakPtr4; |
193 | { |
194 | WeakPtrFactory<int> innerFactory; |
195 | weakPtr1 = innerFactory.createWeakPtr(dummy); |
196 | weakPtr2 = innerFactory.createWeakPtr(dummy); |
197 | weakPtr3 = innerFactory.createWeakPtr(dummy); |
198 | EXPECT_EQ(weakPtr1.get(), &dummy); |
199 | EXPECT_EQ(weakPtr2.get(), &dummy); |
200 | EXPECT_EQ(weakPtr3.get(), &dummy); |
201 | weakPtr1.clear(); |
202 | weakPtr3 = nullptr; |
203 | EXPECT_NULL(weakPtr1.get()); |
204 | EXPECT_EQ(weakPtr2.get(), &dummy); |
205 | EXPECT_NULL(weakPtr3.get()); |
206 | weakPtr1.clear(); |
207 | weakPtr3.clear(); |
208 | EXPECT_NULL(weakPtr1.get()); |
209 | EXPECT_EQ(weakPtr2.get(), &dummy); |
210 | EXPECT_NULL(weakPtr3.get()); |
211 | weakPtr3 = nullptr; |
212 | EXPECT_NULL(weakPtr1.get()); |
213 | EXPECT_EQ(weakPtr2.get(), &dummy); |
214 | EXPECT_NULL(weakPtr3.get()); |
215 | |
216 | weakPtr4 = weakPtr2; |
217 | EXPECT_EQ(weakPtr2.get(), &dummy); |
218 | EXPECT_EQ(weakPtr4.get(), &dummy); |
219 | |
220 | WeakPtr<int> weakPtr5 = weakPtr2; |
221 | EXPECT_EQ(weakPtr2.get(), &dummy); |
222 | EXPECT_EQ(weakPtr5.get(), &dummy); |
223 | weakPtr5.clear(); |
224 | EXPECT_NULL(weakPtr5.get()); |
225 | EXPECT_EQ(weakPtr2.get(), &dummy); |
226 | |
227 | weakPtr4 = outerFactory.createWeakPtr(dummy2); |
228 | EXPECT_EQ(weakPtr2.get(), &dummy); |
229 | EXPECT_EQ(weakPtr4.get(), &dummy2); |
230 | } |
231 | |
232 | EXPECT_NULL(weakPtr1.get()); |
233 | EXPECT_NULL(weakPtr2.get()); |
234 | EXPECT_EQ(weakPtr4.get(), &dummy2); |
235 | |
236 | WeakPtr<int> weakPtr5 = weakPtr4; |
237 | EXPECT_EQ(weakPtr4.get(), &dummy2); |
238 | EXPECT_EQ(weakPtr5.get(), &dummy2); |
239 | weakPtr5.clear(); |
240 | EXPECT_NULL(weakPtr5.get()); |
241 | WeakPtr<int> weakPtr6 = weakPtr5; |
242 | EXPECT_NULL(weakPtr6.get()); |
243 | EXPECT_EQ(weakPtr5.get(), weakPtr6.get()); |
244 | |
245 | WeakPtr<int> weakPtr7 = outerFactory.createWeakPtr(dummy2); |
246 | EXPECT_EQ(weakPtr7.get(), &dummy2); |
247 | weakPtr7 = nullptr; |
248 | EXPECT_NULL(weakPtr7.get()); |
249 | } |
250 | |
251 | TEST(WTF_WeakPtr, Downcasting) |
252 | { |
253 | int dummy0 = 0; |
254 | int dummy1 = 1; |
255 | |
256 | WeakPtr<Base> baseWeakPtr; |
257 | WeakPtr<Derived> derivedWeakPtr; |
258 | |
259 | { |
260 | Derived object; |
261 | Derived* derivedPtr = &object; |
262 | Base* basePtr = static_cast<Base*>(&object); |
263 | |
264 | baseWeakPtr = object.weakPtrFactory().createWeakPtr(object); |
265 | EXPECT_EQ(basePtr->foo(), dummy0); |
266 | EXPECT_EQ(baseWeakPtr->foo(), basePtr->foo()); |
267 | EXPECT_EQ(baseWeakPtr.get()->foo(), basePtr->foo()); |
268 | |
269 | derivedWeakPtr = makeWeakPtr(object); |
270 | EXPECT_EQ(derivedWeakPtr->foo(), dummy1); |
271 | EXPECT_EQ(derivedWeakPtr->foo(), derivedPtr->foo()); |
272 | EXPECT_EQ(derivedWeakPtr.get()->foo(), derivedPtr->foo()); |
273 | |
274 | EXPECT_EQ(baseWeakPtr.get(), derivedWeakPtr.get()); |
275 | } |
276 | |
277 | EXPECT_NULL(baseWeakPtr.get()); |
278 | EXPECT_NULL(derivedWeakPtr.get()); |
279 | } |
280 | |
281 | TEST(WTF_WeakPtr, DerivedConstructAndAssign) |
282 | { |
283 | Derived derived; |
284 | { |
285 | WeakPtr<Derived> derivedWeakPtr = makeWeakPtr(derived); |
286 | WeakPtr<Base> baseWeakPtr { WTFMove(derivedWeakPtr) }; |
287 | EXPECT_EQ(baseWeakPtr.get(), &derived); |
288 | EXPECT_NULL(derivedWeakPtr.get()); |
289 | } |
290 | |
291 | { |
292 | WeakPtr<Derived> derivedWeakPtr = makeWeakPtr(derived); |
293 | WeakPtr<Base> baseWeakPtr { derivedWeakPtr }; |
294 | EXPECT_EQ(baseWeakPtr.get(), &derived); |
295 | EXPECT_EQ(derivedWeakPtr.get(), &derived); |
296 | } |
297 | |
298 | { |
299 | WeakPtr<Derived> derivedWeakPtr = makeWeakPtr(derived); |
300 | WeakPtr<Base> baseWeakPtr; |
301 | baseWeakPtr = WTFMove(derivedWeakPtr); |
302 | EXPECT_EQ(baseWeakPtr.get(), &derived); |
303 | EXPECT_NULL(derivedWeakPtr.get()); |
304 | } |
305 | |
306 | { |
307 | WeakPtr<Derived> derivedWeakPtr = makeWeakPtr(derived); |
308 | WeakPtr<Base> baseWeakPtr; |
309 | baseWeakPtr = derivedWeakPtr; |
310 | EXPECT_EQ(baseWeakPtr.get(), &derived); |
311 | EXPECT_EQ(derivedWeakPtr.get(), &derived); |
312 | } |
313 | } |
314 | |
315 | TEST(WTF_WeakPtr, DerivedConstructAndAssignConst) |
316 | { |
317 | const Derived derived; |
318 | { |
319 | auto derivedWeakPtr = makeWeakPtr(derived); |
320 | WeakPtr<const Base> baseWeakPtr { WTFMove(derivedWeakPtr) }; |
321 | EXPECT_EQ(baseWeakPtr.get(), &derived); |
322 | EXPECT_NULL(derivedWeakPtr.get()); |
323 | } |
324 | |
325 | { |
326 | auto derivedWeakPtr = makeWeakPtr(derived); |
327 | WeakPtr<const Base> baseWeakPtr { derivedWeakPtr }; |
328 | EXPECT_EQ(baseWeakPtr.get(), &derived); |
329 | EXPECT_EQ(derivedWeakPtr.get(), &derived); |
330 | } |
331 | |
332 | { |
333 | auto derivedWeakPtr = makeWeakPtr(derived); |
334 | WeakPtr<const Base> baseWeakPtr; |
335 | baseWeakPtr = WTFMove(derivedWeakPtr); |
336 | EXPECT_EQ(baseWeakPtr.get(), &derived); |
337 | EXPECT_NULL(derivedWeakPtr.get()); |
338 | } |
339 | |
340 | { |
341 | auto derivedWeakPtr = makeWeakPtr(derived); |
342 | WeakPtr<const Base> baseWeakPtr; |
343 | baseWeakPtr = derivedWeakPtr; |
344 | EXPECT_EQ(baseWeakPtr.get(), &derived); |
345 | EXPECT_EQ(derivedWeakPtr.get(), &derived); |
346 | } |
347 | } |
348 | |
349 | template <typename T> |
350 | unsigned computeSizeOfWeakHashSet(const HashSet<WeakPtr<T>>& set) |
351 | { |
352 | unsigned size = 0; |
353 | for (auto& item : set) { |
354 | UNUSED_PARAM(item); |
355 | size++; |
356 | } |
357 | return size; |
358 | } |
359 | |
360 | template <typename T> |
361 | unsigned computeSizeOfWeakHashSet(const WeakHashSet<T>& set) |
362 | { |
363 | unsigned size = 0; |
364 | for (auto& item : set) { |
365 | UNUSED_PARAM(item); |
366 | size++; |
367 | } |
368 | return size; |
369 | } |
370 | |
371 | TEST(WTF_WeakPtr, WeakHashSetBasic) |
372 | { |
373 | { |
374 | WeakHashSet<Base> weakHashSet; |
375 | Base object; |
376 | EXPECT_FALSE(weakHashSet.contains(object)); |
377 | EXPECT_EQ(s_baseWeakReferences, 0u); |
378 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 0u); |
379 | weakHashSet.add(object); |
380 | EXPECT_EQ(s_baseWeakReferences, 1u); |
381 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
382 | EXPECT_TRUE(weakHashSet.contains(object)); |
383 | weakHashSet.add(object); |
384 | EXPECT_TRUE(weakHashSet.contains(object)); |
385 | EXPECT_EQ(s_baseWeakReferences, 1u); |
386 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
387 | weakHashSet.checkConsistency(); |
388 | } |
389 | EXPECT_EQ(s_baseWeakReferences, 0u); |
390 | |
391 | { |
392 | WeakHashSet<Base> weakHashSet; |
393 | Derived object; |
394 | EXPECT_FALSE(weakHashSet.contains(object)); |
395 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 0u); |
396 | EXPECT_EQ(s_baseWeakReferences, 0u); |
397 | weakHashSet.add(object); |
398 | EXPECT_TRUE(weakHashSet.contains(object)); |
399 | EXPECT_EQ(s_baseWeakReferences, 1u); |
400 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
401 | weakHashSet.add(object); |
402 | EXPECT_TRUE(weakHashSet.contains(object)); |
403 | EXPECT_EQ(s_baseWeakReferences, 1u); |
404 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
405 | weakHashSet.checkConsistency(); |
406 | } |
407 | EXPECT_EQ(s_baseWeakReferences, 0u); |
408 | |
409 | { |
410 | WeakHashSet<Base> weakHashSet; |
411 | { |
412 | Base object; |
413 | EXPECT_FALSE(weakHashSet.contains(object)); |
414 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 0u); |
415 | EXPECT_EQ(s_baseWeakReferences, 0u); |
416 | weakHashSet.add(object); |
417 | EXPECT_TRUE(weakHashSet.contains(object)); |
418 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
419 | EXPECT_EQ(s_baseWeakReferences, 1u); |
420 | } |
421 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 0u); |
422 | weakHashSet.checkConsistency(); |
423 | } |
424 | EXPECT_EQ(s_baseWeakReferences, 0u); |
425 | |
426 | { |
427 | WeakHashSet<Base> weakHashSet; |
428 | { |
429 | Base object1; |
430 | Base object2; |
431 | EXPECT_FALSE(weakHashSet.contains(object1)); |
432 | EXPECT_FALSE(weakHashSet.contains(object2)); |
433 | EXPECT_EQ(s_baseWeakReferences, 0u); |
434 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 0u); |
435 | weakHashSet.add(object1); |
436 | EXPECT_TRUE(weakHashSet.contains(object1)); |
437 | EXPECT_FALSE(weakHashSet.contains(object2)); |
438 | EXPECT_EQ(s_baseWeakReferences, 1u); |
439 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
440 | weakHashSet.add(object2); |
441 | EXPECT_TRUE(weakHashSet.contains(object1)); |
442 | EXPECT_TRUE(weakHashSet.contains(object2)); |
443 | EXPECT_EQ(s_baseWeakReferences, 2u); |
444 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 2u); |
445 | weakHashSet.remove(object1); |
446 | EXPECT_FALSE(weakHashSet.contains(object1)); |
447 | EXPECT_TRUE(weakHashSet.contains(object2)); |
448 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
449 | } |
450 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 0u); |
451 | weakHashSet.checkConsistency(); |
452 | } |
453 | EXPECT_EQ(s_baseWeakReferences, 0u); |
454 | |
455 | { |
456 | WeakHashSet<Base> weakHashSet; |
457 | Base object1; |
458 | Base object2; |
459 | Base object3; |
460 | EXPECT_FALSE(weakHashSet.contains(object1)); |
461 | EXPECT_FALSE(weakHashSet.contains(object2)); |
462 | EXPECT_FALSE(weakHashSet.contains(object3)); |
463 | EXPECT_EQ(s_baseWeakReferences, 0u); |
464 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 0u); |
465 | weakHashSet.add(object1); |
466 | weakHashSet.add(object2); |
467 | EXPECT_TRUE(weakHashSet.contains(object1)); |
468 | EXPECT_TRUE(weakHashSet.contains(object2)); |
469 | EXPECT_FALSE(weakHashSet.contains(object3)); |
470 | EXPECT_EQ(s_baseWeakReferences, 2u); |
471 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 2u); |
472 | weakHashSet.remove(object1); |
473 | EXPECT_FALSE(weakHashSet.contains(object1)); |
474 | EXPECT_TRUE(weakHashSet.contains(object2)); |
475 | EXPECT_FALSE(weakHashSet.contains(object3)); |
476 | EXPECT_EQ(s_baseWeakReferences, 2u); // Because object2 holds onto WeakReference. |
477 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
478 | weakHashSet.remove(object3); |
479 | EXPECT_FALSE(weakHashSet.contains(object1)); |
480 | EXPECT_TRUE(weakHashSet.contains(object2)); |
481 | EXPECT_FALSE(weakHashSet.contains(object3)); |
482 | EXPECT_EQ(s_baseWeakReferences, 2u); |
483 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
484 | weakHashSet.add(object2); |
485 | EXPECT_FALSE(weakHashSet.contains(object1)); |
486 | EXPECT_TRUE(weakHashSet.contains(object2)); |
487 | EXPECT_FALSE(weakHashSet.contains(object3)); |
488 | EXPECT_EQ(s_baseWeakReferences, 2u); |
489 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
490 | weakHashSet.checkConsistency(); |
491 | } |
492 | EXPECT_EQ(s_baseWeakReferences, 0u); |
493 | } |
494 | |
495 | TEST(WTF_WeakPtr, WeakHashSetConstObjects) |
496 | { |
497 | { |
498 | WeakHashSet<Base> weakHashSet; |
499 | const Base object; |
500 | EXPECT_FALSE(weakHashSet.contains(object)); |
501 | EXPECT_EQ(s_baseWeakReferences, 0u); |
502 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 0u); |
503 | weakHashSet.add(object); |
504 | EXPECT_EQ(s_baseWeakReferences, 1u); |
505 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
506 | EXPECT_TRUE(weakHashSet.contains(object)); |
507 | weakHashSet.checkConsistency(); |
508 | weakHashSet.add(object); |
509 | EXPECT_TRUE(weakHashSet.contains(object)); |
510 | EXPECT_EQ(s_baseWeakReferences, 1u); |
511 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
512 | weakHashSet.checkConsistency(); |
513 | weakHashSet.remove(object); |
514 | EXPECT_EQ(s_baseWeakReferences, 1u); |
515 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 0u); |
516 | } |
517 | |
518 | { |
519 | WeakHashSet<Base> weakHashSet; |
520 | const Derived object; |
521 | EXPECT_FALSE(weakHashSet.contains(object)); |
522 | EXPECT_EQ(s_baseWeakReferences, 0u); |
523 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 0u); |
524 | weakHashSet.add(object); |
525 | EXPECT_EQ(s_baseWeakReferences, 1u); |
526 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
527 | EXPECT_TRUE(weakHashSet.contains(object)); |
528 | weakHashSet.checkConsistency(); |
529 | weakHashSet.add(object); |
530 | EXPECT_TRUE(weakHashSet.contains(object)); |
531 | EXPECT_EQ(s_baseWeakReferences, 1u); |
532 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
533 | weakHashSet.checkConsistency(); |
534 | weakHashSet.remove(object); |
535 | EXPECT_EQ(s_baseWeakReferences, 1u); |
536 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 0u); |
537 | } |
538 | |
539 | { |
540 | WeakHashSet<Derived> weakHashSet; |
541 | const Derived object; |
542 | EXPECT_FALSE(weakHashSet.contains(object)); |
543 | EXPECT_EQ(s_baseWeakReferences, 0u); |
544 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 0u); |
545 | weakHashSet.add(object); |
546 | EXPECT_EQ(s_baseWeakReferences, 1u); |
547 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
548 | EXPECT_TRUE(weakHashSet.contains(object)); |
549 | weakHashSet.checkConsistency(); |
550 | weakHashSet.add(object); |
551 | EXPECT_TRUE(weakHashSet.contains(object)); |
552 | EXPECT_EQ(s_baseWeakReferences, 1u); |
553 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 1u); |
554 | weakHashSet.checkConsistency(); |
555 | weakHashSet.remove(object); |
556 | EXPECT_EQ(s_baseWeakReferences, 1u); |
557 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 0u); |
558 | } |
559 | } |
560 | |
561 | TEST(WTF_WeakPtr, WeakHashSetExpansion) |
562 | { |
563 | unsigned initialCapacity; |
564 | const static unsigned maxLoadCap = 3; |
565 | { |
566 | WeakHashSet<Base> weakHashSet; |
567 | Base object; |
568 | EXPECT_EQ(s_baseWeakReferences, 0u); |
569 | weakHashSet.add(object); |
570 | EXPECT_EQ(s_baseWeakReferences, 1u); |
571 | initialCapacity = weakHashSet.capacity(); |
572 | } |
573 | EXPECT_EQ(s_baseWeakReferences, 0u); |
574 | |
575 | for (unsigned i = 0; i < 1; ++i) { |
576 | WeakHashSet<Base> weakHashSet; |
577 | Vector<std::unique_ptr<Base>> objects; |
578 | Vector<std::unique_ptr<Base>> otherObjects; |
579 | |
580 | EXPECT_EQ(weakHashSet.capacity(), 0u); |
581 | EXPECT_TRUE(initialCapacity / maxLoadCap); |
582 | for (unsigned i = 0; i < initialCapacity / maxLoadCap; ++i) { |
583 | auto object = std::make_unique<Base>(); |
584 | weakHashSet.add(*object); |
585 | objects.append(WTFMove(object)); |
586 | otherObjects.append(std::make_unique<Base>()); |
587 | weakHashSet.checkConsistency(); |
588 | } |
589 | EXPECT_EQ(s_baseWeakReferences, otherObjects.size()); |
590 | EXPECT_EQ(weakHashSet.capacity(), initialCapacity); |
591 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), objects.size()); |
592 | for (unsigned i = 0; i < otherObjects.size(); ++i) { |
593 | EXPECT_TRUE(weakHashSet.contains(*objects[i])); |
594 | EXPECT_FALSE(weakHashSet.contains(*otherObjects[i])); |
595 | } |
596 | objects.clear(); |
597 | weakHashSet.checkConsistency(); |
598 | EXPECT_EQ(s_baseWeakReferences, otherObjects.size()); |
599 | EXPECT_EQ(weakHashSet.capacity(), initialCapacity); |
600 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 0u); |
601 | for (auto& object : otherObjects) |
602 | EXPECT_FALSE(weakHashSet.contains(*object)); |
603 | for (auto& object : otherObjects) { |
604 | weakHashSet.add(*object); |
605 | weakHashSet.checkConsistency(); |
606 | } |
607 | EXPECT_EQ(weakHashSet.capacity(), initialCapacity); |
608 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), otherObjects.size()); |
609 | for (auto& object : otherObjects) |
610 | EXPECT_TRUE(weakHashSet.contains(*object)); |
611 | } |
612 | EXPECT_EQ(s_baseWeakReferences, 0u); |
613 | |
614 | for (unsigned i = 0; i < 10; ++i) { |
615 | WeakHashSet<Base> weakHashSet; |
616 | Vector<std::unique_ptr<Base>> objects; |
617 | EXPECT_EQ(weakHashSet.capacity(), 0u); |
618 | unsigned objectCount = initialCapacity * 2; |
619 | for (unsigned i = 0; i < objectCount; ++i) { |
620 | auto object = std::make_unique<Base>(); |
621 | weakHashSet.add(*object); |
622 | objects.append(WTFMove(object)); |
623 | weakHashSet.checkConsistency(); |
624 | } |
625 | unsigned originalCapacity = weakHashSet.capacity(); |
626 | EXPECT_EQ(s_baseWeakReferences, objects.size()); |
627 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), objects.size()); |
628 | for (auto& object : objects) |
629 | EXPECT_TRUE(weakHashSet.contains(*object)); |
630 | objects.clear(); |
631 | weakHashSet.checkConsistency(); |
632 | EXPECT_EQ(s_baseWeakReferences, objectCount); |
633 | EXPECT_EQ(weakHashSet.capacity(), originalCapacity); |
634 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), 0u); |
635 | } |
636 | } |
637 | |
638 | TEST(WTF_WeakPtr, WeakHashSetComputesEmpty) |
639 | { |
640 | { |
641 | WeakHashSet<Base> weakHashSet; |
642 | { |
643 | Base object; |
644 | EXPECT_EQ(s_baseWeakReferences, 0u); |
645 | weakHashSet.add(object); |
646 | EXPECT_FALSE(weakHashSet.computesEmpty()); |
647 | } |
648 | EXPECT_EQ(s_baseWeakReferences, 1u); |
649 | EXPECT_TRUE(weakHashSet.computesEmpty()); |
650 | } |
651 | |
652 | { |
653 | WeakHashSet<Base> weakHashSet; |
654 | Base object1; |
655 | EXPECT_EQ(s_baseWeakReferences, 0u); |
656 | weakHashSet.add(object1); |
657 | EXPECT_EQ(s_baseWeakReferences, 1u); |
658 | { |
659 | Base object2; |
660 | weakHashSet.add(object2); |
661 | EXPECT_FALSE(weakHashSet.computesEmpty()); |
662 | } |
663 | EXPECT_EQ(s_baseWeakReferences, 2u); |
664 | EXPECT_FALSE(weakHashSet.computesEmpty()); |
665 | weakHashSet.remove(object1); |
666 | EXPECT_TRUE(weakHashSet.computesEmpty()); |
667 | } |
668 | |
669 | { |
670 | WeakHashSet<Base> weakHashSet; |
671 | Vector<std::unique_ptr<Base>> objects; |
672 | auto firstObject = std::make_unique<Base>(); |
673 | weakHashSet.add(*firstObject); |
674 | do { |
675 | auto object = std::make_unique<Base>(); |
676 | weakHashSet.add(*object); |
677 | objects.append(WTFMove(object)); |
678 | } while (weakHashSet.begin().get() == firstObject.get()); |
679 | |
680 | EXPECT_EQ(s_baseWeakReferences, objects.size() + 1); |
681 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), objects.size() + 1); |
682 | EXPECT_FALSE(weakHashSet.computesEmpty()); |
683 | firstObject = nullptr; |
684 | EXPECT_FALSE(weakHashSet.computesEmpty()); |
685 | EXPECT_EQ(s_baseWeakReferences, objects.size() + 1); |
686 | EXPECT_EQ(computeSizeOfWeakHashSet(weakHashSet), objects.size()); |
687 | } |
688 | } |
689 | |
690 | TEST(WTF_WeakPtr, WeakHashSetComputeSize) |
691 | { |
692 | { |
693 | WeakHashSet<Base> weakHashSet; |
694 | { |
695 | Base object; |
696 | EXPECT_EQ(s_baseWeakReferences, 0u); |
697 | weakHashSet.add(object); |
698 | EXPECT_EQ(s_baseWeakReferences, 1u); |
699 | EXPECT_EQ(weakHashSet.computeSize(), 1u); |
700 | weakHashSet.checkConsistency(); |
701 | } |
702 | EXPECT_TRUE(weakHashSet.computesEmpty()); |
703 | EXPECT_EQ(weakHashSet.computeSize(), 0u); |
704 | EXPECT_EQ(s_baseWeakReferences, 0u); |
705 | EXPECT_TRUE(weakHashSet.computesEmpty()); |
706 | weakHashSet.checkConsistency(); |
707 | } |
708 | |
709 | { |
710 | WeakHashSet<Base> weakHashSet; |
711 | { |
712 | Base object1; |
713 | EXPECT_EQ(s_baseWeakReferences, 0u); |
714 | weakHashSet.add(object1); |
715 | EXPECT_EQ(s_baseWeakReferences, 1u); |
716 | { |
717 | Base object2; |
718 | weakHashSet.add(object2); |
719 | EXPECT_EQ(s_baseWeakReferences, 2u); |
720 | EXPECT_EQ(weakHashSet.computeSize(), 2u); |
721 | weakHashSet.checkConsistency(); |
722 | } |
723 | EXPECT_EQ(s_baseWeakReferences, 2u); |
724 | EXPECT_EQ(weakHashSet.computeSize(), 1u); |
725 | EXPECT_EQ(s_baseWeakReferences, 1u); |
726 | weakHashSet.checkConsistency(); |
727 | weakHashSet.remove(object1); |
728 | EXPECT_EQ(s_baseWeakReferences, 1u); |
729 | EXPECT_EQ(weakHashSet.computeSize(), 0u); |
730 | EXPECT_EQ(s_baseWeakReferences, 1u); |
731 | weakHashSet.checkConsistency(); |
732 | } |
733 | EXPECT_EQ(s_baseWeakReferences, 0u); |
734 | weakHashSet.checkConsistency(); |
735 | } |
736 | |
737 | while (1) { |
738 | WeakHashSet<Base> weakHashSet; |
739 | auto firstObject = std::make_unique<Base>(); |
740 | auto lastObject = std::make_unique<Base>(); |
741 | weakHashSet.add(*firstObject); |
742 | weakHashSet.add(*lastObject); |
743 | if (weakHashSet.begin().get() != firstObject.get()) |
744 | continue; |
745 | EXPECT_EQ(s_baseWeakReferences, 2u); |
746 | EXPECT_EQ(weakHashSet.computeSize(), 2u); |
747 | EXPECT_EQ(s_baseWeakReferences, 2u); |
748 | weakHashSet.checkConsistency(); |
749 | firstObject = nullptr; |
750 | EXPECT_EQ(weakHashSet.computeSize(), 1u); |
751 | EXPECT_EQ(s_baseWeakReferences, 1u); |
752 | weakHashSet.checkConsistency(); |
753 | lastObject = nullptr; |
754 | EXPECT_EQ(s_baseWeakReferences, 1u); |
755 | EXPECT_EQ(weakHashSet.computeSize(), 0u); |
756 | EXPECT_EQ(s_baseWeakReferences, 0u); |
757 | weakHashSet.checkConsistency(); |
758 | break; |
759 | } |
760 | |
761 | { |
762 | WeakHashSet<Base> weakHashSet; |
763 | Vector<std::unique_ptr<Base>> objects; |
764 | auto nonFirstObject = std::make_unique<Base>(); |
765 | weakHashSet.add(*nonFirstObject); |
766 | do { |
767 | auto object = std::make_unique<Base>(); |
768 | weakHashSet.add(*object); |
769 | objects.append(WTFMove(object)); |
770 | } while (weakHashSet.begin().get() == nonFirstObject.get()); |
771 | |
772 | unsigned objectsCount = objects.size(); |
773 | EXPECT_EQ(s_baseWeakReferences, objectsCount + 1); |
774 | EXPECT_EQ(weakHashSet.computeSize(), objectsCount + 1); |
775 | EXPECT_EQ(s_baseWeakReferences, objectsCount + 1); |
776 | weakHashSet.checkConsistency(); |
777 | nonFirstObject = nullptr; |
778 | EXPECT_EQ(weakHashSet.computeSize(), objectsCount); |
779 | EXPECT_EQ(s_baseWeakReferences, objectsCount); |
780 | weakHashSet.checkConsistency(); |
781 | objects.clear(); |
782 | EXPECT_EQ(s_baseWeakReferences, objectsCount); |
783 | EXPECT_EQ(weakHashSet.computeSize(), 0u); |
784 | EXPECT_EQ(s_baseWeakReferences, 0u); |
785 | } |
786 | } |
787 | |
788 | } // namespace TestWebKitAPI |
789 | |