10#include "gtest/gtest.h"
22TEST(BitVectorTest, BasicConstructionAndAccess) {
23 std::vector<uint8_t>
data{0xAA,
26 EXPECT_EQ(bv.width(), 16u);
28 EXPECT_EQ(bv.getBit(0),
false);
29 EXPECT_EQ(bv.getBit(1),
true);
30 EXPECT_EQ(bv.getBit(2),
false);
31 EXPECT_EQ(bv.getBit(3),
true);
32 EXPECT_EQ(bv.getBit(7),
true);
34 EXPECT_TRUE(bv.getBit(8));
35 EXPECT_TRUE(bv.getBit(9));
36 EXPECT_TRUE(bv.getBit(10));
37 EXPECT_TRUE(bv.getBit(11));
38 EXPECT_FALSE(bv.getBit(12));
41TEST(BitVectorTest, ShiftRightShrinksWidth) {
44 for (
int i = 0; i < 4; ++i)
47 EXPECT_EQ(bv.width(), 14u);
49 EXPECT_TRUE(bv.getBit(0));
50 EXPECT_TRUE(bv.getBit(1));
52 EXPECT_THROW(bv >>= 20, std::out_of_range);
55TEST(BitVectorTest, ShiftLeftIncreaseWidth) {
57 for (
int i = 0; i < 8; ++i)
60 EXPECT_EQ(bv.width(), 20u);
63 for (
int i = 0; i < 4; ++i)
64 EXPECT_FALSE(bv.getBit(i));
67 for (
int i = 4; i < 12; ++i)
68 EXPECT_TRUE(bv.getBit(i));
71 for (
int i = 12; i < 20; ++i)
72 EXPECT_FALSE(bv.getBit(i));
75TEST(BitVectorTest, BitwiseOps) {
78 for (
int i = 0; i < 8; ++i) {
79 a.setBit(i, (i % 2) == 1);
80 b.setBit(i, (i / 2) % 2 ==
86 EXPECT_EQ(c_and.width(), 8u);
88 for (
int i = 0; i < 8; ++i) {
89 bool abit =
a.getBit(i);
90 bool bbit =
b.getBit(i);
91 EXPECT_EQ(c_and.getBit(i), (abit & bbit));
92 EXPECT_EQ(c_or.getBit(i), (abit | bbit));
93 EXPECT_EQ(c_xor.getBit(i), (abit ^ bbit));
97TEST(BitVectorTest, EqualityAlignedAndMisaligned) {
101 std::vector<uint8_t> raw{0xAA, 0x0F};
104 EXPECT_TRUE(a0 == b0);
113 EXPECT_TRUE(aShift == bShift);
117 b.setBit(3, !
b.getBit(3));
118 EXPECT_TRUE(aShift != bShift);
121TEST(BitVectorTest, ZeroWidthAndBitwise) {
125 EXPECT_EQ(
a.width(), 0u);
126 EXPECT_EQ((a & b).width(), 0u);
127 EXPECT_EQ((a | b).width(), 0u);
128 EXPECT_EQ((a ^ b).width(), 0u);
131TEST(BitVectorTest, ZeroWidthShiftBehavior) {
134 EXPECT_THROW(z >>= 1, std::out_of_range);
136 EXPECT_NO_THROW(z >>= 0);
138 EXPECT_NO_THROW(z <<= 5);
139 EXPECT_EQ(z.width(), 5u);
142TEST(BitVectorTest, CrossByteAccessAndShift) {
143 std::vector<uint8_t>
data{0xF0, 0x55, 0xCC};
146 EXPECT_EQ(bv.width(), 21u);
149 EXPECT_FALSE(bv.getBit(0));
154TEST(BitVectorTest, MisalignedBitwiseFallback) {
155 std::vector<uint8_t> da{0xAA, 0xCC};
156 std::vector<uint8_t> db{0x0F, 0xF0};
164 for (
size_t i = 0; i <
a.width(); ++i) {
165 bool abit =
a.getBit(i);
166 bool bbit =
b.getBit(i);
167 EXPECT_EQ(rAnd.getBit(i), (abit & bbit));
168 EXPECT_EQ(rOr.getBit(i), (abit | bbit));
169 EXPECT_EQ(rXor.getBit(i), (abit ^ bbit));
173TEST(BitVectorTest, TailByteBitwiseNoMasking) {
176 std::vector<uint8_t> da{0b10101111, 0b00000001};
177 std::vector<uint8_t> db{0b11000011, 0b00000001};
181 for (
size_t i = 0; i < 13; ++i)
182 EXPECT_EQ(r.getBit(i),
a.getBit(i) ^
b.getBit(i));
185TEST(BitVectorTest, ConstructorInvalidBitIndex) {
186 std::vector<uint8_t> raw{0xAA, 0xBB};
187 EXPECT_THROW(
BitVector(raw, 16, 8), std::invalid_argument);
190TEST(BitVectorTest, ConstructorWidthExceedsStorage) {
191 std::vector<uint8_t> raw{0xAA};
192 EXPECT_THROW(
BitVector(raw, 16, 0), std::invalid_argument);
195TEST(BitVectorTest, GetBitOutOfRange) {
196 std::vector<uint8_t> raw{0x44};
198 EXPECT_THROW(bv.getBit(8), std::out_of_range);
201TEST(BitVectorTest, SetBitOutOfRange) {
203 EXPECT_THROW(bv.setBit(4,
true), std::out_of_range);
206TEST(BitVectorTest, ZeroWidthGetBitThrows) {
208 EXPECT_THROW(z.getBit(0), std::out_of_range);
211TEST(BitVectorTest, BitwiseWidthMismatchThrows) {
212 std::vector<uint8_t> raw0{0x00};
213 std::vector<uint8_t> raw1{0x00};
216 EXPECT_THROW((
void)(a & b), std::invalid_argument);
217 EXPECT_THROW((
void)(a | b), std::invalid_argument);
218 EXPECT_THROW((
void)(a ^ b), std::invalid_argument);
221TEST(BitVectorTest, NonOwningModificationThrows) {
222 std::vector<uint8_t> raw{0x00, 0x00};
226 EXPECT_THROW(view.getBit(99), std::out_of_range);
230 EXPECT_NO_THROW(owned.setBit(0,
true));
231 EXPECT_TRUE(owned.getBit(0));
235 EXPECT_EQ(trunc.width(), 16u);
237 owned.setBit(5,
true);
238 EXPECT_TRUE(owned.getBit(5));
241TEST(BitVectorTest, PackedSerializationRoundTrip) {
246 uint64_t packed_value = 0;
247 size_t bit_offset = 0;
250 auto pack = [&](uint64_t value,
size_t width) {
251 uint64_t
mask = (width == 64) ? ~0ULL : ((1ULL << width) - 1ULL);
252 packed_value |= ((value &
mask) << bit_offset);
264 ASSERT_EQ(bit_offset, 27u);
267 std::vector<uint8_t> bytes((27 + 7) / 8, 0);
268 for (
size_t i = 0; i < bytes.size(); ++i) {
269 bytes[i] =
static_cast<uint8_t
>((packed_value >> (8 * i)) & 0xFF);
276 for (
size_t i = 0; i < 1; ++i)
277 if (stream.getBit(i))
282 for (
size_t i = 0; i < 7; ++i)
283 if (stream.getBit(1 + i))
285 EXPECT_EQ(ru7, 0x55u);
288 for (
size_t i = 0; i < 1; ++i)
289 if (stream.getBit(8 + i))
294 for (
size_t i = 0; i < 5; ++i)
295 if (stream.getBit(9 + i))
296 rs5raw |= (1ULL << i);
297 EXPECT_EQ(rs5raw, 27u);
300 for (
size_t i = 0; i < 1; ++i)
301 if (stream.getBit(14 + i))
306 for (
size_t i = 0; i < 9; ++i)
307 if (stream.getBit(15 + i))
309 EXPECT_EQ(ru9, 0x1A5u);
312 for (
size_t i = 0; i < 3; ++i)
313 if (stream.getBit(24 + i))
318TEST(IntTest, ConstructionAndSignExtension) {
324 mbv.setBit(2,
false);
332 EXPECT_EQ(
static_cast<int64_t
>(v), -5);
334 bool expected[8] = {
true,
true,
false,
true,
true,
true,
true,
true};
335 for (
int i = 0; i < 8; ++i)
336 EXPECT_EQ(v.getBit(i), expected[i]) <<
"bit " << i;
339TEST(IntTest, SignExtendOnNarrowTo64) {
342 for (
size_t i = 0; i < 12; ++i)
346 EXPECT_EQ(
static_cast<int64_t
>(v), -1);
348 EXPECT_TRUE(v.getBit(11));
351TEST(IntTest, OverflowSigned) {
354 big.setBit(64,
true);
356 EXPECT_THROW((
void)
static_cast<int64_t
>(v), std::overflow_error);
359TEST(IntTest, WidthOneValues) {
365 mbv_neg.setBit(0,
true);
370 EXPECT_EQ(
static_cast<int64_t
>(z), 0);
371 EXPECT_EQ(
static_cast<int64_t
>(neg), -1);
374TEST(IntTest, LargeWidthSignExtendedConversions) {
377 for (
size_t i = 0; i < 130; ++i)
378 mbv_negAll.setBit(i,
true);
382 mbv_posSmall.setBit(0,
true);
383 mbv_posSmall.setBit(2,
true);
385 Int negAll(mbv_negAll);
386 Int posSmall(mbv_posSmall);
388 EXPECT_EQ(
static_cast<int64_t
>(negAll), -1);
389 EXPECT_EQ(
static_cast<int64_t
>(posSmall), 5);
392TEST(IntTest, LargeWidthBadSignExtensionOverflow) {
395 mbv_v.setBit(0,
true);
396 mbv_v.setBit(2,
true);
397 mbv_v.setBit(100,
true);
400 EXPECT_THROW((
void)
static_cast<int64_t
>(v), std::overflow_error);
403TEST(UIntTest, BasicConstruction) {
407 for (
size_t i = 0; i < 16; ++i)
408 if (val & (1ULL << i))
412 EXPECT_EQ(
static_cast<uint64_t
>(u), 123u);
413 EXPECT_EQ(u.width(), 16u);
416TEST(UIntTest, BitwiseFastVsFallbackConsistency) {
418 std::vector<uint8_t> raw1{0xFF, 0x0F, 0xAA};
419 std::vector<uint8_t> raw2{0x0F, 0xF0, 0x55};
422 auto alignedAnd = aAligned & bAligned;
425 for (
size_t i = 0; i < aAligned.width(); ++i)
426 EXPECT_EQ(alignedAnd.getBit(i), (aAligned.getBit(i) && bAligned.getBit(i)));
429TEST(UIntTest, OverflowUnsignedConversion) {
432 EXPECT_NO_THROW((
void)
static_cast<uint64_t
>(
UInt(big)));
435 big.setBit(65,
true);
437 EXPECT_THROW((
void)
static_cast<uint64_t
>(bigUInt), std::overflow_error);
441TEST(BitVectorFormatTest, ToStringAndStreamBases) {
444 const uint64_t val = 0x1F3ULL;
447 std::vector<uint8_t> bytes((width + 7) / 8, 0);
448 for (
size_t i = 0; i < width; ++i)
449 if (val & (1ULL << i))
450 bytes[i / 8] |=
static_cast<uint8_t
>(1u << (i % 8));
456 EXPECT_EQ(bv.
toString(), std::string(
"1f3"));
457 EXPECT_EQ(bv.
toString(16), std::string(
"1f3"));
458 EXPECT_EQ(bv.
toString(10), std::string(
"499"));
459 EXPECT_EQ(bv.
toString(8), std::string(
"763"));
460 EXPECT_EQ(bv.
toString(2), std::string(
"000111110011"));
464 std::ostringstream oss;
466 EXPECT_EQ(oss.str(),
"499");
469 std::ostringstream oss;
470 oss << std::dec << std::showbase << bv;
471 EXPECT_EQ(oss.str(),
"499");
474 std::ostringstream oss;
475 oss << std::hex << bv;
476 EXPECT_EQ(oss.str(),
"1f3");
479 std::ostringstream oss;
480 oss << std::showbase << std::hex << bv;
481 EXPECT_EQ(oss.str(),
"0x1f3");
484 std::ostringstream oss;
485 oss << std::uppercase << std::showbase << std::hex << bv;
486 EXPECT_EQ(oss.str(),
"0X1F3");
489 std::ostringstream oss;
490 oss << std::oct << bv;
491 EXPECT_EQ(oss.str(),
"763");
494 std::ostringstream oss;
495 oss << std::showbase << std::oct << bv;
496 EXPECT_EQ(oss.str(),
"0763");
503 std::ostringstream ossHex, ossDec, ossOct;
504 ossHex << std::hex << z;
505 ossDec << std::dec << z;
506 ossOct << std::oct << z;
507 EXPECT_EQ(ossHex.str(),
"0");
508 EXPECT_EQ(ossDec.str(),
"0");
509 EXPECT_EQ(ossOct.str(),
"0");
510 EXPECT_EQ(z.toString(2),
"0");
A lightweight, non-owning bit vector view backed by a byte array span.
std::string toString(unsigned base=16) const
A mutable bit vector that owns its underlying storage.