#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 ®); // 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