Supermodel/Src/Util/BitRegister.h

101 lines
3.2 KiB
C++

#ifndef INCLUDED_UTIL_BITREGISTER_H
#define INCLUDED_UTIL_BITREGISTER_H
#include <cstdint>
#include <vector>
#include <ostream>
namespace Util
{
class BitRegister
{
public:
inline bool Empty() const
{
return m_bits.empty();
}
inline size_t Size() const
{
return m_bits.size();
}
// Functions that return all or part of the bit register as an integer
uint8_t GetBit(size_t pos) const;
uint64_t GetBits() const;
uint64_t GetBits(size_t from, size_t count) const;
// Functions that grow/shrink the bit register
void AddToRight(uint8_t bit);
void AddToLeft(uint8_t bit);
uint8_t RemoveFromLeft();
void RemoveFromLeft(size_t count);
uint8_t RemoveFromRight();
void RemoveFromRight(size_t count);
// Functions that preserve the current register size, shifting in the "no
// data" value as needed
void ShiftRight(size_t count);
void ShiftLeft(size_t count);
// Functions that preserve the register size, shifting a bit in one side
// and ejecting one out the other
uint8_t ShiftOutRight(uint8_t bit);
uint8_t ShiftOutLeft(uint8_t bit);
// Functions that insert bits, clipped against current register size
void SetBit(size_t bitPos, uint8_t value);
void Insert(size_t bitPos, const std::string &value);
// Functions that reset the contents but not the size of the register
void SetZeros();
void SetOnes();
// Functions that reset the contents (and size) of the register
void Set(const std::string &value);
void SetZeros(size_t count);
void SetOnes(size_t count);
void Reset();
// Configuration state
void SetNoBitValue(uint8_t bit);
// String serialization
std::string ToBinaryString() const;
std::string ToHexString() const;
friend std::ostream &operator<<(std::ostream &os, const BitRegister &reg);
// Constructors
BitRegister();
BitRegister(size_t count);
BitRegister(size_t count, uint8_t bit);
private:
/*
* Vector layout:
*
* Index: 0 1 2 3 ... N
* +---+---+---+---+-...-+---+
* <-- left -- | 1 | 0 | 1 | 1 | ... | 1 | -- right -->
* +---+---+---+---+-...-+---+
*
* "Left" means lower indices in the array and bits are numbered left to
* right (leftmost bit is bit 0). Insertions of values into the bit vector
* place the MSB in a lower bit number than successive bits. For example,
* insertion of the 8-bit value 0xe2 at bit position 2 places the MSB (1)
* in bit 2, 0 in bit 3, 1 in bit 4, 0 in bit 5, etc.
*/
std::vector<uint8_t> m_bits;
uint8_t m_no_data = 0; // by default, assume non-existent bits are 0
uint8_t GetLeftmost() const;
uint8_t GetRightmost() const;
static size_t HexStart(const std::string &value);
static size_t BinStart(const std::string &value);
static size_t CountBitsHex(const std::string &value, size_t startPos);
static size_t CountBitsBin(const std::string &value, size_t startPos);
};
} // Util
#endif // INCLUDED_UTIL_BITREGISTER_H