From 22308e52cfd9e0064838e8e28f195807516e2d2c Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Sun, 27 Mar 2022 12:48:12 +0100 Subject: AK: Add an ArbitrarySizedEnum template This is an enum-like type that works with arbitrary sized storage > u64, which is the limit for a regular enum class - which limits it to 64 members when needing bit field behavior. Co-authored-by: Ali Mohammad Pur --- Tests/AK/CMakeLists.txt | 1 + Tests/AK/TestArbitrarySizedEnum.cpp | 120 ++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 Tests/AK/TestArbitrarySizedEnum.cpp (limited to 'Tests') diff --git a/Tests/AK/CMakeLists.txt b/Tests/AK/CMakeLists.txt index a7314da56d..fac063f6fd 100644 --- a/Tests/AK/CMakeLists.txt +++ b/Tests/AK/CMakeLists.txt @@ -2,6 +2,7 @@ set(AK_TEST_SOURCES TestFixedPoint.cpp TestAllOf.cpp TestAnyOf.cpp + TestArbitrarySizedEnum.cpp TestArray.cpp TestAtomic.cpp TestBadge.cpp diff --git a/Tests/AK/TestArbitrarySizedEnum.cpp b/Tests/AK/TestArbitrarySizedEnum.cpp new file mode 100644 index 0000000000..1abda962e8 --- /dev/null +++ b/Tests/AK/TestArbitrarySizedEnum.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2022, Linus Groh + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +#include +#include + +AK_MAKE_ARBITRARY_SIZED_ENUM(TestEnum, u8, + Foo = TestEnum(1) << 0, + Bar = TestEnum(1) << 1, + Baz = TestEnum(1) << 2); + +AK_MAKE_ARBITRARY_SIZED_ENUM(BigIntTestEnum, u128, + Foo = BigIntTestEnum(1u) << 127u); + +TEST_CASE(constructor) +{ + { + constexpr TestEnum::Type test; + static_assert(test.value() == 0); + } + { + constexpr TestEnum::Type test { TestEnum::Foo | TestEnum::Baz }; + static_assert(test.value() == 0b101); + } + { + constexpr BigIntTestEnum::Type test { BigIntTestEnum::Foo }; + static_assert(test.value() == u128(1u) << 127u); + } +} + +TEST_CASE(bitwise_or) +{ + { + TestEnum::Type test; + EXPECT_EQ(test.value(), 0); + test |= TestEnum::Foo; + EXPECT_EQ(test.value(), 0b001); + test |= TestEnum::Bar; + EXPECT_EQ(test.value(), 0b011); + test |= TestEnum::Baz; + EXPECT_EQ(test.value(), 0b111); + } + { + BigIntTestEnum::Type test; + EXPECT_EQ(test.value(), 0u); + test |= BigIntTestEnum::Foo; + EXPECT_EQ(test.value(), u128(1u) << 127u); + } +} + +TEST_CASE(bitwise_and) +{ + { + TestEnum::Type test { 0b111 }; + EXPECT_EQ(test.value(), 0b111); + test &= TestEnum::Foo; + EXPECT_EQ(test.value(), 0b001); + } + { + BigIntTestEnum::Type test { u128(1u) << 127u | u128(1u) << 126u }; + EXPECT_EQ(test.value(), u128(1u) << 127u | u128(1u) << 126u); + test &= BigIntTestEnum::Foo; + EXPECT_EQ(test.value(), u128(1u) << 127u); + } +} + +TEST_CASE(bitwise_xor) +{ + { + TestEnum::Type test { 0b111 }; + EXPECT_EQ(test.value(), 0b111); + test ^= TestEnum::Foo; + EXPECT_EQ(test.value(), 0b110); + } + { + BigIntTestEnum::Type test { u128(1u) << 127u | 1u }; + EXPECT_EQ(test.value(), u128(1u) << 127u | 1u); + test ^= BigIntTestEnum::Foo; + EXPECT_EQ(test.value(), 1u); + } +} + +TEST_CASE(has_flag) +{ + { + TestEnum::Type test; + test |= TestEnum::Foo; + EXPECT(test.has_flag(TestEnum::Foo)); + EXPECT(!test.has_flag(TestEnum::Bar)); + EXPECT(!test.has_flag(TestEnum::Baz)); + EXPECT(!test.has_flag(TestEnum::Foo | TestEnum::Bar | TestEnum::Baz)); + } + { + BigIntTestEnum::Type test; + test |= BigIntTestEnum::Foo; + EXPECT(test.has_flag(BigIntTestEnum::Foo)); + } +} + +TEST_CASE(has_any_flag) +{ + { + TestEnum::Type test; + test |= TestEnum::Foo; + EXPECT(test.has_any_flag(TestEnum::Foo)); + EXPECT(!test.has_any_flag(TestEnum::Bar)); + EXPECT(!test.has_any_flag(TestEnum::Baz)); + EXPECT(test.has_any_flag(TestEnum::Foo | TestEnum::Bar | TestEnum::Baz)); + } + { + BigIntTestEnum::Type test; + test |= BigIntTestEnum::Foo; + EXPECT(test.has_any_flag(BigIntTestEnum::Foo)); + } +} -- cgit v1.2.3