22 std::size_t size_ = 0;
23 std::vector<std::uint64_t> data_;
30 if (size_ % 64 == 0) {
31 data_.push_back(
static_cast<std::uint64_t
>(bit));
33 data_.back() |= 1ull << (size_ % 64);
46 throw std::invalid_argument(
"Packed bit width is greater than 64");
51 if (size_ > std::numeric_limits<std::size_t>::max() - width) {
52 throw std::length_error(
"Packed bit sequence is too large");
55 const std::size_t offset = size_ % 64;
57 data_.push_back(width == 64 ? bits : bits & ((1ull << width) - 1));
59 const std::size_t prefix = std::min(width, 64 - offset);
60 const std::uint64_t prefix_mask =
61 prefix == 64 ? ~std::uint64_t{0} : (1ull << prefix) - 1;
62 data_.back() |= (bits & prefix_mask) << offset;
64 data_.push_back(bits >> prefix);
71 std::size_t
size_bits() const noexcept {
return size_; }
77 const std::size_t words =
87 return std::exchange(data_, {});
Builder for a packed LSB-first bit sequence.
Definition packed_bit_builder.h:20
void write_bit(bool bit)
Append one bit.
Definition packed_bit_builder.h:29
std::vector< std::uint64_t > take_words()
Transfer the packed words and reset this builder.
Definition packed_bit_builder.h:85
std::size_t size_bits() const noexcept
Return the number of appended bits.
Definition packed_bit_builder.h:71
void reserve_bits(std::size_t size_bits)
Reserve storage for at least size_bits bits.
Definition packed_bit_builder.h:76
void write_bits(std::uint64_t bits, std::size_t width)
Append the low width bits of bits, least-significant bit first.
Definition packed_bit_builder.h:44