libshit

Just some random shit
git clone https://git.neptards.moe/neptards/libshit.git
Log | Files | Refs | Submodules | README | LICENSE

bitfield.cpp (3093B)


      1 #include "libshit/bitfield.hpp"
      2 
      3 #include "libshit/doctest.hpp"
      4 
      5 #include <cstdint>
      6 
      7 namespace Libshit
      8 {
      9   TEST_SUITE_BEGIN("Libshit::Bitfield");
     10 
     11   TEST_CASE("Empty BF")
     12   {
     13     Bitfield<> BF;
     14     (void) BF;
     15   }
     16 
     17   namespace
     18   {
     19     enum class EnumA { A, B, C, D, ENUM_MAX = D };
     20     enum EnumB { X, Y, Z };
     21 
     22     using BF = Bitfield<
     23       BitBool<struct Bool1>,
     24       BitOptBool<struct OptBool>,
     25       BitUInt<struct UInt, 2>,
     26       BitEnum<struct Enum1, EnumA>,
     27       BitEnum<struct Enum2, EnumB, EnumB::Z>,
     28       BitOptEnum<struct Enum3, EnumA>,
     29       BitBool<struct Bool2>>;
     30     static_assert(sizeof(BF) == sizeof(std::uint16_t));
     31   }
     32 
     33   TEST_CASE("Simple test")
     34   {
     35     BF bf;
     36     auto check = [&](bool b1, std::optional<bool> ob, unsigned u, EnumA a,
     37                      EnumB b, std::optional<EnumA> o, bool b2, unsigned raw)
     38     {
     39       CAPTURE(bf);
     40       CHECK(bf.Get<Bool1>() == b1);
     41       CHECK(bf.Get<OptBool>() == ob);
     42       CHECK(bf.Get<UInt>() == u);
     43       CHECK(bf.Get<Enum1>() == a);
     44       CHECK(bf.Get<Enum2>() == b);
     45       CHECK(bf.Get<Enum3>() == o);
     46       CHECK(bf.Get<Bool2>() == b2);
     47 
     48       BF exp(b1, ob, u, a, b, o, b2);
     49       CHECK(bf == exp);
     50       CHECK(!(bf != exp));
     51       CHECK(bf.GetRaw() == raw);
     52 
     53     };
     54     check(false, {}, 0, EnumA::A, EnumB::X, {}, false, 0);
     55 
     56     bf.Set<Bool1>(true);
     57     check(true, {}, 0, EnumA::A, EnumB::X, {}, false, 0b0'000'00'00'00'00'1);
     58 
     59     bf.Set<OptBool>(false);
     60     check(true, false, 0, EnumA::A, EnumB::X, {}, false, 0b0'000'00'00'00'10'1);
     61     bf.Set<OptBool>(true);
     62     check(true, true, 0, EnumA::A, EnumB::X, {}, false, 0b0'000'00'00'00'11'1);
     63     bf.Set<OptBool>({});
     64     check(true, {}, 0, EnumA::A, EnumB::X, {}, false, 0b0'000'00'00'00'00'1);
     65 
     66     bf.Set<UInt>(3);
     67     check(true, {}, 3, EnumA::A, EnumB::X, {}, false, 0b0'000'00'00'11'00'1);
     68 
     69     bf.Set<Enum3>(EnumA::B);
     70     check(true, {}, 3, EnumA::A, EnumB::X, EnumA::B, false, 0b0'010'00'00'11'00'1);
     71 
     72     bf.Set<Bool2>(false);
     73     check(true, {}, 3, EnumA::A, EnumB::X, EnumA::B, false, 0b0'010'00'00'11'00'1);
     74     bf.Set<Bool2>(true);
     75     check(true, {}, 3, EnumA::A, EnumB::X, EnumA::B, true, 0b1'010'00'00'11'00'1);
     76 
     77     bf.Set<Enum2>(EnumB::Z);
     78     check(true, {}, 3, EnumA::A, EnumB::Z, EnumA::B, true, 0b1'010'10'00'11'00'1);
     79 
     80     bf.Set<Enum3>({});
     81     check(true, {}, 3, EnumA::A, EnumB::Z, {}, true, 0b1'000'10'00'11'00'1);
     82 
     83     bf.Set<UInt>(18); // should this be an error instead?
     84     check(true, {}, 2, EnumA::A, EnumB::Z, {}, true, 0b1'000'10'00'10'00'1);
     85 
     86     bf.Set<Bool1>(false);
     87     check(false, {}, 2, EnumA::A, EnumB::Z, {}, true, 0b1'000'10'00'10'00'0);
     88 
     89     bf = BF{true, {}, 3, EnumA::C, EnumB::X, EnumA::A, false};
     90     check(true, {}, 3, EnumA::C, EnumB::X, EnumA::A, false, 0b0'001'00'10'11'00'1);
     91   }
     92 
     93   // just because I can
     94   static constexpr BF Test0()
     95   {
     96     BF bf;
     97     bf.Set<Bool1>(true);
     98     return bf;
     99   }
    100   static_assert(Test0().Get<Bool1>());
    101   static_assert(!Test0().Get<Bool2>());
    102 
    103   TEST_CASE("BitNop")
    104   {
    105     Bitfield<BitBool<Bool1>, BitNop> bf(true);
    106     CHECK(bf.Get<Bool1>() == true);
    107   }
    108 
    109   TEST_SUITE_END();
    110 }