/*
 * Copyright (C) 2011 Google Inc. All rights reserved.
 * Copyright (C) 2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include "Counters.h"
#include "DeletedAddressOfOperator.h"
#include "MoveOnly.h"
#include "RefLogger.h"
#include "Test.h"
#include <string>
#include <wtf/HashMap.h>
#include <wtf/InlineWeakPtr.h>
#include <wtf/Ref.h>
#include <wtf/RefCountedAndCanMakeWeakPtr.h>
#include <wtf/RefCountedWithInlineWeakPtr.h>
#include <wtf/UniqueRef.h>
#include <wtf/WeakPtr.h>
#include <wtf/text/MakeString.h>
#include <wtf/text/StringHash.h>

namespace {

class InlineWeakPtrObject : public RefCountedWithInlineWeakPtr<InlineWeakPtrObject> {
    WTF_DEPRECATED_MAKE_FAST_ALLOCATED(InlineWeakPtrObject);
public:
    static Ref<InlineWeakPtrObject> create()
    {
        return adoptRef(*new InlineWeakPtrObject);
    }
};

}

namespace TestWebKitAPI {

typedef WTF::HashMap<int, int> IntHashMap;

TEST(WTF_HashMap, HashTableIteratorComparison)
{
    IntHashMap map;
    map.add(1, 2);
    ASSERT_TRUE(map.begin() != map.end());
    ASSERT_FALSE(map.begin() == map.end());

    IntHashMap::const_iterator begin = map.begin();
    ASSERT_TRUE(begin == map.begin());
    ASSERT_TRUE(map.begin() == begin);
    ASSERT_TRUE(begin != map.end());
    ASSERT_TRUE(map.end() != begin);
    ASSERT_FALSE(begin != map.begin());
    ASSERT_FALSE(map.begin() != begin);
    ASSERT_FALSE(begin == map.end());
    ASSERT_FALSE(map.end() == begin);
}

struct TestDoubleHashTraits : HashTraits<double> {
    static constexpr unsigned minimumTableSize = 8;
};

typedef HashMap<double, int64_t, DefaultHash<double>, TestDoubleHashTraits> DoubleHashMap;

static int bucketForKey(double key)
{
    return DefaultHash<double>::hash(key) & (TestDoubleHashTraits::minimumTableSize - 1);
}

template<typename T> struct BigTableHashTraits : public HashTraits<T> {
    static const int minimumTableSize = WTF::HashTableCapacityForSize<4096>::value;
};

template<typename T> struct ZeroHash : public IntHash<T> {
    static unsigned hash(const T&) { return 0; }
};

TEST(WTF_HashMap, DoubleHashCollisions)
{
    // The "clobber" key here is one that ends up stealing the bucket that the -0 key
    // originally wants to be in. This makes the 0 and -0 keys collide and the test then
    // fails unless the FloatHash::equals() implementation can distinguish them.
    const double clobberKey = 6;
    const double zeroKey = 0;
    const double negativeZeroKey = -zeroKey;

    DoubleHashMap map;
#if !CHECK_HASHTABLE_ITERATORS &&!DUMP_HASHTABLE_STATS_PER_TABLE
    static_assert(sizeof(map) == sizeof(void*));
#endif

    map.add(clobberKey, 1);
    map.add(zeroKey, 2);
    map.add(negativeZeroKey, 3);

    ASSERT_EQ(bucketForKey(clobberKey), bucketForKey(negativeZeroKey));
    ASSERT_EQ(map.get(clobberKey), 1);
    ASSERT_EQ(map.get(zeroKey), 2);
    ASSERT_EQ(map.get(negativeZeroKey), 3);
}

TEST(WTF_HashMap, MoveOnlyValues)
{
    HashMap<unsigned, MoveOnly> moveOnlyValues;

    for (size_t i = 0; i < 100; ++i) {
        MoveOnly moveOnly(i + 1);
        moveOnlyValues.set(i + 1, WTF::move(moveOnly));
    }

    for (size_t i = 0; i < 100; ++i) {
        auto it = moveOnlyValues.find(i + 1);
        ASSERT_FALSE(it == moveOnlyValues.end());
    }

    for (size_t i = 0; i < 50; ++i)
        ASSERT_EQ(moveOnlyValues.take(i + 1).value(), i + 1);

    for (size_t i = 50; i < 100; ++i)
        ASSERT_TRUE(moveOnlyValues.remove(i + 1));

    ASSERT_TRUE(moveOnlyValues.isEmpty());
}

TEST(WTF_HashMap, MoveOnlyKeys)
{
    HashMap<MoveOnly, unsigned> moveOnlyKeys;

    for (size_t i = 0; i < 100; ++i) {
        MoveOnly moveOnly(i + 1);
        moveOnlyKeys.set(WTF::move(moveOnly), i + 1);
    }

    for (size_t i = 0; i < 100; ++i) {
        auto it = moveOnlyKeys.find(MoveOnly(i + 1));
        ASSERT_FALSE(it == moveOnlyKeys.end());
    }

    for (size_t i = 0; i < 100; ++i)
        ASSERT_FALSE(moveOnlyKeys.add(MoveOnly(i + 1), i + 1).isNewEntry);

    for (size_t i = 0; i < 100; ++i)
        ASSERT_TRUE(moveOnlyKeys.remove(MoveOnly(i + 1)));

    ASSERT_TRUE(moveOnlyKeys.isEmpty());
}

TEST(WTF_HashMap, InitializerList)
{
    HashMap<unsigned, std::string> map = {
        { 1, "one" },
        { 2, "two" },
        { 3, "three" },
        { 4, "four" },
    };

    EXPECT_EQ(4u, map.size());

    EXPECT_EQ("one", map.get(1));
    EXPECT_EQ("two", map.get(2));
    EXPECT_EQ("three", map.get(3));
    EXPECT_EQ("four", map.get(4));
    EXPECT_EQ(std::string(), map.get(5));
}

TEST(WTF_HashMap, EfficientGetter)
{
    HashMap<unsigned, CopyMoveCounter> map;
    map.set(1, CopyMoveCounter());

    {
        CopyMoveCounter::TestingScope scope;
        map.get(1);
        EXPECT_EQ(0U, CopyMoveCounter::constructionCount);
        EXPECT_EQ(1U, CopyMoveCounter::copyCount);
        EXPECT_EQ(0U, CopyMoveCounter::moveCount);
    }

    {
        CopyMoveCounter::TestingScope scope;
        map.get(2);
        EXPECT_EQ(1U, CopyMoveCounter::constructionCount);
        EXPECT_EQ(0U, CopyMoveCounter::copyCount);
        EXPECT_EQ(1U, CopyMoveCounter::moveCount);
    }
}

TEST(WTF_HashMap, UniquePtrKey)
{
    ConstructorDestructorCounter::TestingScope scope;

    HashMap<std::unique_ptr<ConstructorDestructorCounter>, int> map;

    auto uniquePtr = makeUnique<ConstructorDestructorCounter>();
    map.add(WTF::move(uniquePtr), 2);

    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);

    map.clear();
    
    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
}

TEST(WTF_HashMap, UniquePtrKey_CustomDeleter)
{
    ConstructorDestructorCounter::TestingScope constructorDestructorCounterScope;
    DeleterCounter<ConstructorDestructorCounter>::TestingScope deleterCounterScope;

    HashMap<std::unique_ptr<ConstructorDestructorCounter, DeleterCounter<ConstructorDestructorCounter>>, int> map;

    std::unique_ptr<ConstructorDestructorCounter, DeleterCounter<ConstructorDestructorCounter>> uniquePtr(new ConstructorDestructorCounter(), DeleterCounter<ConstructorDestructorCounter>());
    map.add(WTF::move(uniquePtr), 2);

    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);

    EXPECT_EQ(0u, DeleterCounter<ConstructorDestructorCounter>::deleterCount());

    map.clear();
    
    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);

    EXPECT_EQ(1u, DeleterCounter<ConstructorDestructorCounter>::deleterCount());
}

TEST(WTF_HashMap, UniquePtrKey_FindUsingRawPointer)
{
    HashMap<std::unique_ptr<int>, int> map;

    auto uniquePtr = makeUniqueWithoutFastMallocCheck<int>(5);
    int* ptr = uniquePtr.get();
    map.add(WTF::move(uniquePtr), 2);

    auto it = map.find(ptr);
    ASSERT_TRUE(it != map.end());
    EXPECT_EQ(ptr, it->key.get());
    EXPECT_EQ(2, it->value);
}

TEST(WTF_HashMap, UniquePtrKey_ContainsUsingRawPointer)
{
    HashMap<std::unique_ptr<int>, int> map;

    auto uniquePtr = makeUniqueWithoutFastMallocCheck<int>(5);
    int* ptr = uniquePtr.get();
    map.add(WTF::move(uniquePtr), 2);

    EXPECT_EQ(true, map.contains(ptr));
}

TEST(WTF_HashMap, UniquePtrKey_GetUsingRawPointer)
{
    HashMap<std::unique_ptr<int>, int> map;

    auto uniquePtr = makeUniqueWithoutFastMallocCheck<int>(5);
    int* ptr = uniquePtr.get();
    map.add(WTF::move(uniquePtr), 2);

    int value = map.get(ptr);
    EXPECT_EQ(2, value);
}

TEST(WTF_HashMap, UniquePtrKey_RemoveUsingRawPointer)
{
    ConstructorDestructorCounter::TestingScope scope;

    HashMap<std::unique_ptr<ConstructorDestructorCounter>, int> map;

    auto uniquePtr = makeUnique<ConstructorDestructorCounter>();
    ConstructorDestructorCounter* ptr = uniquePtr.get();
    map.add(WTF::move(uniquePtr), 2);

    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);

    bool result = map.remove(ptr);
    EXPECT_EQ(true, result);

    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
}

TEST(WTF_HashMap, UniquePtrKey_TakeUsingRawPointer)
{
    ConstructorDestructorCounter::TestingScope scope;

    HashMap<std::unique_ptr<ConstructorDestructorCounter>, int> map;

    auto uniquePtr = makeUnique<ConstructorDestructorCounter>();
    ConstructorDestructorCounter* ptr = uniquePtr.get();
    map.add(WTF::move(uniquePtr), 2);

    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);

    int result = map.take(ptr);
    EXPECT_EQ(2, result);

    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
}

TEST(WTF_HashMap, UniqueRefValue)
{
    HashMap<int, UniqueRef<int>> map;
    UniqueRef<int> five = makeUniqueRefWithoutFastMallocCheck<int>(5);
    map.add(5, WTF::move(five));
    EXPECT_TRUE(map.contains(5));
    int* shouldBeFive = map.get(5);
    EXPECT_EQ(*shouldBeFive, 5);
    std::unique_ptr<int> takenFive = map.take(5);
    EXPECT_EQ(*takenFive, 5);
    map.ensure(6, [] {
        return makeUniqueRefWithoutFastMallocCheck<int>(6);
    });
    EXPECT_FALSE(map.contains(5));
    EXPECT_TRUE(map.contains(6));
    for (UniqueRef<int>& a : map.values())
        EXPECT_EQ(a.get(), 6);
}

TEST(WTF_HashMap, RefPtrKey_Add)
{
    {
        DerivedRefLogger a("a");

        HashMap<RefPtr<RefLogger>, int> map;

        RefPtr<RefLogger> ptr(&a);
        map.add(ptr, 0);
    }

    ASSERT_STREQ("ref(a) ref(a) deref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashMap, RefPtrKey_AddUsingRelease)
{
    {
        DerivedRefLogger a("a");

        HashMap<RefPtr<RefLogger>, int> map;

        RefPtr<RefLogger> ptr(&a);
        map.add(WTF::move(ptr), 0);
    }

    EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashMap, RefPtrKey_AddUsingMove)
{
    {
        DerivedRefLogger a("a");

        HashMap<RefPtr<RefLogger>, int> map;

        RefPtr<RefLogger> ptr(&a);
        map.add(WTF::move(ptr), 0);
    }

    EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashMap, RefPtrKey_AddUsingRaw)
{
    {
        DerivedRefLogger a("a");

        HashMap<RefPtr<RefLogger>, int> map;

        RefPtr<RefLogger> ptr(&a);
        map.add(ptr.get(), 0);
    }

    EXPECT_STREQ("ref(a) ref(a) deref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashMap, RefPtrKey_AddKeyAlreadyPresent)
{
    DerivedRefLogger a("a");

    HashMap<RefPtr<RefLogger>, int> map;

    {
        RefPtr<RefLogger> ptr(&a);
        map.add(ptr, 0);
    }

    EXPECT_STREQ("ref(a) ref(a) deref(a) ", takeLogStr().c_str());

    {
        RefPtr<RefLogger> ptr2(&a);
        auto addResult = map.add(ptr2, 0);
        EXPECT_FALSE(addResult.isNewEntry);
    }

    EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

    map.clear();

    EXPECT_STREQ("deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashMap, RefPtrKey_AddUsingReleaseKeyAlreadyPresent)
{
    DerivedRefLogger a("a");

    HashMap<RefPtr<RefLogger>, int> map;

    {
        RefPtr<RefLogger> ptr(&a);
        map.add(ptr, 0);
    }

    EXPECT_STREQ("ref(a) ref(a) deref(a) ", takeLogStr().c_str());

    {
        RefPtr<RefLogger> ptr2(&a);
        auto addResult = map.add(WTF::move(ptr2), 0);
        EXPECT_FALSE(addResult.isNewEntry);
    }

    EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

    map.clear();

    EXPECT_STREQ("deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashMap, RefPtrKey_AddUsingMoveKeyAlreadyPresent)
{
    DerivedRefLogger a("a");

    HashMap<RefPtr<RefLogger>, int> map;

    {
        RefPtr<RefLogger> ptr(&a);
        map.add(ptr, 0);
    }

    EXPECT_STREQ("ref(a) ref(a) deref(a) ", takeLogStr().c_str());

    {
        RefPtr<RefLogger> ptr2(&a);
        auto addResult = map.add(WTF::move(ptr2), 0);
        EXPECT_FALSE(addResult.isNewEntry);
    }

    EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

    map.clear();

    EXPECT_STREQ("deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashMap, RefPtrKey_Set)
{
    {
        DerivedRefLogger a("a");

        HashMap<RefPtr<RefLogger>, int> map;

        RefPtr<RefLogger> ptr(&a);
        map.set(ptr, 0);
    }

    ASSERT_STREQ("ref(a) ref(a) deref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashMap, RefPtrKey_SetUsingRelease)
{
    {
        DerivedRefLogger a("a");

        HashMap<RefPtr<RefLogger>, int> map;

        RefPtr<RefLogger> ptr(&a);
        map.set(WTF::move(ptr), 0);
    }

    EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
}


TEST(WTF_HashMap, RefPtrKey_SetUsingMove)
{
    {
        DerivedRefLogger a("a");

        HashMap<RefPtr<RefLogger>, int> map;

        RefPtr<RefLogger> ptr(&a);
        map.set(WTF::move(ptr), 0);
    }

    EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashMap, RefPtrKey_SetUsingRaw)
{
    {
        DerivedRefLogger a("a");

        HashMap<RefPtr<RefLogger>, int> map;

        RefPtr<RefLogger> ptr(&a);
        map.set(ptr.get(), 0);
    }

    EXPECT_STREQ("ref(a) ref(a) deref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashMap, RefPtrKey_SetKeyAlreadyPresent)
{
    {
        DerivedRefLogger a("a");

        HashMap<RefPtr<RefLogger>, int> map;

        RefPtr<RefLogger> ptr(&a);
        map.set(ptr, 0);

        EXPECT_STREQ("ref(a) ref(a) ", takeLogStr().c_str());

        {
            RefPtr<RefLogger> ptr2(&a);
            auto addResult = map.set(ptr2, 1);
            EXPECT_FALSE(addResult.isNewEntry);
            EXPECT_EQ(1, map.get(ptr.get()));
        }

        EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
    }

    EXPECT_STREQ("deref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashMap, RefPtrKey_SetUsingReleaseKeyAlreadyPresent)
{
    {
        DerivedRefLogger a("a");

        HashMap<RefPtr<RefLogger>, int> map;

        RefPtr<RefLogger> ptr(&a);
        map.set(ptr, 0);

        EXPECT_STREQ("ref(a) ref(a) ", takeLogStr().c_str());

        {
            RefPtr<RefLogger> ptr2(&a);
            auto addResult = map.set(WTF::move(ptr2), 1);
            EXPECT_FALSE(addResult.isNewEntry);
            EXPECT_EQ(1, map.get(ptr.get()));
        }

        EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
    }

    EXPECT_STREQ("deref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashMap, RefPtrKey_SetUsingMoveKeyAlreadyPresent)
{
    {
        DerivedRefLogger a("a");

        HashMap<RefPtr<RefLogger>, int> map;

        RefPtr<RefLogger> ptr(&a);
        map.set(ptr, 0);

        EXPECT_STREQ("ref(a) ref(a) ", takeLogStr().c_str());

        {
            RefPtr<RefLogger> ptr2(&a);
            auto addResult = map.set(WTF::move(ptr2), 1);
            EXPECT_FALSE(addResult.isNewEntry);
            EXPECT_EQ(1, map.get(ptr.get()));
        }

        EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
    }

    EXPECT_STREQ("deref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashMap, Ensure)
{
    HashMap<unsigned, unsigned> map;
    {
        auto addResult = map.ensure(1, [] { return 1; });
        EXPECT_EQ(1u, addResult.iterator->value);
        EXPECT_EQ(1u, addResult.iterator->key);
        EXPECT_TRUE(addResult.isNewEntry);
        auto addResult2 = map.ensure(1, [] { return 2; });
        EXPECT_EQ(1u, addResult2.iterator->value);
        EXPECT_EQ(1u, addResult2.iterator->key);
        EXPECT_FALSE(addResult2.isNewEntry);
    }
}

TEST(WTF_HashMap, Ensure_MoveOnlyValues)
{
    HashMap<unsigned, MoveOnly> moveOnlyValues;
    {
        auto addResult = moveOnlyValues.ensure(1, [] { return MoveOnly(1); });
        EXPECT_EQ(1u, addResult.iterator->value.value());
        EXPECT_EQ(1u, addResult.iterator->key);
        EXPECT_TRUE(addResult.isNewEntry);
        auto addResult2 = moveOnlyValues.ensure(1, [] { return MoveOnly(2); });
        EXPECT_EQ(1u, addResult2.iterator->value.value());
        EXPECT_EQ(1u, addResult2.iterator->key);
        EXPECT_FALSE(addResult2.isNewEntry);
    }
}

TEST(WTF_HashMap, Ensure_UniquePointer)
{
    HashMap<unsigned, std::unique_ptr<unsigned>> map;
    {
        auto addResult = map.ensure(1, [] { return makeUniqueWithoutFastMallocCheck<unsigned>(1); });
        EXPECT_EQ(1u, *map.get(1));
        EXPECT_EQ(1u, *addResult.iterator->value.get());
        EXPECT_EQ(1u, addResult.iterator->key);
        EXPECT_TRUE(addResult.isNewEntry);
        auto addResult2 = map.ensure(1, [] { return makeUniqueWithoutFastMallocCheck<unsigned>(2); });
        EXPECT_EQ(1u, *map.get(1));
        EXPECT_EQ(1u, *addResult2.iterator->value.get());
        EXPECT_EQ(1u, addResult2.iterator->key);
        EXPECT_FALSE(addResult2.isNewEntry);
    }
}

TEST(WTF_HashMap, Ensure_RefPtr)
{
    DerivedRefLogger a("a");

    HashMap<unsigned, RefPtr<RefLogger>> map;

    map.ensure(1, [&] { return RefPtr<RefLogger>(&a); });
    EXPECT_STREQ("ref(a) ", takeLogStr().c_str());

    map.ensure(1, [&] { return RefPtr<RefLogger>(&a); });
    EXPECT_STREQ("", takeLogStr().c_str());

    map.clear();

    EXPECT_STREQ("deref(a) ", takeLogStr().c_str());
}

class ObjectWithRefLogger {
    WTF_DEPRECATED_MAKE_FAST_ALLOCATED(ObjectWithRefLogger);
public:
    ObjectWithRefLogger(Ref<RefLogger>&& logger)
        : m_logger(WTF::move(logger))
    {
    }

    Ref<RefLogger> m_logger;
};


static void testMovingUsingEnsure(Ref<RefLogger>&& logger)
{
    HashMap<unsigned, std::unique_ptr<ObjectWithRefLogger>> map;
    
    map.ensure(1, [&] { return makeUnique<ObjectWithRefLogger>(WTF::move(logger)); });
}

static void testMovingUsingAdd(Ref<RefLogger>&& logger)
{
    HashMap<unsigned, std::unique_ptr<ObjectWithRefLogger>> map;

    auto& slot = map.add(1, nullptr).iterator->value;
    slot = makeUnique<ObjectWithRefLogger>(WTF::move(logger));
}

TEST(WTF_HashMap, Ensure_LambdasCapturingByReference)
{
    {
        DerivedRefLogger a("a");
        Ref<RefLogger> ref(a);
        testMovingUsingEnsure(WTF::move(ref));

        EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
    }

    {
        DerivedRefLogger a("a");
        Ref<RefLogger> ref(a);
        testMovingUsingAdd(WTF::move(ref));

        EXPECT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());
    }
}


TEST(WTF_HashMap, ValueIsDestructedOnRemove)
{
    struct DestructorObserver {
        DestructorObserver() = default;

        DestructorObserver(bool* destructed)
            : destructed(destructed)
        {
        }

        ~DestructorObserver()
        {
            if (destructed)
                *destructed = true;
        }

        DestructorObserver(DestructorObserver&& other)
            : destructed(other.destructed)
        {
            other.destructed = nullptr;
        }

        DestructorObserver& operator=(DestructorObserver&& other)
        {
            destructed = other.destructed;
            other.destructed = nullptr;
            return *this;
        }

        bool* destructed { nullptr };
    };

    HashMap<int, DestructorObserver> map;

    bool destructed = false;
    map.add(5, DestructorObserver { &destructed });

    EXPECT_FALSE(destructed);

    bool removeResult = map.remove(5);

    EXPECT_TRUE(removeResult);
    EXPECT_TRUE(destructed);
}

struct DerefObserver {
    WTF_DEPRECATED_MAKE_STRUCT_FAST_ALLOCATED(DerefObserver);
    NEVER_INLINE void ref()
    {
        ++count;
    }
    NEVER_INLINE void deref()
    {
        --count;
        observedBucket = bucketAddress->get();
    }
    unsigned count { 1 };
    const RefPtr<DerefObserver>* bucketAddress { nullptr };
    const DerefObserver* observedBucket { nullptr };
};

TEST(WTF_HashMap, RefPtrNotZeroedBeforeDeref)
{
    auto observer = makeUniqueWithoutRefCountedCheck<DerefObserver>();

    HashMap<RefPtr<DerefObserver>, int> map;
    map.add(adoptRef(observer.get()), 5);

    auto iterator = map.find(observer.get());
    EXPECT_TRUE(iterator != map.end());

    observer->bucketAddress = &iterator->key;

    EXPECT_TRUE(observer->observedBucket == nullptr);
    EXPECT_TRUE(map.remove(observer.get()));

    // It if fine to either leave the old value intact at deletion or already set it to the deleted
    // value.
    // A zero would be a incorrect outcome as it would mean we nulled the bucket before an opaque
    // call.
    EXPECT_TRUE(observer->observedBucket == observer.get() || observer->observedBucket == RefPtr<DerefObserver>::PtrTraits::hashTableDeletedValue());
    EXPECT_EQ(observer->count, 0u);
}

TEST(WTF_HashMap, Ref_Key)
{
    {
        RefLogger a("a");

        HashMap<Ref<RefLogger>, int> map;

        Ref<RefLogger> ref(a);
        map.add(WTF::move(ref), 1);
    }

    ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

    {
        RefLogger a("a");

        HashMap<Ref<RefLogger>, int> map;

        Ref<RefLogger> ref(a);
        map.set(WTF::move(ref), 1);
    }

    ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

    {
        RefLogger a("a");

        HashMap<Ref<RefLogger>, int> map;

        Ref<RefLogger> refA(a);
        map.add(WTF::move(refA), 1);

        Ref<RefLogger> refA2(a);
        map.set(WTF::move(refA2), 1);
    }

    ASSERT_STREQ("ref(a) ref(a) deref(a) deref(a) ", takeLogStr().c_str());

    {
        RefLogger a("a");

        HashMap<Ref<RefLogger>, int> map;

        Ref<RefLogger> ref(a);
        map.ensure(WTF::move(ref), []() { 
            return 1; 
        });
    }

    ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

    {
        RefLogger a("a");

        HashMap<Ref<RefLogger>, int> map;

        Ref<RefLogger> ref(a);
        map.add(WTF::move(ref), 1);
        
        auto it = map.find(&a);
        ASSERT_TRUE(it != map.end());
        
        ASSERT_EQ(it->key.ptr(), &a);
        ASSERT_EQ(it->value, 1);
    }

    ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

    {
        RefLogger a("a");

        HashMap<Ref<RefLogger>, int> map;

        Ref<RefLogger> ref(a);
        map.add(WTF::move(ref), 1);

        map.remove(&a);
    }

    ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

    {
        RefLogger a("a");

        HashMap<Ref<RefLogger>, int> map;

        Ref<RefLogger> ref(a);
        map.add(WTF::move(ref), 1);

        int i = map.take(&a);
        ASSERT_EQ(i, 1);
    }

    ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

    {
        HashMap<Ref<RefLogger>, int> map;
        for (int i = 0; i < 64; ++i) {
            // FIXME: All of these RefLogger objects leak. No big deal for a test I guess.
            Ref<RefLogger> ref = adoptRef(*new RefLogger("a"));
            auto* pointer = ref.ptr();
            map.add(WTF::move(ref), i + 1);
            ASSERT_TRUE(map.contains(pointer));
        }
    }

    ASSERT_STREQ("deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashMap, Ref_Value)
{
    {
        RefLogger a("a");

        HashMap<int, Ref<RefLogger>> map;

        Ref<RefLogger> ref(a);
        map.add(1, WTF::move(ref));
    }

    ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

    {
        RefLogger a("a");

        HashMap<int, Ref<RefLogger>> map;

        Ref<RefLogger> ref(a);
        map.set(1, WTF::move(ref));
    }

    ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

    {
        RefLogger a("a");
        RefLogger b("b");

        HashMap<int, Ref<RefLogger>> map;

        Ref<RefLogger> refA(a);
        map.add(1, WTF::move(refA));

        Ref<RefLogger> refB(b);
        map.set(1, WTF::move(refB));
    }

    ASSERT_STREQ("ref(a) ref(b) deref(a) deref(b) ", takeLogStr().c_str());

    {
        RefLogger a("a");

        HashMap<int, Ref<RefLogger>> map;

        Ref<RefLogger> ref(a);
        map.add(1, WTF::move(ref));
        
        auto aGet = map.get(1);
        ASSERT_EQ(aGet, &a);
    }

    ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

    {
        HashMap<int, Ref<RefLogger>> map;
        
        auto emptyGet = map.get(1);
        ASSERT_TRUE(emptyGet == nullptr);
    }

    {
        RefLogger a("a");

        HashMap<int, Ref<RefLogger>> map;

        Ref<RefLogger> ref(a);
        map.add(1, WTF::move(ref));
        
        auto aOut = map.take(1);
        ASSERT_TRUE(static_cast<bool>(aOut));
        ASSERT_EQ(&a, aOut.get());
    }

    ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

    {
        HashMap<int, Ref<RefLogger>> map;
        
        auto emptyTake = map.take(1);
        ASSERT_FALSE(static_cast<bool>(emptyTake));
    }

    {
        RefLogger a("a");

        HashMap<int, Ref<RefLogger>> map;

        Ref<RefLogger> ref(a);
        map.add(1, WTF::move(ref));
        map.remove(1);
    }

    ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

    {
        RefLogger a("a");

        HashMap<int, Ref<RefLogger>> map;

        map.ensure(1, [&] {
            Ref<RefLogger> ref(a);
            return ref; 
        });
    }

    ASSERT_STREQ("ref(a) deref(a) ", takeLogStr().c_str());

    {
        HashMap<int, Ref<RefLogger>> map;
        for (int i = 0; i < 64; ++i) {
            // FIXME: All of these RefLogger objects leak. No big deal for a test I guess.
            Ref<RefLogger> ref = adoptRef(*new RefLogger("a"));
            map.add(i + 1, WTF::move(ref));
            ASSERT_TRUE(map.contains(i + 1));
        }
    }

    ASSERT_STREQ("deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) deref(a) ", takeLogStr().c_str());
}

TEST(WTF_HashMap, DeletedAddressOfOperator)
{
    HashMap<int, DeletedAddressOfOperator> map1;
    for (auto& value : map1.values())
        (void)value;
}

TEST(WTF_HashMap, RefMappedToNonZeroEmptyValue)
{
    class Value {
    public:
        Value() = default;
        Value(Value&&) = default;
        Value(const Value&) = default;
        Value& operator=(Value&&) = default;

        Value(int32_t f)
            : m_field(f)
        { }

        int32_t field() { return m_field; }

    private:
        int32_t m_field { 0xbadbeef };
    };

    class Key : public RefCounted<Key> {
        Key() = default;
    public:
        static Ref<Key> create() { return adoptRef(*new Key); }
    };

    static_assert(!WTF::HashTraits<Value>::emptyValueIsZero);

    HashMap<Ref<Key>, Value> map;
    Vector<std::pair<Ref<Key>, int32_t>> vectorMap;

    for (int32_t i = 0; i < 160; ++i) {
        Ref<Key> key = Key::create();
        map.add(Ref<Key>(key.get()), Value { i });
        vectorMap.append({ WTF::move(key), i });
    }

    for (auto& pair : vectorMap)
        ASSERT_EQ(pair.second, map.get(pair.first).field());

    for (auto& pair : vectorMap)
        ASSERT_TRUE(map.remove(pair.first));
}

TEST(WTF_HashMap, Random_Empty)
{
    HashMap<unsigned, unsigned> map;

    auto result = map.random();
    ASSERT_EQ(result, map.end());
}

TEST(WTF_HashMap, Random_WrapAround)
{
    HashMap<unsigned, unsigned, ZeroHash<unsigned>, BigTableHashTraits<unsigned>> map;
    map.add(1, 1);

    auto result = map.random();
    ASSERT_EQ(result, map.begin());
}

TEST(WTF_HashMap, Random_IsEvenlyDistributed)
{
    HashMap<unsigned, unsigned, DefaultHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> map;
    map.add(0, 0);
    map.add(1, 1);

    unsigned zeros = 0;
    unsigned ones = 0;

    for (unsigned i = 0; i < 1000; ++i) {
        auto it = map.random();
        if (!it->value)
            ++zeros;
        else {
            ASSERT_EQ(it->value, 1u);
            ++ones;
        }
    }

    ASSERT_EQ(zeros + ones, 1000u);
    ASSERT_LE(zeros, 600u);
    ASSERT_LE(ones, 600u);
}

TEST(WTF_HashMap, ReserveInitialCapacity)
{
    HashMap<String, String> map;
    EXPECT_EQ(0u, map.size());
    EXPECT_EQ(0u, map.capacity());

    map.reserveInitialCapacity(9999);
    EXPECT_EQ(0u, map.size());
    EXPECT_EQ(32768u, map.capacity());

    for (int i = 0; i < 9999; ++i)
        map.add(makeString("foo"_s, i), makeString("bar"_s, i));
    EXPECT_EQ(9999u, map.size());
    EXPECT_EQ(32768u, map.capacity());
    EXPECT_TRUE(map.contains("foo3"_str));
    EXPECT_STREQ("bar3", map.get("foo3"_str).utf8().data());

    for (int i = 0; i < 9999; ++i)
        map.add(makeString("excess"_s, i), makeString("baz"_s, i));
    EXPECT_EQ(9999u + 9999u, map.size());
    EXPECT_EQ(32768u + 32768u, map.capacity());

    for (int i = 0; i < 9999; ++i)
        EXPECT_TRUE(map.remove(makeString("foo"_s, i)));
    EXPECT_EQ(9999u, map.size());
    EXPECT_EQ(32768u, map.capacity());
    EXPECT_STREQ("baz3", map.get("excess3"_str).utf8().data());

    for (int i = 0; i < 9999; ++i)
        EXPECT_TRUE(map.remove(makeString("excess"_s, i)));
    EXPECT_EQ(0u, map.size());
    EXPECT_EQ(8u, map.capacity());

    HashMap<String, String> map2;
    map2.reserveInitialCapacity(9999);
    EXPECT_FALSE(map2.remove("foo1"_s));

    for (int i = 0; i < 2000; ++i)
        map2.add(makeString("foo"_s, i), makeString("bar"_s, i));
    EXPECT_EQ(2000u, map2.size());
    EXPECT_EQ(32768u, map2.capacity());

    for (int i = 0; i < 2000; ++i)
        EXPECT_TRUE(map2.remove(makeString("foo"_s, i)));
    EXPECT_EQ(0u, map2.size());
    EXPECT_EQ(8u, map2.capacity());
}

TEST(WTF_HashMap, Random_IsEvenlyDistributedAfterRemove)
{
    for (size_t tableSize = 2; tableSize <= 2 * 6; ++tableSize) { // Our hash tables shrink at a load factor of 1 / 6.
        HashMap<unsigned, unsigned, DefaultHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> map;
        for (size_t i = 0; i < tableSize; ++i)
            map.add(i, i);
        for (size_t i = 2; i < tableSize; ++i)
            map.remove(i);

        unsigned zeros = 0;
        unsigned ones = 0;

        for (unsigned i = 0; i < 1000; ++i) {
            auto it = map.random();
            if (!it->value)
                ++zeros;
            else {
                ASSERT_EQ(it->value, 1u);
                ++ones;
            }
        }

        ASSERT_EQ(zeros + ones, 1000u);
        ASSERT_LE(zeros, 600u);
        ASSERT_LE(ones, 600u);
    }
}

class TestObjectWithCustomDestructor {
    WTF_DEPRECATED_MAKE_FAST_ALLOCATED(TestObjectWithCustomDestructor);
public:
    TestObjectWithCustomDestructor(Function<void()>&& runInDestructor)
        : m_runInDestructor(WTF::move(runInDestructor))
    { }

    ~TestObjectWithCustomDestructor()
    {
        m_runInDestructor();
    }

private:
    Function<void()> m_runInDestructor;
};

TEST(WTF_HashMap, Clear_Reenter)
{
    HashMap<uint64_t, std::unique_ptr<TestObjectWithCustomDestructor>> map;
    for (unsigned i = 1; i <= 10; ++i) {
        map.add(i, makeUnique<TestObjectWithCustomDestructor>([&map] {
            map.clear();
            EXPECT_EQ(0U, map.size());
            EXPECT_TRUE(map.isEmpty());
        }));
    }
    EXPECT_EQ(10U, map.size());
    map.clear();
    EXPECT_EQ(0U, map.size());
    EXPECT_TRUE(map.isEmpty());
}

TEST(WTF_HashMap, Set_Reenter)
{
    HashMap<uint64_t, Variant<std::unique_ptr<TestObjectWithCustomDestructor>, int>> map;
    map.add(1, makeUnique<TestObjectWithCustomDestructor>([&map] {
        auto it = map.find(1);
        EXPECT_TRUE(std::holds_alternative<std::unique_ptr<TestObjectWithCustomDestructor>>(it->value));
    }));
    map.set(1, 1);
}

TEST(WTF_HashMap, Take_Set_Reenter)
{
    HashMap<uint64_t, Variant<std::unique_ptr<TestObjectWithCustomDestructor>, int>> map;
    map.add(1, makeUnique<TestObjectWithCustomDestructor>([&map] {
        auto it = map.find(1);
        EXPECT_FALSE(std::holds_alternative<std::unique_ptr<TestObjectWithCustomDestructor>>(it->value));
    }));
    auto value = map.take(1);
    map.set(1, 1);
}

TEST(WTF_HashMap, Ensure_Translator)
{
    HashMap<String, unsigned> map;
    auto addResult = map.ensure<StringViewHashTranslator>(StringView { "foo"_s }, [] { return 1u; });
    EXPECT_TRUE(addResult.isNewEntry);
    EXPECT_TRUE(map.contains<StringViewHashTranslator>(StringView { "foo"_s }));
    EXPECT_EQ(map.size(), 1u);
    unsigned existingValue = map.get<StringViewHashTranslator>(StringView { "foo"_s });
    EXPECT_EQ(existingValue, 1u);
    existingValue = map.get<StringViewHashTranslator>("foo"_str);
    EXPECT_EQ(existingValue, 1u);
    addResult = map.ensure<StringViewHashTranslator>(StringView { "foo"_s }, [] {
        EXPECT_TRUE(false);
        return 2u;
    });
    EXPECT_FALSE(addResult.isNewEntry);
    EXPECT_EQ(map.size(), 1u);
    existingValue = map.get<StringViewHashTranslator>("foo"_str);
    EXPECT_EQ(existingValue, 1u);
    bool didRemove = map.remove<StringViewHashTranslator>(StringView { "foo"_s });
    EXPECT_TRUE(didRemove);
    EXPECT_EQ(map.size(), 0u);
}

TEST(WTF_HashMap, GetOptional)
{
    {
        struct Value {
            int a;
            int b;
        };

        HashMap<unsigned, Value> map;
        map.add(2, Value { 1, 2 });
        map.add(1000, Value { 3, 4 });

        auto optionalValue = map.getOptional(1);
        EXPECT_FALSE(optionalValue.has_value());

        optionalValue = map.getOptional(2);
        EXPECT_TRUE(optionalValue.has_value());
        EXPECT_EQ(1, optionalValue->a);
        EXPECT_EQ(2, optionalValue->b);

        optionalValue = map.getOptional(1000);
        EXPECT_TRUE(optionalValue.has_value());
        EXPECT_EQ(3, optionalValue->a);
        EXPECT_EQ(4, optionalValue->b);

        optionalValue = map.getOptional(10000);
        EXPECT_FALSE(optionalValue.has_value());
    }

    {
        struct CountedValue : public RefCounted<CountedValue> {
            CountedValue() = default;
            int a { 123 };
        };

        HashMap<unsigned, Ref<CountedValue>> map;
        map.add(2, adoptRef(*new CountedValue { }));

        auto optionalValue = map.getOptional(1);
        EXPECT_FALSE(optionalValue.has_value());

        optionalValue = map.getOptional(2);
        EXPECT_TRUE(optionalValue.has_value());
        EXPECT_EQ(123, optionalValue.value().get().a);
    }

}

TEST(WTF_HashMap, KeysValuesRangesAllAnyNoneOf)
{
    IntHashMap map;
    map.add(1, 1);
    map.add(2, 2);
    map.add(3, 3);

    EXPECT_TRUE(std::ranges::all_of(map.keys(), [] (int el) {
        return el < 4;
    }));
    EXPECT_TRUE(std::ranges::none_of(map.keys(), [] (int el) {
        return el > 4;
    }));
    EXPECT_TRUE(std::ranges::any_of(map.keys(), [] (int el) {
        return el < 2;
    }));
    EXPECT_TRUE(std::ranges::all_of(map.values(), [] (int el) {
        return el < 4;
    }));
    EXPECT_TRUE(std::ranges::none_of(map.values(), [] (int el) {
        return el > 4;
    }));
    EXPECT_TRUE(std::ranges::any_of(map.values(), [] (int el) {
        return el < 2;
    }));
}

TEST(WTF_HashMap, fromRangeConstructorBasicTypes)
{
    Vector<KeyValuePair<int, String>> pairs {
        { 1, "one"_s },
        { 2, "two"_s },
        { 3, "three"_s }
    };
    HashMap<int, String> wtfMap = pairs | rangeTo<HashMap<int, String>>();

    EXPECT_EQ(3U, wtfMap.size());
    EXPECT_EQ("one"_s, wtfMap.get(1));
    EXPECT_EQ("two"_s, wtfMap.get(2));
    EXPECT_EQ("three"_s, wtfMap.get(3));
}

TEST(WTF_HashMap, fromRangeConstructorInitializerList)
{
    auto initList = {
        KeyValuePair { 10, 100 },
        KeyValuePair(20, 200),
        KeyValuePair(30, 300)
    };
    HashMap<int, int> wtfMap(fromRange, initList);

    EXPECT_EQ(3U, wtfMap.size());
    EXPECT_EQ(100, wtfMap.get(10));
    EXPECT_EQ(200, wtfMap.get(20));
    EXPECT_EQ(300, wtfMap.get(30));
}

TEST(WTF_HashMap, fromRangeConstructorEmptyRange)
{
    Vector<KeyValuePair<int, int>> emptyVec;
    HashMap<int, int> wtfMap(fromRange, emptyVec);

    EXPECT_TRUE(wtfMap.isEmpty());
    EXPECT_EQ(0U, wtfMap.size());
}

TEST(WTF_HashMap, fromRangeConstructorMoveOnlyValues)
{
    Vector<KeyValuePair<int, MoveOnly>> stdVec;
    stdVec.append({ 1, MoveOnly { 42 } });
    stdVec.append({ 2, MoveOnly { 99 } });

    HashMap<int, MoveOnly> wtfMap(fromRange, WTF::move(stdVec));

    EXPECT_EQ(2U, wtfMap.size());

    auto it1 = wtfMap.find(1);
    auto it2 = wtfMap.find(2);

    ASSERT_NE(wtfMap.end(), it1);
    ASSERT_NE(wtfMap.end(), it2);

    EXPECT_EQ(42U, it1->value.value());
    EXPECT_EQ(99U, it2->value.value());
}

TEST(WTF_HashMap, fromRangeConstructorStringKeys)
{
    Vector<KeyValuePair<String, double>> stdVec {
        { "pi"_s, 3.14159 },
        { "e"_s, 2.71828 },
        { "sqrt2"_s, 1.41421 }
    };
    HashMap<String, double> wtfMap(fromRange, stdVec);

    EXPECT_EQ(3U, wtfMap.size());
    EXPECT_DOUBLE_EQ(3.14159, wtfMap.get("pi"_s));
    EXPECT_DOUBLE_EQ(2.71828, wtfMap.get("e"_s));
    EXPECT_DOUBLE_EQ(1.41421, wtfMap.get("sqrt2"_s));
}

TEST(WTF_HashMap, fromRangeConstructorCustomHashTraits)
{
    // Test with custom hash map configuration
    using CustomHashMap = HashMap<double, int64_t, DefaultHash<double>, TestDoubleHashTraits>;

    Vector<KeyValuePair<double, int64_t>> stdVec {
        { 1.1, 11 },
        { 2.2, 22 },
        { 3.3, 33 }
    };
    CustomHashMap wtfMap(fromRange, stdVec);

    EXPECT_EQ(3U, wtfMap.size());
    EXPECT_EQ(11, wtfMap.get(1.1));
    EXPECT_EQ(22, wtfMap.get(2.2));
    EXPECT_EQ(33, wtfMap.get(3.3));
}

TEST(WTF_HashMap, RangeToBasicUsage)
{
    // Test the rangeTo range adaptor with HashMap
    Vector<KeyValuePair<int, String>> stdVec {
        { 1, "one"_s },
        { 2, "two"_s },
        { 3, "three"_s }
    };
    auto wtfMap = stdVec | rangeTo<HashMap<int, String>>();

    EXPECT_EQ(3U, wtfMap.size());
    EXPECT_EQ("one"_s, wtfMap.get(1));
    EXPECT_EQ("two"_s, wtfMap.get(2));
    EXPECT_EQ("three"_s, wtfMap.get(3));
}

TEST(WTF_HashMap, RangeToChainedOperations)
{
    Vector<KeyValuePair<int, int>> stdVec {
        { 1, 10 },
        { 2, 20 },
        { 3, 30 },
        { 4, 40 }
    };

    auto result = stdVec
        | std::views::filter([](const auto& pair) { return !(pair.key % 2); })
        | std::views::transform([](const auto& pair) -> KeyValuePair<int, int> { return { pair.key, pair.value * 2 }; })
        | rangeTo<HashMap<int, int>>();

    EXPECT_EQ(2U, result.size());
    EXPECT_EQ(40, result.get(2)); // 20 * 2
    EXPECT_EQ(80, result.get(4)); // 40 * 2
}

class Object : public WTF::RefCountedAndCanMakeWeakPtr<Object> {
public:
    static Ref<Object> create() { return adoptRef(*new Object); }

private:
    Object() = default;
};

TEST(WTF_HashMap, WeakPtr)
{
    HashMap<WeakPtr<Object>, int> map;

    RefPtr object1 = Object::create();
    map.add(object1.get(), 1);

    Ref object2 = Object::create();

    // Present when live
    EXPECT_TRUE(map.contains(object1.get()));
    EXPECT_EQ(map.find(object1.get())->value, 1);
    EXPECT_EQ(1u, map.size());
    for (auto& entry : map) {
        EXPECT_EQ(entry.key, object1.get());
        EXPECT_EQ(entry.value, 1);
    }

    EXPECT_FALSE(map.contains(&object2.get()));
    EXPECT_EQ(map.find(&object2.get()), map.end());

    Object* rawObject1 = object1.get();
    object1 = nullptr;

    // Absent when dead
    EXPECT_EQ(map.get(rawObject1), 0);
    EXPECT_FALSE(map.contains(rawObject1));
    EXPECT_EQ(map.find(rawObject1), map.end());
    EXPECT_EQ(map.begin(), map.end());

    // Accurate size after removing weak nulls
    EXPECT_EQ(1u, map.size());
    map.removeWeakNullEntries();
    EXPECT_EQ(0u, map.size());

    // Bounded growth as added objects die
    for (size_t i = 0; i < 128; ++i)
        map.add(&Object::create().get(), 1);
    EXPECT_LT(map.size(), 16u);
}

TEST(WTF_HashMap, InlineWeakPtr)
{
    HashMap<InlineWeakPtr<InlineWeakPtrObject>, int> map;

    RefPtr object1 = InlineWeakPtrObject::create();
    map.add(object1.get(), 1);

    Ref object2 = InlineWeakPtrObject::create();

    // Present when live
    EXPECT_TRUE(map.contains(object1.get()));
    EXPECT_EQ(map.find(object1.get())->value, 1);
    EXPECT_EQ(1u, map.size());
    for (auto& entry : map) {
        EXPECT_EQ(entry.key, object1.get());
        EXPECT_EQ(entry.value, 1);
    }

    EXPECT_FALSE(map.contains(&object2.get()));
    EXPECT_EQ(map.find(&object2.get()), map.end());

    InlineWeakPtrObject* rawObject1 = object1.get();
    object1 = nullptr;

    // Absent when dead
    EXPECT_EQ(map.get(rawObject1), 0);
    EXPECT_FALSE(map.contains(rawObject1));
    EXPECT_EQ(map.find(rawObject1), map.end());
    EXPECT_EQ(map.begin(), map.end());

    // Accurate size after removing weak nulls
    EXPECT_EQ(1u, map.size());
    map.removeWeakNullEntries();
    EXPECT_EQ(0u, map.size());

    // Bounded growth as added objects die
    for (size_t i = 0; i < 128; ++i)
        map.add(&InlineWeakPtrObject::create().get(), 1);
    EXPECT_LT(map.size(), 16u);
}

} // namespace TestWebKitAPI
