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
28static 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
43namespace TestWebKitAPI {
44
45struct 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
52class Base : public CanMakeWeakPtr<Base> {
53public:
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
64class Derived : public Base {
65public:
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
78namespace TestWebKitAPI {
79
80TEST(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
105TEST(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
118TEST(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
138TEST(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
154struct Foo : public CanMakeWeakPtr<Foo> {
155 void bar() { };
156};
157
158TEST(WTF_WeakPtr, Dereference)
159{
160 Foo f;
161 WeakPtrFactory<Foo> factory;
162 WeakPtr<Foo> weakPtr = factory.createWeakPtr(f);
163 weakPtr->bar();
164}
165
166TEST(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
184TEST(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
249TEST(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
279TEST(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
313TEST(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
347template <typename T>
348unsigned 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
358template <typename T>
359unsigned 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
369TEST(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
493TEST(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
559TEST(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
636TEST(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
688TEST(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