Unreviewed, rolling out r245857.
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WTF / WeakPtr.cpp
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