36class MutableBitVector;
58 std::optional<size_t>
width = std::nullopt, uint8_t
bitIndex = 0);
67 bool getBit(
size_t i)
const;
73 throw std::runtime_error(
"Cannot get data span with non-zero bit index");
95 throw std::invalid_argument(
"msb width exceeds bit width");
99 std::string
toString(
unsigned base = 16)
const;
132 throw std::out_of_range(
"bit_iterator dereference out of range");
156 return !(*
this == other);
171 return !(*
this == sent);
198 const char *fmt,
unsigned target)
const;
215 operator uint64_t()
const {
return toUI64(); }
216 operator uint32_t()
const {
return toUInt<uint32_t>(); }
217 operator uint16_t()
const {
return toUInt<uint16_t>(); }
218 operator uint8_t()
const {
return toUInt<uint8_t>(); }
221 template <
typename T>
223 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value,
224 "T must be an unsigned integral type");
225 constexpr unsigned N =
sizeof(T) * 8;
231 if (this->
width() > N)
233 "UInt does not fit in uint{}_t", N);
234 return static_cast<T
>(
toUI64());
250 int64_t
toI64()
const;
251 operator int64_t()
const {
return toI64(); }
252 operator int32_t()
const {
return toInt<int32_t>(); }
253 operator int16_t()
const {
return toInt<int16_t>(); }
254 operator int8_t()
const {
return toInt<int8_t>(); }
257 template <
typename T>
259 static_assert(std::is_integral<T>::value && std::is_signed<T>::value,
260 "T must be a signed integral type");
261 constexpr unsigned N =
sizeof(T) * 8;
268 if (this->
width() > N) {
269 const uint8_t expected = this->
getBit(N - 1) ? uint8_t{0xFF} : uint8_t{0};
272 return static_cast<T
>(
toI64());
285 std::optional<size_t>
width = std::nullopt);
306 void setBit(
size_t i,
bool v);
348 Int(int64_t v,
unsigned width = 64);
349 operator int64_t()
const {
return IntView(*
this); }
350 operator int32_t()
const {
return IntView(*
this); }
351 operator int16_t()
const {
return IntView(*
this); }
352 operator int8_t()
const {
return IntView(*
this); }
362 operator uint64_t()
const {
return UIntView(*
this); }
363 operator uint32_t()
const {
return UIntView(*
this); }
364 operator uint16_t()
const {
return UIntView(*
this); }
365 operator uint8_t()
const {
return UIntView(*
this); }
372inline constexpr bool std::ranges::enable_borrowed_range<esi::BitVector> =
true;
376 std::ranges::enable_borrowed_range<esi::MutableBitVector> =
true;
Forward iterator for iterating over bits from LSB (index 0) to MSB.
std::forward_iterator_tag iterator_category
bit_iterator & operator++()
Pre-increment: move to next bit.
std::ptrdiff_t difference_type
bool operator!=(std::default_sentinel_t sent) const
Sentinel-compatible inequality.
bool operator<(const bit_iterator &other) const
Less-than comparison (for ranges support).
bool operator==(const bit_iterator &other) const
Equality comparison.
bit_iterator()=default
Default constructor.
const BitVector * bitVector
bool operator==(std::default_sentinel_t) const
Sentinel-compatible equality (for ranges support).
bit_iterator(const BitVector *bv, size_t pos=0)
Construct an iterator at the given bit position.
bit_iterator operator++(int)
Post-increment: move to next bit.
bool operator!=(const bit_iterator &other) const
Inequality comparison.
bool operator*() const
Dereference: returns the bit value at the current position.
A lightweight, non-owning bit vector view backed by a byte array span.
friend MutableBitVector operator^(const BitVector &a, const BitVector &b)
Bitwise XOR: creates a new MutableBitVector with the result.
void checkHighBytesEqual(unsigned lowExclusive, uint8_t expectedByte, const char *fmt, unsigned target) const
friend MutableBitVector operator&(const BitVector &a, const BitVector &b)
Bitwise AND: creates a new MutableBitVector with the result.
BitVector msb(size_t n) const
Return a view of the N most-significant bits.
BitVector slice(size_t offset, size_t sliceWidth) const
Create a new immutable view of a contiguous bit slice [offset, offset+sliceWidth).
BitVector & operator=(const BitVector &other)
bool getBit(size_t i) const
Return the i-th bit (0 = LSB) as boolean.
BitVector lsb(size_t n) const
Return a view of the N least-significant bits.
std::string toString(unsigned base=16) const
bit_iterator begin() const
Return an iterator to the first bit (LSB).
bool operator!=(const BitVector &rhs) const
std::span< const byte > data
BitVector & operator>>=(size_t n)
BitVector operator>>(size_t n) const
Logical right shift that drops the least-significant n bits by advancing the byte/bit index and reduc...
bool operator==(const BitVector &rhs) const
bit_iterator end() const
Return an iterator past the last bit.
std::span< const byte > getSpan() const
Return a handle to the underlying span.
friend MutableBitVector operator|(const BitVector &a, const BitVector &b)
Bitwise OR: creates a new MutableBitVector with the result.
Non-owning view of a signed bit vector with toI64() and implicit conversions to signed scalar types.
IntView(const BitVector &v)
Adopt an existing view as signed.
int64_t toI64() const
Convert to an int64_t, sign-extending from the high bit and throwing if the value does not fit.
A mutable bit vector that owns its underlying storage.
MutableBitVector & operator|=(const MutableBitVector &other)
MutableBitVector & operator>>=(size_t n)
In-place logical right shift that drops the least-significant n bits.
std::vector< uint8_t > takeStorage()
Return and transfer ownership of the underlying storage.
MutableBitVector & operator<<=(size_t n)
In-place logical left shift shifts in n zero bits at LSB, shifting existing bits upward.
MutableBitVector operator~() const
std::span< const byte > getSpan() const
Return a handle to the underlying span (always aligned since bitIndex=0).
MutableBitVector & operator&=(const MutableBitVector &other)
MutableBitVector()=default
std::vector< byte > owner
void setBit(size_t i, bool v)
Set the i-th bit.
MutableBitVector & operator=(const MutableBitVector &other)
MutableBitVector & operator^=(const MutableBitVector &other)
Non-owning view of an unsigned bit vector with toUI64() and implicit conversions to unsigned scalar t...
uint64_t toUI64() const
Convert to a uint64_t, throwing if the value does not fit.
UIntView(const BitVector &v)
Adopt an existing view as unsigned.
std::ostream & operator<<(std::ostream &os, const BitVector &bv)