sTodo-m5paper-client/libraries/FastLED/tests/test_bitset.cpp
2025-06-30 20:47:33 +02:00

270 lines
7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// g++ --std=c++11 test.cpp
#include "test.h"
#include "fl/bitset.h"
#include "fl/bitset_dynamic.h"
using namespace fl;
TEST_CASE("test bitset") {
// defaultconstructed bitset is empty
bitset_fixed<10> bs;
REQUIRE_EQ(bs.none(), true);
REQUIRE_EQ(bs.count(), 0);
REQUIRE_EQ(bs.size(), 10);
// set a bit
bs.set(3);
REQUIRE_EQ(bs.test(3), true);
REQUIRE_EQ(bs[3], true);
REQUIRE_EQ(bs.any(), true);
REQUIRE_EQ(bs.count(), 1);
// reset that bit
bs.reset(3);
REQUIRE_EQ(bs.test(3), false);
REQUIRE_EQ(bs.none(), true);
// toggle a bit
bs.flip(2);
REQUIRE_EQ(bs.test(2), true);
bs.flip(2);
REQUIRE_EQ(bs.test(2), false);
// flip all bits
bitset_fixed<5> bs2;
for (size_t i = 0; i < 5; ++i)
bs2.set(i, (i % 2) == 0);
auto bs2_flipped = ~bs2;
for (size_t i = 0; i < 5; ++i)
REQUIRE_EQ(bs2_flipped.test(i), !bs2.test(i));
// all() and count()
bitset_fixed<4> bs3;
for (size_t i = 0; i < 4; ++i)
bs3.set(i);
REQUIRE_EQ(bs3.all(), true);
REQUIRE_EQ(bs3.count(), 4);
// check that the count can auto expand
bs3.set(100);
REQUIRE_EQ(bs3.count(), 4);
// bitwise AND, OR, XOR
bitset_fixed<4> a, b;
a.set(0); a.set(2);
b.set(1); b.set(2);
auto or_ab = a | b;
REQUIRE_EQ(or_ab.test(0), true);
REQUIRE_EQ(or_ab.test(1), true);
REQUIRE_EQ(or_ab.test(2), true);
REQUIRE_EQ(or_ab.test(3), false);
auto and_ab = a & b;
REQUIRE_EQ(and_ab.test(2), true);
REQUIRE_EQ(and_ab.test(0), false);
auto xor_ab = a ^ b;
REQUIRE_EQ(xor_ab.test(0), true);
REQUIRE_EQ(xor_ab.test(1), true);
REQUIRE_EQ(xor_ab.test(2), false);
// reset and none()
a.reset(); b.reset();
REQUIRE_EQ(a.none(), true);
// Test expected size of bitset_fixed
REQUIRE_EQ(bitset_fixed<8>().size(), 8);
REQUIRE_EQ(bitset_fixed<16>().size(), 16);
REQUIRE_EQ(bitset_fixed<32>().size(), 32);
REQUIRE_EQ(bitset_fixed<64>().size(), 64);
REQUIRE_EQ(bitset_fixed<100>().size(), 100);
REQUIRE_EQ(bitset_fixed<1000>().size(), 1000);
// Test memory size of bitset_fixed class (sizeof)
// For bitset_fixed<8>, we expect 1 uint64_t block (8 bytes)
REQUIRE_EQ(sizeof(bitset_fixed<8>), 8);
// For bitset_fixed<64>, we expect 1 uint64_t block (8 bytes)
REQUIRE_EQ(sizeof(bitset_fixed<64>), 8);
// For bitset_fixed<65>, we expect 2 uint64_t blocks (16 bytes)
REQUIRE_EQ(sizeof(bitset_fixed<65>), 16);
// For bitset_fixed<128>, we expect 2 uint64_t blocks (16 bytes)
REQUIRE_EQ(sizeof(bitset_fixed<128>), 16);
// For bitset_fixed<129>, we expect 3 uint64_t blocks (24 bytes)
REQUIRE_EQ(sizeof(bitset_fixed<129>), 24);
}
TEST_CASE("compare fixed and dynamic bitsets") {
// Test that fixed and dynamic bitsets behave the same
bitset_fixed<10> fixed_bs;
fl::bitset_dynamic dynamic_bs(10);
// Set the same bits in both
fixed_bs.set(1);
fixed_bs.set(5);
fixed_bs.set(9);
dynamic_bs.set(1);
dynamic_bs.set(5);
dynamic_bs.set(9);
// Verify they have the same state
REQUIRE_EQ(fixed_bs.size(), dynamic_bs.size());
REQUIRE_EQ(fixed_bs.count(), dynamic_bs.count());
for (size_t i = 0; i < 10; ++i) {
REQUIRE_EQ(fixed_bs.test(i), dynamic_bs.test(i));
}
}
TEST_CASE("test bitset_dynamic") {
// default-constructed bitset is empty
bitset_dynamic bs;
REQUIRE_EQ(bs.size(), 0);
REQUIRE_EQ(bs.none(), true);
REQUIRE_EQ(bs.count(), 0);
// resize and test
bs.resize(10);
REQUIRE_EQ(bs.size(), 10);
REQUIRE_EQ(bs.none(), true);
// set a bit
bs.set(3);
REQUIRE_EQ(bs.test(3), true);
REQUIRE_EQ(bs[3], true);
REQUIRE_EQ(bs.any(), true);
REQUIRE_EQ(bs.count(), 1);
// reset that bit
bs.reset(3);
REQUIRE_EQ(bs.test(3), false);
REQUIRE_EQ(bs.none(), true);
// toggle a bit
bs.flip(2);
REQUIRE_EQ(bs.test(2), true);
bs.flip(2);
REQUIRE_EQ(bs.test(2), false);
// resize larger
bs.set(5);
bs.resize(20);
REQUIRE_EQ(bs.size(), 20);
REQUIRE_EQ(bs.test(5), true);
REQUIRE_EQ(bs.count(), 1);
// resize smaller (truncate)
bs.resize(4);
REQUIRE_EQ(bs.size(), 4);
REQUIRE_EQ(bs.test(5), false); // out of range now
REQUIRE_EQ(bs.count(), 0);
// test with larger sizes that span multiple blocks
bitset_dynamic large_bs(100);
large_bs.set(0);
large_bs.set(63);
large_bs.set(64);
large_bs.set(99);
REQUIRE_EQ(large_bs.count(), 4);
REQUIRE_EQ(large_bs.test(0), true);
REQUIRE_EQ(large_bs.test(63), true);
REQUIRE_EQ(large_bs.test(64), true);
REQUIRE_EQ(large_bs.test(99), true);
// flip all bits
bitset_dynamic bs2(5);
for (size_t i = 0; i < 5; ++i)
bs2.set(i, (i % 2) == 0);
bs2.flip();
for (size_t i = 0; i < 5; ++i)
REQUIRE_EQ(bs2.test(i), !((i % 2) == 0));
// all() and count()
bitset_dynamic bs3(4);
for (size_t i = 0; i < 4; ++i)
bs3.set(i);
REQUIRE_EQ(bs3.all(), true);
REQUIRE_EQ(bs3.count(), 4);
// out-of-range ops are no-ops
bs3.set(100);
REQUIRE_EQ(bs3.count(), 4);
// bitwise AND, OR, XOR
bitset_dynamic a(4), b(4);
a.set(0); a.set(2);
b.set(1); b.set(2);
auto or_ab = a | b;
REQUIRE_EQ(or_ab.test(0), true);
REQUIRE_EQ(or_ab.test(1), true);
REQUIRE_EQ(or_ab.test(2), true);
REQUIRE_EQ(or_ab.test(3), false);
auto and_ab = a & b;
REQUIRE_EQ(and_ab.test(2), true);
REQUIRE_EQ(and_ab.test(0), false);
auto xor_ab = a ^ b;
REQUIRE_EQ(xor_ab.test(0), true);
REQUIRE_EQ(xor_ab.test(1), true);
REQUIRE_EQ(xor_ab.test(2), false);
// reset and none()
a.reset(); b.reset();
REQUIRE_EQ(a.none(), true);
REQUIRE_EQ(b.none(), true);
// copy constructor
bitset_dynamic original(10);
original.set(3);
original.set(7);
bitset_dynamic copy(original);
REQUIRE_EQ(copy.size(), 10);
REQUIRE_EQ(copy.test(3), true);
REQUIRE_EQ(copy.test(7), true);
REQUIRE_EQ(copy.count(), 2);
// move constructor
bitset_dynamic moved(fl::move(copy));
REQUIRE_EQ(moved.size(), 10);
REQUIRE_EQ(moved.test(3), true);
REQUIRE_EQ(moved.test(7), true);
REQUIRE_EQ(moved.count(), 2);
REQUIRE_EQ(copy.size(), 0); // moved from should be empty
// assignment operator
bitset_dynamic assigned = original;
REQUIRE_EQ(assigned.size(), 10);
REQUIRE_EQ(assigned.test(3), true);
REQUIRE_EQ(assigned.test(7), true);
// clear
assigned.clear();
REQUIRE_EQ(assigned.size(), 0);
REQUIRE_EQ(assigned.none(), true);
// Test memory size changes with resize
bitset_dynamic small_bs(8);
bitset_dynamic medium_bs(65);
bitset_dynamic large_bs2(129);
// These sizes should match the fixed bitset tests
REQUIRE_EQ(small_bs.size(), 8);
REQUIRE_EQ(medium_bs.size(), 65);
REQUIRE_EQ(large_bs2.size(), 129);
}