#include <iostream>
#include <climits>
#include <stdexcept>
#include <cassert>
class bitbuffer {
char buffer;
char held_bits;
public:
bitbuffer() :held_bits(0), buffer(0) {}
unsigned long long read(unsigned char bits) {
unsigned long long result = 0;
//if the buffer doesn't hold enough bits
while (bits > held_bits) {
//grab the all bits in the buffer
bits -= held_bits;
result |= ((unsigned long long)buffer) << bits;
//reload the buffer
if (!std::cin)
throw std::runtime_error("");
std::cin.get(buffer);
held_bits = (char)std::cin.gcount() * CHAR_BIT;
}
//append the bits left to the end of the result
result |= buffer >> (held_bits-bits);
//remove those bits from the buffer
held_bits -= bits;
buffer &= (1ull<<held_bits)-1;
return result;
};
};
int main() {
std::cout << "enter 65535: ";
bitbuffer reader; //0x3635353335
assert(reader.read(4) == 0x3);
assert(reader.read(4) == 0x6);
assert(reader.read(8) == 0x35);
assert(reader.read(1) == 0x0);
assert(reader.read(1) == 0x0);
assert(reader.read(1) == 0x1);
assert(reader.read(1) == 0x1);
assert(reader.read(4) == 0x5);
assert(reader.read(16) == 0x3335);
assert(reader.read(8) == 0x0A);
std::cout << "enter FFFFFFFF: ";
assert(reader.read(64) == 0x4646464646464646ull);
std::cout << "PASS!";
return 0;
}