blob: 25e2bd1b21ba4975eb31d9de9019c29515aac007 [file] [log] [blame]
/*
* Copyright (C) 2011-2022 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 "MoveOnly.h"
#include <wtf/VariantList.h>
namespace TestWebKitAPI {
TEST(WTF_VariantList, Basic)
{
WTF::VariantList<Variant<int, float>> variantList;
EXPECT_TRUE(variantList.isEmpty());
variantList.append(0);
EXPECT_FALSE(variantList.isEmpty());
unsigned iterations = 0;
for (auto proxy : variantList) {
EXPECT_TRUE(proxy.holds_alternative<int>());
WTF::switchOn(proxy,
[&](int value) { EXPECT_EQ(0, value); },
[&](float) { FAIL(); }
);
WTF::switchOn(proxy,
[&](int value) { EXPECT_EQ(0, value); },
[&](float) { FAIL(); }
);
WTF::switchOn(proxy.asVariant(),
[&](int value) { EXPECT_EQ(0, value); },
[&](float) { FAIL(); }
);
++iterations;
}
EXPECT_EQ(1u, iterations);
}
TEST(WTF_VariantList, Basic_InlineCapacity)
{
WTF::VariantList<Variant<int, float>, 8> variantList;
EXPECT_TRUE(variantList.isEmpty());
variantList.append(0);
EXPECT_FALSE(variantList.isEmpty());
unsigned iterations = 0;
for (auto proxy : variantList) {
EXPECT_TRUE(proxy.holds_alternative<int>());
WTF::switchOn(proxy,
[&](int value) { EXPECT_EQ(0, value); },
[&](float) { FAIL(); }
);
WTF::switchOn(proxy,
[&](int value) { EXPECT_EQ(0, value); },
[&](float) { FAIL(); }
);
WTF::switchOn(proxy.asVariant(),
[&](int value) { EXPECT_EQ(0, value); },
[&](float) { FAIL(); }
);
++iterations;
}
EXPECT_EQ(1u, iterations);
}
TEST(WTF_VariantList, MoveOnly)
{
WTF::VariantList<Variant<int, MoveOnly, float>> variantList;
variantList.append(MoveOnly(0));
variantList.append(MoveOnly(1));
unsigned iterations = 0;
for (auto proxy : variantList) {
EXPECT_TRUE(proxy.holds_alternative<MoveOnly>());
WTF::switchOn(proxy,
[&](int) { FAIL(); },
[&](const MoveOnly& value) { EXPECT_EQ(iterations, value.value()); },
[&](float) { FAIL(); }
);
++iterations;
}
EXPECT_EQ(2u, iterations);
}
TEST(WTF_VariantList, EmptyMove)
{
WTF::VariantList<Variant<int, MoveOnly, float>> variantList;
EXPECT_TRUE(variantList.isEmpty());
auto moved = WTF::move(variantList);
EXPECT_TRUE(moved.isEmpty());
}
TEST(WTF_VariantList, EmptyCopy)
{
WTF::VariantList<Variant<int, float>> variantList;
EXPECT_TRUE(variantList.isEmpty());
auto copied = variantList;
EXPECT_TRUE(copied.isEmpty());
EXPECT_TRUE(variantList.isEmpty());
}
TEST(WTF_VariantList, MoveWithItems)
{
WTF::VariantList<Variant<int, MoveOnly, float>> variantList;
variantList.append(0);
variantList.append(MoveOnly(1u));
variantList.append(2.0f);
auto moved = WTF::move(variantList);
unsigned iterations = 0;
for (auto proxy : moved) {
WTF::switchOn(proxy,
[&](int value) { EXPECT_EQ(0, value); },
[&](const MoveOnly& value) { EXPECT_EQ(1u, value.value()); },
[&](float value) { EXPECT_EQ(2.0f, value); }
);
++iterations;
}
EXPECT_EQ(3u, iterations);
}
TEST(WTF_VariantList, CopyWithItems)
{
WTF::VariantList<Variant<int, float>> variantList;
variantList.append(0);
variantList.append(1.0f);
auto copied = variantList;
unsigned iterations = 0;
for (auto proxy : variantList) {
WTF::switchOn(proxy,
[&](int value) { EXPECT_EQ(0, value); },
[&](float value) { EXPECT_EQ(1.0f, value); }
);
++iterations;
}
EXPECT_EQ(2u, iterations);
iterations = 0;
for (auto proxy : copied) {
WTF::switchOn(proxy,
[&](int value) { EXPECT_EQ(0, value); },
[&](float value) { EXPECT_EQ(1.0f, value); }
);
++iterations;
}
EXPECT_EQ(2u, iterations);
}
TEST(WTF_VariantList, Equality)
{
WTF::VariantList<Variant<int, float, double>> a;
WTF::VariantList<Variant<int, float, double>> b;
// Test self equality when empty.
EXPECT_EQ(a, a);
// Test equality when both empty.
EXPECT_EQ(a, b);
a.append(1);
a.append(2.0);
// Test self equality when NON-empty.
EXPECT_EQ(a, a);
// Test NON-equality when one is empty.
EXPECT_NE(a, b);
b.append(1);
b.append(2.0);
// Test equality when NOT empty.
EXPECT_EQ(a, b);
b.append(3.0f);
// Test NON-equality when both NON-empty.
EXPECT_NE(a, b);
}
TEST(WTF_VariantList, Grow)
{
WTF::VariantList<Variant<int, float, double>> variantList;
EXPECT_EQ(0u, variantList.capacityInBytes());
constexpr auto firstCapacity = 32u;
variantList.append(0.0);
EXPECT_EQ(firstCapacity, variantList.capacityInBytes());
for (unsigned i = 0; i < 5; ++i)
variantList.append(0.0);
EXPECT_NE(firstCapacity, variantList.capacityInBytes());
}
TEST(WTF_VariantList, Sizer)
{
using List = WTF::VariantList<Variant<int, float, double>>;
// Create a sizer for the list.
auto sizer = List::Sizer { };
// Emulate appending a few items.
sizer.append<double>();
sizer.append<float>();
sizer.append<double>();
sizer.append<int>();
// Create a list, passing the sizer in to initialize the capacity.
auto list = List(sizer);
// Record the capacity.
auto initialListCapacity = list.capacityInBytes();
EXPECT_EQ(0u, list.sizeInBytes());
// Append the same series of item types to the actual list.
list.append(1.0);
list.append(2.0f);
list.append(3.0);
list.append(4);
// Check that the size has grown.
EXPECT_NE(0u, list.sizeInBytes());
// Check that the capacity has not changed.
EXPECT_EQ(initialListCapacity, list.capacityInBytes());
// Check that the capacity is exactly equal to the size.
EXPECT_EQ(list.capacityInBytes(), list.sizeInBytes());
}
TEST(WTF_VariantList, InlineCapacity)
{
using List = WTF::VariantList<Variant<int, double>, 8>;
List list;
EXPECT_EQ(8u, list.capacityInBytes());
EXPECT_EQ(0u, list.sizeInBytes());
list.append(1);
EXPECT_EQ(8u, list.capacityInBytes());
EXPECT_NE(0u, list.sizeInBytes());
list.append(2.0);
EXPECT_NE(8u, list.capacityInBytes());
EXPECT_NE(0u, list.sizeInBytes());
}
} // namespace TestWebKitAPI