11#ifndef JAU_BITHEAP_HPP_
12#define JAU_BITHEAP_HPP_
66 typedef std::vector<unit_type> storage_t;
74 return bitpos + length <= bit_size;
91 : bit_size(bitstr.
size()),
96 if( !
put(0, bitstr) ) {
102 bit_size = new_bit_size;
104 storage.resize(unit_size, 0);
127 return storage[u] & (one_u << b);
158 if ( storage[u] & m ) {
168 for (
size_type i = 0; i < unit_size; ++i ) {
190 for(
size_type l = 0, r = bit_size-1; l < r; ++l, --r) {
191 const bool s =
get(l);
202 [[nodiscard]]
constexpr bool set(
size_type bitpos)
noexcept {
return put(bitpos,
true); }
207 [[nodiscard]]
constexpr bool clr(
size_type bitpos)
noexcept {
return put(bitpos,
false); }
219 return put(dstBitpos,
get(srcBitpos));
232 return m & storage[u];
236 const size_type l1 = std::min(length, left);
242 return d1 | ((
m2 & storage[u + 1]) << l1);
264 storage[u] = ((~m) & storage[u])
269 const size_type l1 = std::min(length, left);
271 storage[u] = ((~(
m1 << b)) & storage[u])
272 | ((
m1 & data) << b);
276 storage[u + 1] = ((
~m2) & storage[u + 1])
277 | (
m2 & (data >> l1));
289 [[nodiscard]]
bool put(
size_type bitpos, std::string_view bitstr)
noexcept {
290 if ( 0 == bitstr.size() ) {
292 }
else if ( !
in_range(bitpos, bitstr.size()) ) {
299 std::string_view segment = bitstr.substr(strPos, len);
318 }
else if ( !
in_range(bitpos, length) ) {
321 const unit_type v = bit ? std::numeric_limits<unit_type>::max() : 0;
341 if ( remaining > 0 ) {
348 assert(0 == remaining);
354 (void)
set(0, bit_size, bit);
369 for (
size_type i = 0; i < unit_size; ++i ) {
375 if (
this == &rhs ) {
378 if ( unit_size != rhs.unit_size ) {
382 while ( i < unit_size && storage[i] == rhs.storage[i] ) {
385 return i == unit_size;
389 size_t length = o.bit_size;
392 }
else if ( !
in_range(bitpos, length) ) {
398 if ( 0 == unit_bit_pos ) {
401 for (
size_type u = 0; u < unit_count && 0 < length; ++u ) {
402 if( !
putUnit( i, l, o.storage[u] ) ) {
410 for (
size_type i = 0; i < length; ++i ) {
411 if( !
put(bitpos + i, o.
get(i)) ) {
422 }
else if ( !
in_range(bitpos, length) ) {
425 std::pair<bitheap, bool> r{
bitheap(length),
true };
429 if ( 0 == unit_bit_pos ) {
432 for (
size_type u = unit_pos; u < unit_count && 0 < length; ++u ) {
433 if( !r.first.putUnit( i, l, storage[u] ) ) {
442 if( !r.first.put(i,
get(bitpos+i)) ) {
451 if ( 0 == length || !
in_range(bitpos, length) ) {
462 if ( 0 == bit_pos ) {
466 for (
size_type i = unit_pos + unit_count; i-- > unit_pos && 0 < length; ) {
473 while(length-- > 0) {
474 r.push_back(
get(--i) ?
'1' :
'0');
484 return "bitfield[unit[bits "+std::to_string(
unit_bit_size)+
", count "+std::to_string(unit_size)+
485 "], bits"+std::to_string(bit_size)+
": "+
toString()+
"]";
Simple dynamically heap-sized bitheap for efficient bit storage access in O(1).
constexpr bitheap(size_type bitSize) noexcept
Constructs an empty bitheap instance.
constexpr bool in_range(size_type bitpos, size_type length) const noexcept
constexpr bool set(size_type bitpos) noexcept
Sets the bit at position bitpos of this storage.
size_type count() const noexcept
constexpr bool operator[](size_type bitpos) const noexcept
constexpr bool in_range(size_type bitpos) const noexcept
std::string toString(size_type bitpos, size_type length, PrefixOpt prefix=PrefixOpt::none) const noexcept
unit_type getUnit(size_type bitpos, size_type length) const noexcept
constexpr bitheap & flip() noexcept
constexpr bool operator==(const bitheap &rhs) const noexcept
std::string toString(PrefixOpt prefix=PrefixOpt::none) const noexcept
static constexpr size_type unit_byte_size
One unit size in bytes.
std::string infoString() const noexcept
bool set(size_type bitpos, size_type length, bool bit) noexcept
Set length bits starting at bitpos of this bitfield to the given value bit.
constexpr bool reset(size_type bitpos) noexcept
Clear the bit at position bitpos of this storage.
constexpr bool get(size_type bitpos) const noexcept
constexpr bool clr(size_type bitpos) noexcept
Clear the bit at position bitpos of this storage.
std::pair< bitheap, bool > subbits(size_type bitpos, size_type length) const noexcept
constexpr size_type size() const noexcept
Returns storage size in bits.
constexpr bitheap & reset() noexcept
bool putUnit(size_type bitpos, size_type length, unit_type data) noexcept
Writes length bits of given data into this storage, starting with the lowest bit from the storage pos...
static constexpr size_type unit_bit_size
One unit size in bits.
bool copyUnit(size_type srcBitpos, size_type dstBitpos, size_type length) noexcept
Copies length bits at position srcBitpos to position dstBitpos, returning the copied bits.
bitheap & setAll(bool bit) noexcept
Set all bits of this bitfield to the given value bit.
unsigned long unit_type
Unit data type.
bool put(size_type bitpos, std::string_view bitstr) noexcept
Writes bitstr msb bit-pattern into this storage, starting with the lowest bit from the storage positi...
static constexpr size_type unit_shift
One unit shift amount.
constexpr bool flip(size_type bitpos) noexcept
Flips the bit value at position bitpos in this storage.
constexpr bool put(size_type bitpos, bool v) noexcept
Writes the bit value v to position bitpos into this storage.
size_t size_type
size_t data type, bit position and count
bitheap(std::string_view bitstr)
Constructs a bitheap instance, initialized with bitstr msb bit-pattern.
bool copy(size_type srcBitpos, size_type dstBitpos) noexcept
Copies the bit at position srcBitpos to position dstBitpos, returning the copied bit-value.
void resize(size_t new_bit_size)
constexpr void clear() noexcept
constexpr bitheap & reverse() noexcept
bool put(size_t bitpos, const bitheap &o)
static constexpr T bit_mask(size_t n) noexcept
Returns the T bit mask of n-bits, i.e.
std::ostream & operator<<(std::ostream &out, const bitfield_t< StorageType, BitSize > &v)
constexpr uint8_t rev_bits(uint8_t v) noexcept
Reverse bits of one byte.
constexpr size_t log2_byteshift(const size_t bytesize) noexcept
Returns log2(bytesize*8), e.g.
constexpr T max(const T x, const T y) noexcept
Returns the maximum of two integrals (w/ branching) in O(1)
constexpr size_t bit_count(T n) noexcept
Returns the number of set bits within given unsigned integral.
std::string toBitString(const void *data, const nsize_t length, const bit_order_t bitOrder=bit_order_t::msb, const PrefixOpt prefix=PrefixOpt::prefix, size_t bit_len=0) noexcept
Produce a binary string representation of the given lsb-first byte values.
SizeBoolPair fromBitString(std::vector< uint8_t > &out, const uint8_t bitstr[], const size_t bitstr_len, const bit_order_t bitOrder=bit_order_t::msb, const Bool checkPrefix=Bool::True) noexcept
Converts a given binary string representation into a byte vector, lsb-first.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
@ msb
Identifier for most-significant-bit (msb) first.
static const Mat4f m1(m1_0)
static const Mat4f m2(m2_0)