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