Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- Replaced the old `BitVector` with the generic `BitVector<I>` and renamed the
mutable variant to `RawBitVector`.
- Extended `BitVectorBuilder` with `push_bits` and `set_bit` APIs.
- Added `from_bit` constructor on `BitVectorBuilder` for repeating a single bit.
- `DacsByte` now stores level data as zero-copy `View<[u8]>` values.
- Added `get_bits` methods to `BitVectorData` and `BitVector`.
- Added `scripts/devtest.sh` and `scripts/preflight.sh` for testing and
Expand Down
24 changes: 24 additions & 0 deletions src/bit_vector/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,22 @@ impl BitVectorBuilder {
Self::default()
}

/// Creates a builder that stores `len` copies of `bit`.
pub fn from_bit(bit: bool, len: usize) -> Self {
if len == 0 {
return Self::default();
}
let word = if bit { usize::MAX } else { 0 };
let num_words = (len + WORD_LEN - 1) / WORD_LEN;
let mut words = vec![word; num_words];
let shift = len % WORD_LEN;
if shift != 0 {
let mask = (1 << shift) - 1;
*words.last_mut().unwrap() &= mask;
}
Self { words, len }
}

/// Pushes a single bit.
pub fn push_bit(&mut self, bit: bool) {
let pos_in_word = self.len % WORD_LEN;
Expand Down Expand Up @@ -590,6 +606,14 @@ mod tests {
assert_eq!(bv.data.get_bits(61, 7).unwrap(), 0b0111110);
}

#[test]
fn builder_from_bit() {
let builder = BitVectorBuilder::from_bit(true, 5);
let bv: BitVector<NoIndex> = builder.freeze::<NoIndex>();
assert_eq!(bv.len(), 5);
assert_eq!(bv.num_ones(), 5);
}

#[test]
fn iter_collects() {
let data = BitVectorData::from_bits([true, false, true]);
Expand Down