You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
3.0 KiB
C++
111 lines
3.0 KiB
C++
#include "libshit/bitfield.hpp"
|
|
|
|
#include "libshit/doctest.hpp"
|
|
|
|
#include <cstdint>
|
|
|
|
namespace Libshit
|
|
{
|
|
TEST_SUITE_BEGIN("Libshit::Bitfield");
|
|
|
|
TEST_CASE("Empty BF")
|
|
{
|
|
Bitfield<> BF;
|
|
(void) BF;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
enum class EnumA { A, B, C, D, ENUM_MAX = D };
|
|
enum EnumB { X, Y, Z };
|
|
|
|
using BF = Bitfield<
|
|
BitBool<struct Bool1>,
|
|
BitOptBool<struct OptBool>,
|
|
BitUInt<struct UInt, 2>,
|
|
BitEnum<struct Enum1, EnumA>,
|
|
BitEnum<struct Enum2, EnumB, EnumB::Z>,
|
|
BitOptEnum<struct Enum3, EnumA>,
|
|
BitBool<struct Bool2>>;
|
|
static_assert(sizeof(BF) == sizeof(std::uint16_t));
|
|
}
|
|
|
|
TEST_CASE("Simple test")
|
|
{
|
|
BF bf;
|
|
auto check = [&](bool b1, std::optional<bool> ob, unsigned u, EnumA a,
|
|
EnumB b, std::optional<EnumA> o, bool b2, unsigned raw)
|
|
{
|
|
CAPTURE(bf);
|
|
CHECK(bf.Get<Bool1>() == b1);
|
|
CHECK(bf.Get<OptBool>() == ob);
|
|
CHECK(bf.Get<UInt>() == u);
|
|
CHECK(bf.Get<Enum1>() == a);
|
|
CHECK(bf.Get<Enum2>() == b);
|
|
CHECK(bf.Get<Enum3>() == o);
|
|
CHECK(bf.Get<Bool2>() == b2);
|
|
|
|
BF exp(b1, ob, u, a, b, o, b2);
|
|
CHECK(bf == exp);
|
|
CHECK(!(bf != exp));
|
|
CHECK(bf.GetRaw() == raw);
|
|
|
|
};
|
|
check(false, {}, 0, EnumA::A, EnumB::X, {}, false, 0);
|
|
|
|
bf.Set<Bool1>(true);
|
|
check(true, {}, 0, EnumA::A, EnumB::X, {}, false, 0b0'000'00'00'00'00'1);
|
|
|
|
bf.Set<OptBool>(false);
|
|
check(true, false, 0, EnumA::A, EnumB::X, {}, false, 0b0'000'00'00'00'10'1);
|
|
bf.Set<OptBool>(true);
|
|
check(true, true, 0, EnumA::A, EnumB::X, {}, false, 0b0'000'00'00'00'11'1);
|
|
bf.Set<OptBool>({});
|
|
check(true, {}, 0, EnumA::A, EnumB::X, {}, false, 0b0'000'00'00'00'00'1);
|
|
|
|
bf.Set<UInt>(3);
|
|
check(true, {}, 3, EnumA::A, EnumB::X, {}, false, 0b0'000'00'00'11'00'1);
|
|
|
|
bf.Set<Enum3>(EnumA::B);
|
|
check(true, {}, 3, EnumA::A, EnumB::X, EnumA::B, false, 0b0'010'00'00'11'00'1);
|
|
|
|
bf.Set<Bool2>(false);
|
|
check(true, {}, 3, EnumA::A, EnumB::X, EnumA::B, false, 0b0'010'00'00'11'00'1);
|
|
bf.Set<Bool2>(true);
|
|
check(true, {}, 3, EnumA::A, EnumB::X, EnumA::B, true, 0b1'010'00'00'11'00'1);
|
|
|
|
bf.Set<Enum2>(EnumB::Z);
|
|
check(true, {}, 3, EnumA::A, EnumB::Z, EnumA::B, true, 0b1'010'10'00'11'00'1);
|
|
|
|
bf.Set<Enum3>({});
|
|
check(true, {}, 3, EnumA::A, EnumB::Z, {}, true, 0b1'000'10'00'11'00'1);
|
|
|
|
bf.Set<UInt>(18); // should this be an error instead?
|
|
check(true, {}, 2, EnumA::A, EnumB::Z, {}, true, 0b1'000'10'00'10'00'1);
|
|
|
|
bf.Set<Bool1>(false);
|
|
check(false, {}, 2, EnumA::A, EnumB::Z, {}, true, 0b1'000'10'00'10'00'0);
|
|
|
|
bf = BF{true, {}, 3, EnumA::C, EnumB::X, EnumA::A, false};
|
|
check(true, {}, 3, EnumA::C, EnumB::X, EnumA::A, false, 0b0'001'00'10'11'00'1);
|
|
}
|
|
|
|
// just because I can
|
|
static constexpr BF Test0()
|
|
{
|
|
BF bf;
|
|
bf.Set<Bool1>(true);
|
|
return bf;
|
|
}
|
|
static_assert(Test0().Get<Bool1>());
|
|
static_assert(!Test0().Get<Bool2>());
|
|
|
|
TEST_CASE("BitNop")
|
|
{
|
|
Bitfield<BitBool<Bool1>, BitNop> bf(true);
|
|
CHECK(bf.Get<Bool1>() == true);
|
|
}
|
|
|
|
TEST_SUITE_END();
|
|
}
|