imported from "final" folder
This commit is contained in:
449
.pio/libdeps/esp01_1m/FastLED/tests/test_bitset.cpp
Normal file
449
.pio/libdeps/esp01_1m/FastLED/tests/test_bitset.cpp
Normal file
@@ -0,0 +1,449 @@
|
||||
// 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") {
|
||||
// default‐constructed 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 uint16_t block (2 bytes)
|
||||
REQUIRE_EQ(sizeof(bitset_fixed<8>), 2);
|
||||
|
||||
// For bitset_fixed<16>, we expect 1 uint16_t block (2 bytes)
|
||||
REQUIRE_EQ(sizeof(bitset_fixed<16>), 2);
|
||||
|
||||
// For bitset_fixed<17>, we expect 2 uint16_t blocks (4 bytes)
|
||||
REQUIRE_EQ(sizeof(bitset_fixed<17>), 4);
|
||||
|
||||
// For bitset_fixed<32>, we expect 2 uint16_t blocks (4 bytes)
|
||||
REQUIRE_EQ(sizeof(bitset_fixed<32>), 4);
|
||||
|
||||
// For bitset_fixed<33>, we expect 3 uint16_t blocks (6 bytes)
|
||||
REQUIRE_EQ(sizeof(bitset_fixed<33>), 6);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("test bitset_fixed find_first") {
|
||||
// Test find_first for true bits
|
||||
bitset_fixed<64> bs;
|
||||
|
||||
// Initially no bits are set, so find_first(true) should return -1
|
||||
REQUIRE_EQ(bs.find_first(true), -1);
|
||||
|
||||
// find_first(false) should return 0 (first unset bit)
|
||||
REQUIRE_EQ(bs.find_first(false), 0);
|
||||
|
||||
// Set bit at position 5
|
||||
bs.set(5);
|
||||
REQUIRE_EQ(bs.find_first(true), 5);
|
||||
REQUIRE_EQ(bs.find_first(false), 0);
|
||||
|
||||
// Set bit at position 0
|
||||
bs.set(0);
|
||||
REQUIRE_EQ(bs.find_first(true), 0);
|
||||
REQUIRE_EQ(bs.find_first(false), 1);
|
||||
|
||||
// Set bit at position 63 (last bit)
|
||||
bs.set(63);
|
||||
REQUIRE_EQ(bs.find_first(true), 0);
|
||||
REQUIRE_EQ(bs.find_first(false), 1);
|
||||
|
||||
// Clear bit 0, now first set bit should be 5
|
||||
bs.reset(0);
|
||||
REQUIRE_EQ(bs.find_first(true), 5);
|
||||
REQUIRE_EQ(bs.find_first(false), 0);
|
||||
|
||||
// Test with larger bitset
|
||||
bitset_fixed<128> bs2;
|
||||
bs2.set(100);
|
||||
REQUIRE_EQ(bs2.find_first(true), 100);
|
||||
REQUIRE_EQ(bs2.find_first(false), 0);
|
||||
|
||||
// Test edge case: all bits set
|
||||
bitset_fixed<8> bs3;
|
||||
for (fl::u32 i = 0; i < 8; ++i) {
|
||||
bs3.set(i);
|
||||
}
|
||||
REQUIRE_EQ(bs3.find_first(true), 0);
|
||||
REQUIRE_EQ(bs3.find_first(false), -1);
|
||||
|
||||
// Test edge case: no bits set
|
||||
bitset_fixed<8> bs4;
|
||||
REQUIRE_EQ(bs4.find_first(true), -1);
|
||||
REQUIRE_EQ(bs4.find_first(false), 0);
|
||||
}
|
||||
|
||||
TEST_CASE("test bitset_dynamic find_first") {
|
||||
// Test find_first for dynamic bitset
|
||||
bitset_dynamic bs(64);
|
||||
|
||||
// Initially no bits are set, so find_first(true) should return -1
|
||||
REQUIRE_EQ(bs.find_first(true), -1);
|
||||
|
||||
// find_first(false) should return 0 (first unset bit)
|
||||
REQUIRE_EQ(bs.find_first(false), 0);
|
||||
|
||||
// Set bit at position 5
|
||||
bs.set(5);
|
||||
REQUIRE_EQ(bs.find_first(true), 5);
|
||||
REQUIRE_EQ(bs.find_first(false), 0);
|
||||
|
||||
// Set bit at position 0
|
||||
bs.set(0);
|
||||
REQUIRE_EQ(bs.find_first(true), 0);
|
||||
REQUIRE_EQ(bs.find_first(false), 1);
|
||||
|
||||
// Set bit at position 63 (last bit)
|
||||
bs.set(63);
|
||||
REQUIRE_EQ(bs.find_first(true), 0);
|
||||
REQUIRE_EQ(bs.find_first(false), 1);
|
||||
|
||||
// Clear bit 0, now first set bit should be 5
|
||||
bs.reset(0);
|
||||
REQUIRE_EQ(bs.find_first(true), 5);
|
||||
REQUIRE_EQ(bs.find_first(false), 0);
|
||||
|
||||
// Test with all bits set
|
||||
bitset_dynamic bs2(16);
|
||||
for (fl::u32 i = 0; i < 16; ++i) {
|
||||
bs2.set(i);
|
||||
}
|
||||
REQUIRE_EQ(bs2.find_first(true), 0);
|
||||
REQUIRE_EQ(bs2.find_first(false), -1);
|
||||
|
||||
// Test with no bits set
|
||||
bitset_dynamic bs3(16);
|
||||
REQUIRE_EQ(bs3.find_first(true), -1);
|
||||
REQUIRE_EQ(bs3.find_first(false), 0);
|
||||
}
|
||||
|
||||
TEST_CASE("test bitset_inlined find_first") {
|
||||
// Test find_first for inlined bitset (uses fixed bitset internally for small sizes)
|
||||
bitset<64> bs;
|
||||
|
||||
// Initially no bits are set, so find_first(true) should return -1
|
||||
REQUIRE_EQ(bs.find_first(true), -1);
|
||||
|
||||
// find_first(false) should return 0 (first unset bit)
|
||||
REQUIRE_EQ(bs.find_first(false), 0);
|
||||
|
||||
// Set bit at position 5
|
||||
bs.set(5);
|
||||
REQUIRE_EQ(bs.find_first(true), 5);
|
||||
REQUIRE_EQ(bs.find_first(false), 0);
|
||||
|
||||
// Set bit at position 0
|
||||
bs.set(0);
|
||||
REQUIRE_EQ(bs.find_first(true), 0);
|
||||
REQUIRE_EQ(bs.find_first(false), 1);
|
||||
|
||||
// Set bit at position 63 (last bit)
|
||||
bs.set(63);
|
||||
REQUIRE_EQ(bs.find_first(true), 0);
|
||||
REQUIRE_EQ(bs.find_first(false), 1);
|
||||
|
||||
// Clear bit 0, now first set bit should be 5
|
||||
bs.reset(0);
|
||||
REQUIRE_EQ(bs.find_first(true), 5);
|
||||
REQUIRE_EQ(bs.find_first(false), 0);
|
||||
|
||||
// Test with all bits set
|
||||
bitset<16> bs2;
|
||||
for (fl::u32 i = 0; i < 16; ++i) {
|
||||
bs2.set(i);
|
||||
}
|
||||
REQUIRE_EQ(bs2.find_first(true), 0);
|
||||
REQUIRE_EQ(bs2.find_first(false), -1);
|
||||
|
||||
// Test with no bits set
|
||||
bitset<16> bs3;
|
||||
REQUIRE_EQ(bs3.find_first(true), -1);
|
||||
REQUIRE_EQ(bs3.find_first(false), 0);
|
||||
|
||||
// Test with larger size that uses dynamic bitset internally
|
||||
bitset<300> bs4;
|
||||
bs4.set(150);
|
||||
REQUIRE_EQ(bs4.find_first(true), 150);
|
||||
REQUIRE_EQ(bs4.find_first(false), 0);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("test bitset_fixed find_run") {
|
||||
// Test interesting patterns
|
||||
bitset_fixed<32> bs;
|
||||
// Set pattern: 0001 1001 0111 1100 0000 1111 0000 0011
|
||||
bs.set(3);
|
||||
bs.set(4);
|
||||
bs.set(7);
|
||||
bs.set(9);
|
||||
bs.set(10);
|
||||
bs.set(11);
|
||||
bs.set(12);
|
||||
bs.set(13);
|
||||
bs.set(20);
|
||||
bs.set(21);
|
||||
bs.set(22);
|
||||
bs.set(23);
|
||||
bs.set(30);
|
||||
bs.set(31);
|
||||
|
||||
FL_WARN("bs: " << bs);
|
||||
|
||||
// Find first run of length 3
|
||||
int idx = bs.find_run(true, 3);
|
||||
REQUIRE_EQ(idx, 9); // First run at 3
|
||||
|
||||
idx = bs.find_run(false, 2, 9);
|
||||
REQUIRE_EQ(idx, 14); // First run at 3
|
||||
|
||||
// off the edge
|
||||
idx = bs.find_run(true, 3, 31);
|
||||
REQUIRE_EQ(idx, -1);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user