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
33static unsigned s_baseWeakReferences = 0;
34
35namespace TestWebKitAPI {
36
37class Base {
38public:
39 Base() { }
40
41 int foo()
42 {
43 return 0;
44 }
45
46 auto& weakPtrFactory() const { return m_weakPtrFactory; }
47
48private:
49 WeakPtrFactory<Base> m_weakPtrFactory;
50};
51
52class Derived : public Base {
53public:
54 Derived() { }
55
56 int foo()
57 {
58 return 1;
59 }
60};
61
62}
63
64namespace WTF {
65
66template<>
67WeakReference<TestWebKitAPI::Base>::WeakReference(TestWebKitAPI::Base* ptr)
68 : m_ptr(ptr)
69{
70 ++s_baseWeakReferences;
71}
72template<>
73WeakReference<TestWebKitAPI::Base>::~WeakReference()
74{
75 --s_baseWeakReferences;
76}
77
78}
79
80namespace TestWebKitAPI {
81
82TEST(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
107TEST(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
120TEST(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
140TEST(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
156struct Foo {
157 void bar() { };
158};
159
160TEST(WTF_WeakPtr, Dereference)
161{
162 Foo f;
163 WeakPtrFactory<Foo> factory;
164 WeakPtr<Foo> weakPtr = factory.createWeakPtr(f);
165 weakPtr->bar();
166}
167
168TEST(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
186TEST(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
251TEST(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
281TEST(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
315TEST(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
349template <typename T>
350unsigned 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
360template <typename T>
361unsigned 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
371TEST(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
495TEST(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
561TEST(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
638TEST(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
690TEST(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