WeakPtr breaks vtables when upcasting to base classes
[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 static unsigned s_baseWeakReferences = 0;
29
30 #define DID_CREATE_WEAK_REFERENCE(p) do { \
31     ++s_baseWeakReferences; \
32 } while (0);
33
34 #define WILL_DESTROY_WEAK_REFERENCE(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