diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index a6bbefd..9e3bff9 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -28,6 +28,10 @@ jobs: run: cargo test --features miniserde --verbose - name: Run borsh tests run: cargo test --features borsh --verbose + - name: Run smallvec tests + run: cargo test --features smallvec --verbose + - name: Run smallvec and serde tests + run: cargo test --features smallvec,serde --verbose miri: name: "Miri" @@ -58,7 +62,7 @@ jobs: strategy: fail-fast: false matrix: - rust: [1.85.0, 1.86.0] + rust: [1.86.0, 1.87.0] timeout-minutes: 45 steps: - uses: actions/checkout@v5 @@ -67,16 +71,22 @@ jobs: toolchain: ${{matrix.rust}} - run: cargo build - run: cargo build --features serde + - run: cargo build --features serde,smallvec - run: cargo build --features serde --no-default-features + - run: cargo build --features serde,smallvec --no-default-features - run: cargo build --features miniserde - run: cargo build --features borsh - run: cargo build --features borsh,serde - run: cargo build --features borsh,serde,miniserde - run: cargo build --features borsh,serde,miniserde --no-default-features + - run: cargo build --features borsh,serde,miniserde,smallvec --no-default-features - run: cargo test - run: cargo test --features serde + - run: cargo test --features serde,smallvec - run: cargo test --features borsh,serde,miniserde + - run: cargo test --features borsh,serde,miniserde,smallvec - run: cargo test --features borsh,serde,miniserde --no-default-features + - run: cargo test --features borsh,serde,miniserde,smallvec --no-default-features clippy: runs-on: ubuntu-latest @@ -90,6 +100,7 @@ jobs: - run: cargo clippy --workspace --tests --examples --features serde - run: cargo clippy --workspace --tests --examples --features miniserde - run: cargo clippy --workspace --tests --examples --features borsh + - run: cargo clippy --workspace --tests --examples --features smallvec docs: runs-on: ubuntu-latest @@ -102,3 +113,13 @@ jobs: toolchain: stable - uses: swatinem/rust-cache@v2 - run: cargo doc --workspace --no-deps + + success: + runs-on: ubuntu-latest + needs: [fmt, clippy, miri, msrv] + steps: + - uses: actions/checkout@v5 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + - run: echo empty diff --git a/.vscode/settings.json b/.vscode/settings.json index d8146ae..f7b4abd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,4 @@ { "rust-analyzer.check.command": "clippy", - "rust-analyzer.cargo.features": ["serde", "borsh", "miniserde"] + "rust-analyzer.cargo.features": ["serde", "borsh", "miniserde", "smallvec"] } diff --git a/matrix/Cargo.toml b/matrix/Cargo.toml index d872946..772aca7 100644 --- a/matrix/Cargo.toml +++ b/matrix/Cargo.toml @@ -18,7 +18,7 @@ name = "bit_matrix" [dependencies] serde = { version = "1.0", default-features = false, features = ["derive", "alloc"], optional = true } miniserde = { version = "0.1", optional = true } -borsh = { version = "1.7.0", optional = true } +borsh = { version = "1.8.0", optional = true } [dependencies.bit-vec] path = "../vec/" diff --git a/matrix/src/lib.rs b/matrix/src/lib.rs index d215c4a..6ea3870 100644 --- a/matrix/src/lib.rs +++ b/matrix/src/lib.rs @@ -75,6 +75,8 @@ #![warn(clippy::multiple_crate_versions)] #![warn(clippy::single_match)] #![warn(clippy::missing_safety_doc)] +// FIXME https://github.com/near/borsh/issues/159 +#![allow(clippy::multiple_crate_versions)] mod matrix; mod row; diff --git a/matrix/src/matrix.rs b/matrix/src/matrix.rs index 8c8406d..a813dd6 100644 --- a/matrix/src/matrix.rs +++ b/matrix/src/matrix.rs @@ -24,7 +24,7 @@ impl BitMatrix { /// Create a new BitMatrix with specific numbers of bits in columns and rows. pub fn new(rows: usize, row_bits: usize) -> Self { BitMatrix { - bit_vec: BitVec::from_elem_general(round_up_to_next(row_bits, B::bits()) * rows, false), + bit_vec: BitVec::from_elem_general(round_up_to_next(row_bits, B::BITS) * rows, false), row_bits, } } @@ -35,7 +35,7 @@ impl BitMatrix { if self.row_bits == 0 { 0 } else { - let row_blocks = round_up_to_next(self.row_bits, B::bits()) / B::bits(); + let row_blocks = round_up_to_next(self.row_bits, B::BITS) / B::BITS; self.bit_vec.storage().len() / row_blocks } } @@ -58,7 +58,7 @@ impl BitMatrix { /// Panics if `(row, col)` is out of bounds. #[inline] pub fn set(&mut self, row: usize, col: usize, enabled: bool) { - let row_size_in_bits = round_up_to_next(self.row_bits, B::bits()); + let row_size_in_bits = round_up_to_next(self.row_bits, B::BITS); self.bit_vec.set(row * row_size_in_bits + col, enabled); } @@ -71,19 +71,19 @@ impl BitMatrix { /// Grows the matrix in-place, adding `num_rows` rows filled with `value`. pub fn grow(&mut self, num_rows: usize, value: bool) { self.bit_vec - .grow(round_up_to_next(self.row_bits, B::bits()) * num_rows, value); + .grow(round_up_to_next(self.row_bits, B::BITS) * num_rows, value); } /// Truncates the matrix. pub fn truncate(&mut self, num_rows: usize) { self.bit_vec - .truncate(round_up_to_next(self.row_bits, B::bits()) * num_rows); + .truncate(round_up_to_next(self.row_bits, B::BITS) * num_rows); } /// Returns a slice of the matrix's rows. #[inline] pub fn sub_matrix>(&self, range: R) -> BitSubMatrix<'_, B> { - let row_size = round_up_to_next(self.row_bits, B::bits()) / B::bits(); + let row_size = round_up_to_next(self.row_bits, B::BITS) / B::BITS; BitSubMatrix { slice: &self.bit_vec.storage()[( range.start_bound().map(|&s| s * row_size), @@ -111,7 +111,7 @@ impl BitMatrix { } fn row_size(&self) -> usize { - round_up_to_next(self.row_bits, B::bits()) / B::bits() + round_up_to_next(self.row_bits, B::BITS) / B::BITS } /// Given a row's index, returns a slice of all rows above that row, a reference to said row, @@ -131,7 +131,7 @@ impl BitMatrix { /// and a slice of all rows below. #[inline] pub fn split_at_mut(&mut self, row: usize) -> (BitSubMatrixMut<'_, B>, BitSubMatrixMut<'_, B>) { - let row_size = round_up_to_next(self.row_bits, B::bits()) / B::bits(); + let row_size = round_up_to_next(self.row_bits, B::BITS) / B::BITS; let (first, second) = unsafe { self.bit_vec.storage_mut().split_at_mut(row * row_size) }; ( BitSubMatrixMut::new(first, self.row_bits), @@ -198,7 +198,7 @@ impl Index for BitMatrix { #[inline] fn index(&self, row: usize) -> &Self::Output { - let row_size = round_up_to_next(self.row_bits, B::bits()) / B::bits(); + let row_size = round_up_to_next(self.row_bits, B::BITS) / B::BITS; BitSlice::new(&self.bit_vec.storage()[row * row_size..(row + 1) * row_size]) } } @@ -207,7 +207,7 @@ impl Index for BitMatrix { impl IndexMut for BitMatrix { #[inline] fn index_mut(&mut self, row: usize) -> &mut Self::Output { - let row_size = round_up_to_next(self.row_bits, B::bits()) / B::bits(); + let row_size = round_up_to_next(self.row_bits, B::BITS) / B::BITS; // Safety: // This does not introduce any memory unsafety despite the `unsafe` keyword. unsafe { @@ -225,7 +225,7 @@ impl Index<(usize, usize)> for BitMatrix { #[inline] fn index(&self, (row, col): (usize, usize)) -> &bool { - let row_size_in_bits = round_up_to_next(self.row_bits, B::bits()); + let row_size_in_bits = round_up_to_next(self.row_bits, B::BITS); if self.bit_vec.get(row * row_size_in_bits + col).unwrap() { &TRUE } else { diff --git a/matrix/src/row.rs b/matrix/src/row.rs index 740e3b7..f282ec8 100644 --- a/matrix/src/row.rs +++ b/matrix/src/row.rs @@ -17,7 +17,7 @@ impl BitSlice { #[inline] pub fn new(slice: &[Block]) -> &Self { // Safety: - // This is the only way to construct a custom DST. + // This is currently the only way to construct a custom DST. // We wish the layout of DSTs were defined. unsafe { mem::transmute(slice) } } @@ -26,7 +26,7 @@ impl BitSlice { #[inline] pub fn new_mut(slice: &mut [Block]) -> &mut Self { // Safety: - // This is the only way to construct a custom DST. + // This is currently the only way to construct a custom DST. // We wish the layout of DSTs were defined. unsafe { mem::transmute(slice) } } @@ -50,21 +50,21 @@ impl BitSlice { /// Returns `true` if a bit is enabled in the bit vector slice, or `false` otherwise. #[inline] pub fn get(&self, bit: usize) -> bool { - let (block, i) = div_rem(bit, Block::bits()); + let (block, i) = div_rem(bit, Block::BITS); match self.slice.get(block) { None => false, - Some(&b) => (b & (Block::one() << i)) != Block::zero(), + Some(&b) => (b & (Block::ONE << i)) != Block::ZERO, } } /// Returns a small integer-sized slice of the bit vector slice. #[inline] pub fn small_slice_aligned(&self, bit: usize, len: u8) -> Block { - let (block, i) = div_rem(bit, Block::bits()); + let (block, i) = div_rem(bit, Block::BITS); match self.slice.get(block) { - None => Block::zero(), + None => Block::ZERO, Some(&b) => { - let len_mask = (Block::one() << len as usize) - Block::one(); + let len_mask = (Block::ONE << len as usize) - Block::ONE; (b >> i) & len_mask } } @@ -78,11 +78,11 @@ impl ops::Index for BitSlice { #[inline] fn index(&self, bit: usize) -> &bool { - let (block, i) = div_rem(bit, Block::bits()); + let (block, i) = div_rem(bit, Block::BITS); match self.slice.get(block) { None => &FALSE, Some(&b) => { - if (b & (Block::one() << i)) != Block::zero() { + if (b & (Block::ONE << i)) != Block::ZERO { &TRUE } else { &FALSE diff --git a/matrix/src/submatrix.rs b/matrix/src/submatrix.rs index 3cedd5f..6f193b1 100644 --- a/matrix/src/submatrix.rs +++ b/matrix/src/submatrix.rs @@ -37,10 +37,7 @@ impl<'a, B: BitBlock> BitSubMatrix<'a, B> { #[inline] pub unsafe fn from_raw_parts(ptr: *const B, rows: usize, row_bits: usize) -> Self { BitSubMatrix { - slice: slice::from_raw_parts( - ptr, - round_up_to_next(row_bits, B::bits()) / B::bits() * rows, - ), + slice: slice::from_raw_parts(ptr, round_up_to_next(row_bits, B::BITS) / B::BITS * rows), row_bits, } } @@ -53,12 +50,12 @@ impl<'a, B: BitBlock> BitSubMatrix<'a, B> { // We wish the layout of DSTs were defined. unsafe { mem::transmute(arg) } } - let row_size = round_up_to_next(self.row_bits, B::bits()) / B::bits(); + let row_size = round_up_to_next(self.row_bits, B::BITS) / B::BITS; self.slice.chunks(row_size).map(f::) } fn row_size(&self) -> usize { - round_up_to_next(self.row_bits, B::bits()) / B::bits() + round_up_to_next(self.row_bits, B::BITS) / B::BITS } } @@ -78,7 +75,7 @@ impl<'a, B: BitBlock> BitSubMatrixMut<'a, B> { BitSubMatrixMut { slice: slice::from_raw_parts_mut( ptr, - round_up_to_next(row_bits, B::bits()) / B::bits() * rows, + round_up_to_next(row_bits, B::BITS) / B::BITS * rows, ), row_bits, } @@ -103,9 +100,9 @@ impl<'a, B: BitBlock> BitSubMatrixMut<'a, B> { /// Panics if `(row, col)` is out of bounds. #[inline] pub fn set(&mut self, row: usize, col: usize, enabled: bool) { - let row_size_in_bits = round_up_to_next(self.row_bits, B::bits()); + let row_size_in_bits = round_up_to_next(self.row_bits, B::BITS); let bit = row * row_size_in_bits + col; - let (block, i) = div_rem(bit, B::bits()); + let (block, i) = div_rem(bit, B::BITS); assert!( block < self.slice.len() && col < self.row_bits, "invalid index given to `BitSubMatrixMut::set`" @@ -115,9 +112,9 @@ impl<'a, B: BitBlock> BitSubMatrixMut<'a, B> { // We check for `block` being within bounds in the assert above. let elt = self.slice.get_unchecked_mut(block); if enabled { - *elt |= B::one() << i; + *elt |= B::ONE << i; } else { - *elt = *elt & !(B::one() << i); + *elt = *elt & !(B::ONE << i); } } } @@ -129,17 +126,17 @@ impl<'a, B: BitBlock> BitSubMatrixMut<'a, B> { /// Unsafe if `(row, col)` is out of bounds. #[inline] pub unsafe fn set_unchecked(&mut self, row: usize, col: usize, enabled: bool) { - let row_size_in_bits = round_up_to_next(self.row_bits, B::bits()); + let row_size_in_bits = round_up_to_next(self.row_bits, B::BITS); let bit = row * row_size_in_bits + col; - let (block, i) = div_rem(bit, B::bits()); + let (block, i) = div_rem(bit, B::BITS); unsafe { // Safety: // Unsafe if `(row, col)` is out of bounds. let elt = self.slice.get_unchecked_mut(block); if enabled { - *elt |= B::one() << i; + *elt |= B::ONE << i; } else { - *elt = *elt & !(B::one() << i); + *elt = *elt & !(B::ONE << i); } } } @@ -242,7 +239,7 @@ impl<'a, B: BitBlock> BitSubMatrixMut<'a, B> { } fn row_size(&self) -> usize { - round_up_to_next(self.row_bits, B::bits()) / B::bits() + round_up_to_next(self.row_bits, B::BITS) / B::BITS } } diff --git a/set/Cargo.toml b/set/Cargo.toml index 89a9614..1f23677 100644 --- a/set/Cargo.toml +++ b/set/Cargo.toml @@ -13,7 +13,7 @@ readme = "README.md" edition = "2021" [dependencies] -borsh = { version = "1.7.0", default-features = false, features = ["derive"], optional = true } +borsh = { version = "1.8.0", default-features = false, features = ["derive"], optional = true } serde = { version = "1.0", default-features = false, features = ["derive", "alloc"], optional = true } miniserde = { version = "0.1", optional = true } diff --git a/set/src/iter.rs b/set/src/iter.rs index e43722e..ddce8c6 100644 --- a/set/src/iter.rs +++ b/set/src/iter.rs @@ -12,7 +12,7 @@ where T: Iterator, { fn from_blocks(mut blocks: T) -> Self { - let h = blocks.next().unwrap_or(B::zero()); + let h = blocks.next().unwrap_or(B::ZERO); BlockIter { tail: blocks, head: h, @@ -212,21 +212,18 @@ where type Item = usize; fn next(&mut self) -> Option { - while self.head == B::zero() { - match self.tail.next() { - Some(w) => self.head = w, - None => return None, - } - self.head_offset += B::bits(); + while self.head == B::ZERO { + self.head = self.tail.next()?; + self.head_offset += B::BITS; } // from the current block, isolate the // LSB and subtract 1, producing k: // a block with a number of set bits // equal to the index of the LSB - let k = (self.head & (!self.head + B::one())) - B::one(); + let k = (self.head & (!self.head + B::ONE)) - B::ONE; // update block, removing the LSB - self.head = self.head & (self.head - B::one()); + self.head = self.head & (self.head - B::ONE); // return offset + (index of LSB) Some(self.head_offset + B::count_ones(k)) } @@ -238,7 +235,7 @@ where #[inline] fn size_hint(&self) -> (usize, Option) { match self.tail.size_hint() { - (_, Some(h)) => (0, Some((1 + h) * B::bits())), + (_, Some(h)) => (0, Some((1 + h) * B::BITS)), _ => (0, None), } } @@ -250,8 +247,8 @@ impl Iterator for TwoBitPositions<'_, B> { fn next(&mut self) -> Option { match (self.set.next(), self.other.next()) { (Some(a), Some(b)) => Some((self.merge)(a, b)), - (Some(a), None) => Some((self.merge)(a, B::zero())), - (None, Some(b)) => Some((self.merge)(B::zero(), b)), + (Some(a), None) => Some((self.merge)(a, B::ZERO)), + (None, Some(b)) => Some((self.merge)(B::ZERO, b)), _ => None, } } diff --git a/set/src/lib.rs b/set/src/lib.rs index ceca689..1f67051 100644 --- a/set/src/lib.rs +++ b/set/src/lib.rs @@ -57,10 +57,15 @@ #![warn(clippy::multiple_crate_versions)] #![warn(clippy::single_match)] #![warn(clippy::missing_safety_doc)] +// FIXME https://github.com/near/borsh/issues/159 +#![allow(clippy::multiple_crate_versions)] #[cfg(any(test, feature = "std"))] extern crate std; +#[cfg(not(feature = "std"))] +extern crate alloc; + mod iter; mod set; mod util; @@ -70,6 +75,14 @@ pub(crate) mod local_prelude { pub use core::cmp::Ordering; pub use core::iter::{self, Chain, Enumerate, FromIterator, Repeat, Skip, Take}; pub use core::{cmp, fmt, hash}; + + #[cfg(feature = "std")] + pub use std::vec::Vec; + + #[cfg(not(feature = "std"))] + pub use alloc::vec::Vec; + + pub(crate) use crate::util; } pub use bit_vec::BitBlock; diff --git a/set/src/set.rs b/set/src/set.rs index a44fa9f..0421cc8 100644 --- a/set/src/set.rs +++ b/set/src/set.rs @@ -1,4 +1,6 @@ -use crate::{local_prelude::*, util}; +use bit_vec::BitContainer; + +use crate::local_prelude::*; #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr( @@ -9,8 +11,8 @@ use crate::{local_prelude::*, util}; feature = "miniserde", derive(miniserde::Deserialize, miniserde::Serialize) )] -pub struct BitSet { - pub(crate) bit_vec: BitVec, +pub struct BitSet = Vec> { + pub(crate) bit_vec: BitVec, } impl Clone for BitSet { @@ -365,8 +367,8 @@ impl BitSet { unsafe { self_bit_vec.storage_mut()[i] = new; } - if i == self_bit_vec.storage().len() - 1 && self_bit_vec.len() % B::bits() > 0 { - debug_assert!(new >> (self_bit_vec.len() % B::bits()) == B::zero()); + if i == self_bit_vec.storage().len() - 1 && self_bit_vec.len() % B::BITS > 0 { + debug_assert!(new >> (self_bit_vec.len() % B::BITS) == B::ZERO); } } } @@ -400,7 +402,7 @@ impl BitSet { .storage() .iter() .rev() - .take_while(|&&n| n == B::zero()) + .take_while(|&&n| n == B::ZERO) .count(); // Truncate away all empty trailing blocks, then shrink_to_fit let trunc_len = old_len - n; @@ -411,7 +413,7 @@ impl BitSet { // thus maintaining the trailing bit invariant. unsafe { bit_vec.storage_mut().truncate(trunc_len); - bit_vec.set_len(trunc_len * B::bits()); + bit_vec.set_len(trunc_len * B::BITS); } bit_vec.shrink_to_fit(); } @@ -672,7 +674,7 @@ impl BitSet { // Check that `self` intersect `other` is self self_bit_vec.blocks().zip(other_bit_vec.blocks()).all(|(w1, w2)| w1 & w2 == w1) && // Make sure if `self` has any more blocks than `other`, they're all 0 - self_bit_vec.blocks().skip(other_blocks).all(|w| w == B::zero()) + self_bit_vec.blocks().skip(other_blocks).all(|w| w == B::ZERO) } /// Returns `true` if the set is a superset of another. diff --git a/set/src/util.rs b/set/src/util.rs index c024242..7d3f726 100644 --- a/set/src/util.rs +++ b/set/src/util.rs @@ -1,3 +1,5 @@ +use bit_vec::BitContainer; + use crate::local_prelude::*; #[allow(type_alias_bounds)] @@ -14,19 +16,19 @@ pub(crate) fn blocks_for_bits(bits: usize) -> usize { // // Note that we can technically avoid this branch with the expression // `(nbits + BITS - 1) / 32::BITS`, but if nbits is almost usize::MAX this will overflow. - if bits % B::bits() == 0 { - bits / B::bits() + if bits % B::BITS == 0 { + bits / B::BITS } else { - bits / B::bits() + 1 + bits / B::BITS + 1 } } #[allow(clippy::iter_skip_zero)] // Take two BitVec's, and return iterators of their words, where the shorter one // has been padded with 0's -pub(crate) fn match_words<'a, 'b, B: BitBlock>( - a: &'a BitVec, - b: &'b BitVec, +pub(crate) fn match_words<'a, 'b, B: BitBlock, C: BitContainer>( + a: &'a BitVec, + b: &'b BitVec, ) -> (MatchWords<'a, B>, MatchWords<'b, B>) { let a_len = a.storage().len(); let b_len = b.storage().len(); @@ -36,19 +38,19 @@ pub(crate) fn match_words<'a, 'b, B: BitBlock>( ( a.blocks() .enumerate() - .chain(iter::repeat(B::zero()).enumerate().take(b_len).skip(a_len)), + .chain(iter::repeat(B::ZERO).enumerate().take(b_len).skip(a_len)), b.blocks() .enumerate() - .chain(iter::repeat(B::zero()).enumerate().take(0).skip(0)), + .chain(iter::repeat(B::ZERO).enumerate().take(0).skip(0)), ) } else { ( a.blocks() .enumerate() - .chain(iter::repeat(B::zero()).enumerate().take(0).skip(0)), + .chain(iter::repeat(B::ZERO).enumerate().take(0).skip(0)), b.blocks() .enumerate() - .chain(iter::repeat(B::zero()).enumerate().take(a_len).skip(b_len)), + .chain(iter::repeat(B::ZERO).enumerate().take(a_len).skip(b_len)), ) } } diff --git a/vec/Cargo.toml b/vec/Cargo.toml index b8fbc53..7be799e 100644 --- a/vec/Cargo.toml +++ b/vec/Cargo.toml @@ -13,9 +13,10 @@ readme = "README.md" edition = "2021" [dependencies] -borsh = { version = "1.7.0", default-features = false, features = ["derive"], optional = true } +borsh = { version = "1.8.0", default-features = false, features = ["derive"], optional = true } serde = { version = "1.0", default-features = false, features = ["derive", "alloc"], optional = true } miniserde = { version = "0.1", optional = true } +smallvec = { version = "1.15", optional = true } [dev-dependencies] serde_json = "1.0" @@ -27,6 +28,7 @@ generic-tests = "0.1" default = ["std"] std = ["serde?/std", "borsh?/std"] allocator_api = [] +serde = ["dep:serde", "smallvec?/serde"] [package.metadata.docs.rs] features = ["borsh", "serde", "miniserde"] diff --git a/vec/src/block.rs b/vec/src/block.rs new file mode 100644 index 0000000..3811afd --- /dev/null +++ b/vec/src/block.rs @@ -0,0 +1,61 @@ +use core::hash; +use core::ops::*; + +/// Abstracts over a pile of bits (basically unsigned primitives) +pub trait BitBlock: + Copy + + Add + + Sub + + Shl + + Shr + + Not + + BitAnd + + BitOr + + BitXor + + Rem + + BitOrAssign + + Eq + + Ord + + hash::Hash +{ + /// How many bits it has + const BITS: usize; + /// How many bytes it has + const BYTES: usize = Self::BITS / 8; + /// Convert a byte into this type (lowest-order bits set) + fn from_byte(byte: u8) -> Self; + /// Count the number of 1's in the bitwise repr + fn count_ones(self) -> usize; + /// Count the number of 0's in the bitwise repr + fn count_zeros(self) -> usize { + Self::BITS - self.count_ones() + } + /// Get `0` + const ZERO: Self; + /// Get `1` + const ONE: Self; +} + +macro_rules! bit_block_impl { + ($(($t: ident, $size: expr)),*) => ($( + impl BitBlock for $t { + const BITS: usize = $size; + #[inline] + fn from_byte(byte: u8) -> Self { $t::from(byte) } + #[inline] + fn count_ones(self) -> usize { self.count_ones() as usize } + #[inline] + fn count_zeros(self) -> usize { self.count_zeros() as usize } + const ONE: Self = 1; + const ZERO: Self = 0; + } + )*) +} + +bit_block_impl! { + (u8, 8), + (u16, 16), + (u32, 32), + (u64, 64), + (usize, usize::BITS as usize) +} diff --git a/vec/src/blocks.rs b/vec/src/blocks.rs new file mode 100644 index 0000000..53793b3 --- /dev/null +++ b/vec/src/blocks.rs @@ -0,0 +1,42 @@ +use crate::local_prelude::*; +use core::slice; + +impl BitVec { + /// Iterator over the underlying blocks of data + #[inline] + pub fn blocks(&self) -> Blocks<'_, C::Block> { + // (2) + Blocks { + iter: self.storage.slice().iter(), + } + } +} + +/// An iterator over the blocks of a `BitVec`. +#[derive(Clone)] +pub struct Blocks<'a, B: 'a + BitBlock> { + iter: slice::Iter<'a, B>, +} + +impl Iterator for Blocks<'_, B> { + type Item = B; + + #[inline] + fn next(&mut self) -> Option { + self.iter.next().cloned() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } +} + +impl DoubleEndedIterator for Blocks<'_, B> { + #[inline] + fn next_back(&mut self) -> Option { + self.iter.next_back().cloned() + } +} + +impl ExactSizeIterator for Blocks<'_, B> {} diff --git a/vec/src/blocks_mut.rs b/vec/src/blocks_mut.rs new file mode 100644 index 0000000..dea5158 --- /dev/null +++ b/vec/src/blocks_mut.rs @@ -0,0 +1,39 @@ +use crate::local_prelude::*; +use core::slice; + +impl BitVec { + /// Iterator over mutable refs to the underlying blocks of data. + #[inline] + pub(crate) fn blocks_mut(&mut self) -> BlocksMut<'_, C::Block> { + // (2) + BlocksMut(self.storage.slice_mut().iter_mut()) + } +} + +pub struct BlocksMut<'a, B: BitBlock>(slice::IterMut<'a, B>); + +impl<'a, B> Iterator for BlocksMut<'a, B> +where + B: BitBlock, +{ + type Item = &'a mut B; + + #[inline] + fn next(&mut self) -> Option { + self.0.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } +} + +impl DoubleEndedIterator for BlocksMut<'_, B> { + #[inline] + fn next_back(&mut self) -> Option { + self.0.next_back() + } +} + +impl ExactSizeIterator for BlocksMut<'_, B> {} diff --git a/vec/src/container.rs b/vec/src/container.rs new file mode 100644 index 0000000..ec845eb --- /dev/null +++ b/vec/src/container.rs @@ -0,0 +1,270 @@ +use crate::local_prelude::*; +use core::ops; + +#[allow(clippy::len_without_is_empty)] +pub trait BitContainer: Clone { + type Block: BitBlock; + + const BITS: usize = Self::Block::BITS; + const BYTES: usize = Self::Block::BYTES; + const ONE: Self::Block = Self::Block::ONE; + const ZERO: Self::Block = Self::Block::ZERO; + + type Alloc: Default; + fn new_in(alloc: Self::Alloc) -> Self; + fn slice(&self) -> &[Self::Block]; + fn slice_mut(&mut self) -> &mut [Self::Block]; + fn len(&self) -> usize { + self.slice().len() + } + fn pop(&mut self) -> Option; + fn drain>(&mut self, range: R) -> impl Iterator; + fn capacity(&self) -> usize; + fn append(&mut self, other: &mut Self); + fn reserve(&mut self, additional: usize); + fn push(&mut self, value: Self::Block); + fn split_off(&mut self, at: usize) -> Self; + fn truncate(&mut self, len: usize); + fn reserve_exact(&mut self, len: usize); + fn shrink_to_fit(&mut self); + fn extend(&mut self, iter: T) + where + T: IntoIterator; + fn with_capacity(capacity: usize) -> Self; + fn clear(&mut self); + fn with_capacity_in(capacity: usize, alloc: Self::Alloc) -> Self; +} + +#[cfg(not(feature = "allocator_api"))] +impl BitContainer for Vec { + type Block = T; + type Alloc = (); + + fn new_in(_alloc: Self::Alloc) -> Self { + Vec::new() + } + + fn slice(&self) -> &[Self::Block] { + &self[..] + } + + fn slice_mut(&mut self) -> &mut [Self::Block] { + &mut self[..] + } + + fn pop(&mut self) -> Option { + Vec::pop(self) + } + + fn drain>(&mut self, range: R) -> impl Iterator { + Vec::drain(self, range) + } + + fn capacity(&self) -> usize { + Vec::capacity(self) + } + + fn append(&mut self, other: &mut Self) { + Vec::append(self, other); + } + + fn reserve(&mut self, additional: usize) { + Vec::reserve(self, additional); + } + + fn push(&mut self, value: Self::Block) { + Vec::push(self, value); + } + + fn split_off(&mut self, at: usize) -> Self { + Vec::split_off(self, at) + } + + fn truncate(&mut self, len: usize) { + Vec::truncate(self, len); + } + + fn reserve_exact(&mut self, len: usize) { + Vec::reserve_exact(self, len); + } + + fn shrink_to_fit(&mut self) { + Vec::shrink_to_fit(self); + } + + fn extend(&mut self, iter: I) + where + I: IntoIterator, + { + Extend::extend(self, iter); + } + + fn with_capacity_in(capacity: usize, _alloc: Self::Alloc) -> Self { + Vec::with_capacity(capacity) + } + + fn with_capacity(capacity: usize) -> Self { + Vec::with_capacity(capacity) + } + + fn clear(&mut self) { + Vec::clear(self) + } +} + +#[cfg(feature = "allocator_api")] +impl BitStore for Vec +where + A: core::alloc::Allocator + Clone + Default, +{ + type Block = T; + type Alloc = A; + + fn new_in(alloc: Self::Alloc) -> Self { + Vec::new_in(alloc) + } + + fn slice(&self) -> &[Self::Block] { + &self[..] + } + + fn slice_mut(&mut self) -> &mut [Self::Block] { + &mut self[..] + } + + fn pop(&mut self) -> Option { + Vec::pop(self) + } + + fn drain>(&mut self, range: R) -> impl Iterator { + Vec::drain(self, range) + } + + fn capacity(&self) -> usize { + Vec::capacity(self) + } + + fn append(&mut self, other: &mut Self) { + Vec::append(self, other); + } + + fn reserve(&mut self, additional: usize) { + Vec::reserve(self, additional); + } + + fn push(&mut self, value: Self::Block) { + Vec::push(self, value); + } + + fn split_off(&mut self, at: usize) -> Self { + Vec::split_off(self, at) + } + + fn truncate(&mut self, len: usize) { + Vec::truncate(self, len); + } + + fn reserve_exact(&mut self, len: usize) { + Vec::reserve_exact(self, len); + } + + fn shrink_to_fit(&mut self) { + Vec::shrink_to_fit(self); + } + + fn extend(&mut self, iter: I) + where + I: IntoIterator, + { + Extend::extend(self, iter); + } + + fn with_capacity_in(capacity: usize, alloc: A) -> Self { + Vec::with_capacity_in(capacity, alloc) + } + + fn with_capacity(capacity: usize) -> Self { + Vec::with_capacity_in(capacity, A::default()) + } +} + +#[cfg(feature = "smallvec")] +impl BitContainer for smallvec::SmallVec +where + A::Item: BitBlock, +{ + type Block = A::Item; + type Alloc = (); + + fn slice(&self) -> &[Self::Block] { + &self[..] + } + + fn slice_mut(&mut self) -> &mut [Self::Block] { + &mut self[..] + } + + fn pop(&mut self) -> Option { + self.pop() + } + + fn drain>(&mut self, range: R) -> impl Iterator { + self.drain(range) + } + + fn capacity(&self) -> usize { + self.capacity() + } + + fn append(&mut self, other: &mut Self) { + self.append(other); + } + + fn reserve(&mut self, additional: usize) { + self.reserve(additional); + } + + fn push(&mut self, value: Self::Block) { + self.push(value); + } + + fn split_off(&mut self, at: usize) -> Self { + // TODO + self.to_vec().split_off(at).into() + } + + fn truncate(&mut self, len: usize) { + self.truncate(len); + } + + fn reserve_exact(&mut self, len: usize) { + self.reserve_exact(len); + } + + fn shrink_to_fit(&mut self) { + self.shrink_to_fit(); + } + + fn extend(&mut self, iter: I) + where + I: IntoIterator, + { + core::iter::Extend::extend(self, iter); + } + + fn with_capacity(capacity: usize) -> Self { + smallvec::SmallVec::with_capacity(capacity) + } + + fn clear(&mut self) { + self.clear(); + } + + fn new_in(_alloc: ()) -> Self { + smallvec::SmallVec::new() + } + + fn with_capacity_in(capacity: usize, _alloc: ()) -> Self { + smallvec::SmallVec::with_capacity(capacity) + } +} diff --git a/vec/src/into_iter.rs b/vec/src/into_iter.rs new file mode 100644 index 0000000..b4aaa96 --- /dev/null +++ b/vec/src/into_iter.rs @@ -0,0 +1,38 @@ +use crate::{local_prelude::*, BitVec}; + +pub struct IntoIter { + bit_vec: BitVec, + range: ops::Range, +} + +impl Iterator for IntoIter { + type Item = bool; + + #[inline] + fn next(&mut self) -> Option { + self.range.next().map(|i| self.bit_vec.get(i).unwrap()) + } +} + +impl DoubleEndedIterator for IntoIter { + #[inline] + fn next_back(&mut self) -> Option { + self.range.next_back().map(|i| self.bit_vec.get(i).unwrap()) + } +} + +impl ExactSizeIterator for IntoIter {} + +impl IntoIterator for BitVec { + type Item = bool; + type IntoIter = IntoIter; + + #[inline] + fn into_iter(self) -> IntoIter { + let nbits = self.nbits; + IntoIter { + bit_vec: self, + range: 0..nbits, + } + } +} diff --git a/vec/src/iter.rs b/vec/src/iter.rs new file mode 100644 index 0000000..f267954 --- /dev/null +++ b/vec/src/iter.rs @@ -0,0 +1,71 @@ +use crate::local_prelude::*; +use core::ops; + +impl BitVec { + /// Returns an iterator over the elements of the vector in order. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let bv = BitVec::from_bytes(&[0b01110100, 0b10010010]); + /// assert_eq!(bv.iter().filter(|x| *x).count(), 7); + /// ``` + #[inline] + pub fn iter(&self) -> Iter<'_, C::Block, C> { + self.ensure_invariant(); + Iter { + bit_vec: self, + range: 0..self.nbits, + } + } +} + +/// An iterator for `BitVec`. +#[derive(Clone)] +pub struct Iter<'a, B: BitBlock = u32, C: 'a + BitContainer = Vec> { + bit_vec: &'a BitVec, + range: ops::Range, +} + +impl Iterator for Iter<'_, C::Block, C> { + type Item = bool; + + #[inline] + fn next(&mut self) -> Option { + // NB: indexing is slow for extern crates when it has to go through &TRUE or &FALSE + // variables. get is more direct, and unwrap is fine since we're sure of the range. + self.range.next().map(|i| self.bit_vec.get(i).unwrap()) + } + + fn nth(&mut self, n: usize) -> Option { + // This override is used by the compiler to optimize Iterator::skip. + // Without this, the default implementation of Iterator::nth is used, which walks over + // the whole iterator up to n. + self.range.nth(n).and_then(|i| self.bit_vec.get(i)) + } + + fn size_hint(&self) -> (usize, Option) { + self.range.size_hint() + } +} + +impl DoubleEndedIterator for Iter<'_, C::Block, C> { + #[inline] + fn next_back(&mut self) -> Option { + self.range.next_back().map(|i| self.bit_vec.get(i).unwrap()) + } +} + +impl ExactSizeIterator for Iter<'_, C::Block, C> {} + +impl<'a, C: BitContainer> IntoIterator for &'a BitVec { + type Item = bool; + type IntoIter = Iter<'a, C::Block, C>; + + #[inline] + fn into_iter(self) -> Iter<'a, C::Block, C> { + self.iter() + } +} diff --git a/vec/src/lib.rs b/vec/src/lib.rs index 2b5c762..5517942 100644 --- a/vec/src/lib.rs +++ b/vec/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2023 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2026 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -82,3600 +82,67 @@ //! assert_eq!(num_primes, 1_229); //! ``` -#![doc(html_root_url = "https://docs.rs/bit-vec/0.9.0/bit_vec/")] +#![doc(html_root_url = "https://docs.rs/bit-vec/0.11.0/bit_vec/")] #![no_std] #![deny(clippy::shadow_reuse)] #![deny(clippy::shadow_same)] #![deny(clippy::shadow_unrelated)] -#![warn(clippy::multiple_inherent_impl)] +#![allow(clippy::multiple_inherent_impl)] #![warn(clippy::multiple_crate_versions)] #![warn(clippy::single_match)] #![warn(clippy::missing_safety_doc)] +// FIXME https://github.com/near/borsh/issues/159 +#![allow(clippy::multiple_crate_versions)] #[cfg(any(test, feature = "std"))] #[macro_use] extern crate std; -#[cfg(all(feature = "std", feature = "borsh"))] -use std::borrow::ToOwned; -#[cfg(all(feature = "std", feature = "miniserde"))] -use std::boxed::Box; -#[cfg(feature = "std")] -use std::rc::Rc; -#[cfg(feature = "std")] -use std::string::String; -#[cfg(feature = "std")] -use std::vec::Vec; - #[cfg(not(feature = "std"))] -#[macro_use] extern crate alloc; -#[cfg(all(not(feature = "std"), feature = "borsh"))] -use alloc::borrow::ToOwned; -#[cfg(all(not(feature = "std"), feature = "miniserde"))] -use alloc::boxed::Box; -#[cfg(not(feature = "std"))] -use alloc::rc::Rc; -#[cfg(not(feature = "std"))] -use alloc::string::String; -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; - -use core::error::Error; - -#[cfg(feature = "borsh")] -extern crate borsh; -#[cfg(feature = "miniserde")] -extern crate miniserde; -#[cfg(feature = "serde")] -extern crate serde; +mod block; +mod blocks; +mod blocks_mut; +mod container; +mod iter; +#[cfg(any(feature = "miniserde", feature = "serde", feature = "borsh"))] +mod serde; +mod smart_mut; mod util; - -use core::cell::RefCell; -use core::cmp::Ordering; -use core::fmt::Write; -use core::iter::FromIterator; -use core::ops::*; -use core::{cmp, fmt, hash, iter, mem, slice}; - -type MutBlocks<'a, B> = slice::IterMut<'a, B>; - -/// Abstracts over a pile of bits (basically unsigned primitives) -pub trait BitBlock: - Copy - + Add - + Sub - + Shl - + Shr - + Not - + BitAnd - + BitOr - + BitXor - + Rem - + BitOrAssign - + Eq - + Ord - + hash::Hash -{ - /// How many bits it has - fn bits() -> usize; - /// How many bytes it has - #[inline] - fn bytes() -> usize { - Self::bits() / 8 - } - /// Convert a byte into this type (lowest-order bits set) - fn from_byte(byte: u8) -> Self; - /// Count the number of 1's in the bitwise repr - fn count_ones(self) -> usize; - /// Count the number of 0's in the bitwise repr - fn count_zeros(self) -> usize { - Self::bits() - self.count_ones() - } - /// Get `0` - fn zero() -> Self; - /// Get `1` - fn one() -> Self; -} - -macro_rules! bit_block_impl { - ($(($t: ident, $size: expr)),*) => ($( - impl BitBlock for $t { - #[inline] - fn bits() -> usize { $size } - #[inline] - fn from_byte(byte: u8) -> Self { $t::from(byte) } - #[inline] - fn count_ones(self) -> usize { self.count_ones() as usize } - #[inline] - fn count_zeros(self) -> usize { self.count_zeros() as usize } - #[inline] - fn one() -> Self { 1 } - #[inline] - fn zero() -> Self { 0 } - } - )*) -} - -bit_block_impl! { - (u8, 8), - (u16, 16), - (u32, 32), - (u64, 64), - (usize, core::mem::size_of::() * 8) -} - -/// The bitvector type. -/// -/// # Examples -/// -/// ``` -/// use bit_vec::BitVec; -/// -/// let mut bv = BitVec::from_elem(10, false); -/// -/// // insert all primes less than 10 -/// bv.set(2, true); -/// bv.set(3, true); -/// bv.set(5, true); -/// bv.set(7, true); -/// println!("{:?}", bv); -/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count()); -/// -/// // flip all values in bitvector, producing non-primes less than 10 -/// bv.negate(); -/// println!("{:?}", bv); -/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count()); -/// -/// // reset bitvector to empty -/// bv.fill(false); -/// println!("{:?}", bv); -/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count()); -/// ``` -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize))] -#[cfg_attr(feature = "miniserde", derive(miniserde::Serialize))] -pub struct BitVec { - /// Internal representation of the bit vector - storage: Vec, - /// The number of valid bits in the internal representation - nbits: usize, -} - -#[cfg(any(feature = "serde", feature = "borsh", feature = "miniserde"))] -#[cfg_attr(feature = "serde", derive(serde::Deserialize))] -#[cfg_attr(feature = "borsh", derive(borsh::BorshDeserialize))] -#[cfg_attr(feature = "miniserde", derive(miniserde::Deserialize))] -struct UncheckedBitVec { - storage: Vec, - nbits: usize, -} - -#[cfg(feature = "serde")] -impl<'de, B: BitBlock> serde::Deserialize<'de> for BitVec -where - B: serde::Deserialize<'de>, -{ - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - use serde::de::Error; - UncheckedBitVec::::deserialize(deserializer).and_then(|unchecked| { - let result = BitVec { - storage: unchecked.storage, - nbits: unchecked.nbits, - }; - if !result.storage_len_matches_nbits() { - Err(D::Error::custom(DeserializeError::StorageLenMismatch)) - } else if !result.is_last_block_fixed() { - Err(D::Error::custom(DeserializeError::TrailingBits)) - } else { - Ok(result) - } - }) - } -} - -#[cfg(feature = "borsh")] -impl borsh::BorshDeserialize for BitVec -where - B: borsh::BorshDeserialize, -{ - fn deserialize_reader(reader: &mut R) -> borsh::io::Result { - UncheckedBitVec::::deserialize_reader(reader).and_then(|unchecked| { - let result = BitVec { - storage: unchecked.storage, - nbits: unchecked.nbits, - }; - if !result.storage_len_matches_nbits() { - Err(borsh::io::Error::other( - DeserializeError::StorageLenMismatch, - )) - } else if !result.is_last_block_fixed() { - Err(borsh::io::Error::other(DeserializeError::TrailingBits)) - } else { - Ok(result) - } - }) - } -} - -#[cfg(feature = "miniserde")] -miniserde::make_place!(Place); - -#[cfg(feature = "miniserde")] -struct BitVecBuilder<'a, B> { - storage: Option>, - nbits: Option, - out: &'a mut Option>, -} - -#[cfg(feature = "miniserde")] -impl miniserde::de::Visitor for Place> -where - B: miniserde::Deserialize, -{ - fn map(&mut self) -> miniserde::Result> { - Ok(Box::new(BitVecBuilder { - storage: None, - nbits: None, - out: &mut self.out, - })) - } -} - -#[cfg(feature = "miniserde")] -impl miniserde::de::Map for BitVecBuilder<'_, B> -where - B: miniserde::Deserialize, -{ - fn key(&mut self, k: &str) -> miniserde::Result<&mut dyn miniserde::de::Visitor> { - match k { - "storage" => Ok(miniserde::Deserialize::begin(&mut self.storage)), - "nbits" => Ok(miniserde::Deserialize::begin(&mut self.nbits)), - _ => Ok(::ignore()), - } - } - - fn finish(&mut self) -> miniserde::Result<()> { - let storage = self.storage.take().ok_or(miniserde::Error)?; - let nbits = self.nbits.take().ok_or(miniserde::Error)?; - let result = BitVec { storage, nbits }; - if !result.storage_len_matches_nbits() || !result.is_last_block_fixed() { - Err(miniserde::Error) - } else { - *self.out = Some(result); - Ok(()) - } - } -} - -#[cfg(feature = "miniserde")] -impl miniserde::Deserialize for BitVec -where - B: miniserde::Deserialize, -{ - fn begin(out: &mut Option) -> &mut dyn miniserde::de::Visitor { - Place::new(out) - } -} - -#[derive(Debug)] -pub enum DeserializeError { - StorageLenMismatch, - TrailingBits, -} - -impl core::fmt::Display for DeserializeError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.simple_description()) - } -} - -#[cfg(feature = "borsh")] -impl From for String { - fn from(value: DeserializeError) -> Self { - value.simple_description().to_owned() - } -} - -impl Error for DeserializeError {} - -impl DeserializeError { - fn simple_description(&self) -> &str { - match self { - DeserializeError::TrailingBits => "some out of bounds trailing bits are set", - DeserializeError::StorageLenMismatch => "nbits and storage length isnt same", - } - } -} - -// FIXME(Gankro): NopeNopeNopeNopeNope (wait for IndexGet to be a thing) -impl Index for BitVec { - type Output = bool; - - #[inline] - fn index(&self, i: usize) -> &bool { - if self.get(i).expect("index out of bounds") { - &true - } else { - &false - } - } -} - -/// Computes how many blocks are needed to store that many bits -fn blocks_for_bits(bits: usize) -> usize { - // If we want 17 bits, dividing by 32 will produce 0. So we add 1 to make sure we - // reserve enough. But if we want exactly a multiple of 32, this will actually allocate - // one too many. So we need to check if that's the case. We can do that by computing if - // bitwise AND by `32 - 1` is 0. But LLVM should be able to optimize the semantically - // superior modulo operator on a power of two to this. - // - // Note that we can technically avoid this branch with the expression - // `(nbits + U32_BITS - 1) / 32::BITS`, but if nbits is almost usize::MAX this will overflow. - if bits % B::bits() == 0 { - bits / B::bits() - } else { - bits / B::bits() + 1 - } -} - -/// Computes the bitmask for the final word of the vector -fn mask_for_bits(bits: usize) -> B { - // Note especially that a perfect multiple of U32_BITS should mask all 1s. - (!B::zero()) >> ((B::bits() - bits % B::bits()) % B::bits()) -} - -impl BitVec { - /// Creates an empty `BitVec`. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// let mut bv = BitVec::new(); - /// ``` - #[inline] - pub fn new() -> Self { - Default::default() - } - - /// Creates a `BitVec` that holds `nbits` elements, setting each element - /// to `bit`. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::from_elem(10, false); - /// assert_eq!(bv.len(), 10); - /// for x in bv.iter() { - /// assert_eq!(x, false); - /// } - /// ``` - #[inline] - pub fn from_elem(len: usize, bit: bool) -> Self { - BitVec::::from_elem_general(len, bit) - } - - /// Constructs a new, empty `BitVec` with the specified capacity. - /// - /// The bitvector will be able to hold at least `capacity` bits without - /// reallocating. If `capacity` is 0, it will not allocate. - /// - /// It is important to note that this function does not specify the - /// *length* of the returned bitvector, but only the *capacity*. - #[inline] - pub fn with_capacity(capacity: usize) -> Self { - BitVec::::with_capacity_general(capacity) - } - - /// Transforms a byte-vector into a `BitVec`. Each byte becomes eight bits, - /// with the most significant bits of each byte coming first. Each - /// bit becomes `true` if equal to 1 or `false` if equal to 0. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let bv = BitVec::from_bytes(&[0b10100000, 0b00010010]); - /// assert!(bv.eq_vec(&[true, false, true, false, - /// false, false, false, false, - /// false, false, false, true, - /// false, false, true, false])); - /// ``` - pub fn from_bytes(bytes: &[u8]) -> Self { - BitVec::::from_bytes_general(bytes) - } - - /// Creates a `BitVec` of the specified length where the value at each index - /// is `f(index)`. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let bv = BitVec::from_fn(5, |i| { i % 2 == 0 }); - /// assert!(bv.eq_vec(&[true, false, true, false, true])); - /// ``` - #[inline] - pub fn from_fn(len: usize, f: F) -> Self - where - F: FnMut(usize) -> bool, - { - BitVec::::from_fn_general(len, f) - } -} - -impl BitVec { - /// Creates an empty `BitVec`. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// let mut bv = BitVec::::new_general(); - /// ``` - #[inline] - pub fn new_general() -> Self { - Default::default() - } - - /// Creates a `BitVec` that holds `nbits` elements, setting each element - /// to `bit`. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::::from_elem_general(10, false); - /// assert_eq!(bv.len(), 10); - /// for x in bv.iter() { - /// assert_eq!(x, false); - /// } - /// ``` - #[inline] - pub fn from_elem_general(len: usize, bit: bool) -> Self { - let nblocks = blocks_for_bits::(len); - let mut bit_vec = BitVec { - storage: vec![if bit { !B::zero() } else { B::zero() }; nblocks], - nbits: len, - }; - bit_vec.fix_last_block(); - bit_vec - } - - /// Constructs a new, empty `BitVec` with the specified capacity. - /// - /// The bitvector will be able to hold at least `capacity` bits without - /// reallocating. If `capacity` is 0, it will not allocate. - /// - /// It is important to note that this function does not specify the - /// *length* of the returned bitvector, but only the *capacity*. - #[inline] - pub fn with_capacity_general(capacity: usize) -> Self { - BitVec { - storage: Vec::with_capacity(blocks_for_bits::(capacity)), - nbits: 0, - } - } - - /// Transforms a byte-vector into a `BitVec`. Each byte becomes eight bits, - /// with the most significant bits of each byte coming first. Each - /// bit becomes `true` if equal to 1 or `false` if equal to 0. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let bv = BitVec::::from_bytes_general(&[0b10100000, 0b00010010]); - /// assert!(bv.eq_vec(&[true, false, true, false, - /// false, false, false, false, - /// false, false, false, true, - /// false, false, true, false])); - /// ``` - pub fn from_bytes_general(bytes: &[u8]) -> Self { - let len = bytes - .len() - .checked_mul(u8::bits()) - .expect("capacity overflow"); - let mut bit_vec = BitVec::with_capacity_general(len); - let complete_words = bytes.len() / B::bytes(); - let extra_bytes = bytes.len() % B::bytes(); - - bit_vec.nbits = len; - - for i in 0..complete_words { - let mut accumulator = B::zero(); - for idx in 0..B::bytes() { - accumulator |= - B::from_byte(util::reverse_bits(bytes[i * B::bytes() + idx])) << (idx * 8) - } - bit_vec.storage.push(accumulator); - } - - if extra_bytes > 0 { - let mut last_word = B::zero(); - for (i, &byte) in bytes[complete_words * B::bytes()..].iter().enumerate() { - last_word |= B::from_byte(util::reverse_bits(byte)) << (i * 8); - } - bit_vec.storage.push(last_word); - } - - bit_vec - } - - /// Creates a `BitVec` of the specified length where the value at each index - /// is `f(index)`. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let bv = BitVec::::from_fn_general(5, |i| { i % 2 == 0 }); - /// assert!(bv.eq_vec(&[true, false, true, false, true])); - /// ``` - #[inline] - pub fn from_fn_general(len: usize, mut f: F) -> Self - where - F: FnMut(usize) -> bool, - { - let mut bit_vec = BitVec::from_elem_general(len, false); - for i in 0..len { - bit_vec.set(i, f(i)); - } - bit_vec - } - - /// Applies the given operation to the blocks of self and other, and sets - /// self to be the result. This relies on the caller not to corrupt the - /// last word. - #[inline] - fn process(&mut self, other: &BitVec, mut op: F) -> bool - where - F: FnMut(B, B) -> B, - { - assert_eq!(self.len(), other.len()); - debug_assert_eq!(self.storage.len(), other.storage.len()); - let mut changed_bits = B::zero(); - for (a, b) in self.blocks_mut().zip(other.blocks()) { - let w = op(*a, b); - changed_bits |= *a ^ w; - *a = w; - } - changed_bits != B::zero() - } - - /// Iterator over mutable refs to the underlying blocks of data. - #[inline] - fn blocks_mut(&mut self) -> MutBlocks<'_, B> { - // (2) - self.storage.iter_mut() - } - - /// Iterator over the underlying blocks of data - #[inline] - pub fn blocks(&self) -> Blocks<'_, B> { - // (2) - Blocks { - iter: self.storage.iter(), - } - } - - /// Exposes the raw block storage of this `BitVec`. - /// - /// Only really intended for `BitSet`. - #[inline] - pub fn storage(&self) -> &[B] { - &self.storage - } - - /// Exposes the raw block storage of this `BitVec`. - /// - /// # Safety - /// - /// Can break the structure's invariants despite not - /// giving real memory unsafety. Only really intended for `BitSet`. - #[inline] - pub unsafe fn storage_mut(&mut self) -> &mut Vec { - &mut self.storage - } - - /// Helper for procedures involving spare space in the last block. - #[inline] - fn last_block_with_mask(&self) -> Option<(B, B)> { - let extra_bits = self.len() % B::bits(); - if extra_bits > 0 { - let mask = (B::one() << extra_bits) - B::one(); - let storage_len = self.storage.len(); - Some((self.storage[storage_len - 1], mask)) - } else { - None - } - } - - /// Helper for procedures involving spare space in the last block. - #[inline] - fn last_block_mut_with_mask(&mut self) -> Option<(&mut B, B)> { - let extra_bits = self.len() % B::bits(); - if extra_bits > 0 { - let mask = (B::one() << extra_bits) - B::one(); - let storage_len = self.storage.len(); - Some((&mut self.storage[storage_len - 1], mask)) - } else { - None - } - } - - /// An operation might screw up the unused bits in the last block of the - /// `BitVec`. As per (3), it's assumed to be all 0s. This method fixes it up. - fn fix_last_block(&mut self) { - if let Some((last_block, used_bits)) = self.last_block_mut_with_mask() { - *last_block = *last_block & used_bits; - } - } - - /// Operations such as change detection for xnor, nor and nand are easiest - /// to implement when unused bits are all set to 1s. - fn fix_last_block_with_ones(&mut self) { - if let Some((last_block, used_bits)) = self.last_block_mut_with_mask() { - *last_block |= !used_bits; - } - } - - /// Check whether last block's invariant is fine. - fn is_last_block_fixed(&self) -> bool { - if let Some((last_block, used_bits)) = self.last_block_with_mask() { - last_block & !used_bits == B::zero() - } else { - true - } - } - - /// Checks whether our `nbits` fits within our storage. - fn storage_len_matches_nbits(&self) -> bool { - self.storage.len() == blocks_for_bits::(self.nbits) - } - - /// Ensure the invariant for the last block. - /// - /// An operation might screw up the unused bits in the last block of the - /// `BitVec`. - /// - /// This method fails in case the last block is not fixed. The check - /// is skipped outside testing. - #[inline] - fn ensure_invariant(&self) { - if cfg!(test) { - debug_assert!(self.storage_len_matches_nbits()); - debug_assert!(self.is_last_block_fixed()); - } - } - - /// Retrieves the value at index `i`, or `None` if the index is out of bounds. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let bv = BitVec::from_bytes(&[0b01100000]); - /// assert_eq!(bv.get(0), Some(false)); - /// assert_eq!(bv.get(1), Some(true)); - /// assert_eq!(bv.get(100), None); - /// - /// // Can also use array indexing - /// assert_eq!(bv[1], true); - /// ``` - #[inline] - pub fn get(&self, i: usize) -> Option { - self.ensure_invariant(); - if i >= self.nbits { - return None; - } - let w = i / B::bits(); - let b = i % B::bits(); - self.storage - .get(w) - .map(|&block| (block & (B::one() << b)) != B::zero()) - } - - /// Retrieves the value at index `i`, without doing bounds checking. - /// - /// For a safe alternative, see `get`. - /// - /// # Safety - /// - /// Calling this method with an out-of-bounds index is undefined behavior - /// even if the resulting reference is not used. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let bv = BitVec::from_bytes(&[0b01100000]); - /// // Safety: - /// // We access the structure with in-bounds indices (those smaller - /// // than 32). - /// unsafe { - /// assert_eq!(bv.get_unchecked(0), false); - /// assert_eq!(bv.get_unchecked(1), true); - /// } - /// ``` - #[inline] - pub unsafe fn get_unchecked(&self, i: usize) -> bool { - self.ensure_invariant(); - let w = i / B::bits(); - let b = i % B::bits(); - let block = *self.storage.get_unchecked(w); - block & (B::one() << b) != B::zero() - } - - /// Retrieves a smart pointer to the value at index `i`, or `None` if the index is out of bounds. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::from_bytes(&[0b01100000]); - /// *bv.get_mut(0).unwrap() = true; - /// *bv.get_mut(1).unwrap() = false; - /// assert!(bv.get_mut(100).is_none()); - /// assert_eq!(bv, BitVec::from_bytes(&[0b10100000])); - /// ``` - #[inline] - pub fn get_mut(&mut self, index: usize) -> Option> { - self.get(index).map(move |value| MutBorrowedBit { - vec: Rc::new(RefCell::new(self)), - index, - #[cfg(debug_assertions)] - old_value: value, - new_value: value, - }) - } - - /// Retrieves a smart pointer to the value at index `i`, without doing bounds checking. - /// - /// # Safety - /// - /// Calling this method with out-of-bounds `index` may cause undefined behavior even when - /// the result is not used. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::from_bytes(&[0b01100000]); - /// unsafe { - /// *bv.get_unchecked_mut(0) = true; - /// *bv.get_unchecked_mut(1) = false; - /// } - /// assert_eq!(bv, BitVec::from_bytes(&[0b10100000])); - /// ``` - #[inline] - pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> MutBorrowedBit<'_, B> { - let value = self.get_unchecked(index); - MutBorrowedBit { - #[cfg(debug_assertions)] - old_value: value, - new_value: value, - vec: Rc::new(RefCell::new(self)), - index, - } - } - - /// Sets the value of a bit at an index `i`. - /// - /// # Panics - /// - /// Panics if `i` is out of bounds. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::from_elem(5, false); - /// bv.set(3, true); - /// assert_eq!(bv[3], true); - /// ``` - #[inline] - pub fn set(&mut self, i: usize, x: bool) { - self.ensure_invariant(); - assert!( - i < self.nbits, - "index out of bounds: {:?} >= {:?}", - i, - self.nbits - ); - let w = i / B::bits(); - let b = i % B::bits(); - let flag = B::one() << b; - let val = if x { - self.storage[w] | flag - } else { - self.storage[w] & !flag - }; - self.storage[w] = val; - } - - /// Sets all bits to 1. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let before = 0b01100000; - /// let after = 0b11111111; - /// - /// let mut bv = BitVec::from_bytes(&[before]); - /// bv.set_all(); - /// assert_eq!(bv, BitVec::from_bytes(&[after])); - /// ``` - #[inline] - #[deprecated(since = "0.9.0", note = "please use `.fill(true)` instead")] - pub fn set_all(&mut self) { - self.ensure_invariant(); - for w in &mut self.storage { - *w = !B::zero(); - } - self.fix_last_block(); - } - - /// Flips all bits. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let before = 0b01100000; - /// let after = 0b10011111; - /// - /// let mut bv = BitVec::from_bytes(&[before]); - /// bv.negate(); - /// assert_eq!(bv, BitVec::from_bytes(&[after])); - /// ``` - #[inline] - pub fn negate(&mut self) { - self.ensure_invariant(); - for w in &mut self.storage { - *w = !*w; - } - self.fix_last_block(); - } - - /// Calculates the union of two bitvectors. This acts like the bitwise `or` - /// function. - /// - /// Sets `self` to the union of `self` and `other`. Both bitvectors must be - /// the same length. Returns `true` if `self` changed. - /// - /// # Panics - /// - /// Panics if the bitvectors are of different lengths. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let a = 0b01100100; - /// let b = 0b01011010; - /// let res = 0b01111110; - /// - /// let mut a = BitVec::from_bytes(&[a]); - /// let b = BitVec::from_bytes(&[b]); - /// - /// assert!(a.union(&b)); - /// assert_eq!(a, BitVec::from_bytes(&[res])); - /// ``` - #[deprecated(since = "0.7.0", note = "Please use the 'or' function instead")] - #[inline] - pub fn union(&mut self, other: &Self) -> bool { - self.or(other) - } - - /// Calculates the intersection of two bitvectors. This acts like the - /// bitwise `and` function. - /// - /// Sets `self` to the intersection of `self` and `other`. Both bitvectors - /// must be the same length. Returns `true` if `self` changed. - /// - /// # Panics - /// - /// Panics if the bitvectors are of different lengths. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let a = 0b01100100; - /// let b = 0b01011010; - /// let res = 0b01000000; - /// - /// let mut a = BitVec::from_bytes(&[a]); - /// let b = BitVec::from_bytes(&[b]); - /// - /// assert!(a.intersect(&b)); - /// assert_eq!(a, BitVec::from_bytes(&[res])); - /// ``` - #[deprecated(since = "0.7.0", note = "Please use the 'and' function instead")] - #[inline] - pub fn intersect(&mut self, other: &Self) -> bool { - self.and(other) - } - - /// Calculates the bitwise `or` of two bitvectors. - /// - /// Sets `self` to the union of `self` and `other`. Both bitvectors must be - /// the same length. Returns `true` if `self` changed. - /// - /// # Panics - /// - /// Panics if the bitvectors are of different lengths. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let a = 0b01100100; - /// let b = 0b01011010; - /// let res = 0b01111110; - /// - /// let mut a = BitVec::from_bytes(&[a]); - /// let b = BitVec::from_bytes(&[b]); - /// - /// assert!(a.or(&b)); - /// assert_eq!(a, BitVec::from_bytes(&[res])); - /// ``` - #[inline] - pub fn or(&mut self, other: &Self) -> bool { - self.ensure_invariant(); - debug_assert!(other.is_last_block_fixed()); - self.process(other, |w1, w2| w1 | w2) - } - - /// Calculates the bitwise `and` of two bitvectors. - /// - /// Sets `self` to the intersection of `self` and `other`. Both bitvectors - /// must be the same length. Returns `true` if `self` changed. - /// - /// # Panics - /// - /// Panics if the bitvectors are of different lengths. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let a = 0b01100100; - /// let b = 0b01011010; - /// let res = 0b01000000; - /// - /// let mut a = BitVec::from_bytes(&[a]); - /// let b = BitVec::from_bytes(&[b]); - /// - /// assert!(a.and(&b)); - /// assert_eq!(a, BitVec::from_bytes(&[res])); - /// ``` - #[inline] - pub fn and(&mut self, other: &Self) -> bool { - self.ensure_invariant(); - debug_assert!(other.is_last_block_fixed()); - self.process(other, |w1, w2| w1 & w2) - } - - /// Calculates the difference between two bitvectors. - /// - /// Sets each element of `self` to the value of that element minus the - /// element of `other` at the same index. Both bitvectors must be the same - /// length. Returns `true` if `self` changed. - /// - /// # Panics - /// - /// Panics if the bitvectors are of different length. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let a = 0b01100100; - /// let b = 0b01011010; - /// let a_b = 0b00100100; // a - b - /// let b_a = 0b00011010; // b - a - /// - /// let mut bva = BitVec::from_bytes(&[a]); - /// let bvb = BitVec::from_bytes(&[b]); - /// - /// assert!(bva.difference(&bvb)); - /// assert_eq!(bva, BitVec::from_bytes(&[a_b])); - /// - /// let bva = BitVec::from_bytes(&[a]); - /// let mut bvb = BitVec::from_bytes(&[b]); - /// - /// assert!(bvb.difference(&bva)); - /// assert_eq!(bvb, BitVec::from_bytes(&[b_a])); - /// ``` - #[inline] - pub fn difference(&mut self, other: &Self) -> bool { - self.ensure_invariant(); - debug_assert!(other.is_last_block_fixed()); - self.process(other, |w1, w2| w1 & !w2) - } - - /// Calculates the xor of two bitvectors. - /// - /// Sets `self` to the xor of `self` and `other`. Both bitvectors must be - /// the same length. Returns `true` if `self` changed. - /// - /// # Panics - /// - /// Panics if the bitvectors are of different length. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let a = 0b01100110; - /// let b = 0b01010100; - /// let res = 0b00110010; - /// - /// let mut a = BitVec::from_bytes(&[a]); - /// let b = BitVec::from_bytes(&[b]); - /// - /// assert!(a.xor(&b)); - /// assert_eq!(a, BitVec::from_bytes(&[res])); - /// ``` - #[inline] - pub fn xor(&mut self, other: &Self) -> bool { - self.ensure_invariant(); - debug_assert!(other.is_last_block_fixed()); - self.process(other, |w1, w2| w1 ^ w2) - } - - /// Calculates the nand of two bitvectors. - /// - /// Sets `self` to the nand of `self` and `other`. Both bitvectors must be - /// the same length. Returns `true` if `self` changed. - /// - /// # Panics - /// - /// Panics if the bitvectors are of different length. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let a = 0b01100110; - /// let b = 0b01010100; - /// let res = 0b10111011; - /// - /// let mut a = BitVec::from_bytes(&[a]); - /// let b = BitVec::from_bytes(&[b]); - /// - /// assert!(a.nand(&b)); - /// assert_eq!(a, BitVec::from_bytes(&[res])); - /// ``` - #[inline] - pub fn nand(&mut self, other: &Self) -> bool { - self.ensure_invariant(); - debug_assert!(other.is_last_block_fixed()); - self.fix_last_block_with_ones(); - let result = self.process(other, |w1, w2| !(w1 & w2)); - self.fix_last_block(); - result - } - - /// Calculates the nor of two bitvectors. - /// - /// Sets `self` to the nor of `self` and `other`. Both bitvectors must be - /// the same length. Returns `true` if `self` changed. - /// - /// # Panics - /// - /// Panics if the bitvectors are of different length. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let a = 0b01100110; - /// let b = 0b01010100; - /// let res = 0b10001001; - /// - /// let mut a = BitVec::from_bytes(&[a]); - /// let b = BitVec::from_bytes(&[b]); - /// - /// assert!(a.nor(&b)); - /// assert_eq!(a, BitVec::from_bytes(&[res])); - /// ``` - #[inline] - pub fn nor(&mut self, other: &Self) -> bool { - self.ensure_invariant(); - debug_assert!(other.is_last_block_fixed()); - self.fix_last_block_with_ones(); - let result = self.process(other, |w1, w2| !(w1 | w2)); - self.fix_last_block(); - result - } - - /// Calculates the xnor of two bitvectors. - /// - /// Sets `self` to the xnor of `self` and `other`. Both bitvectors must be - /// the same length. Returns `true` if `self` changed. - /// - /// # Panics - /// - /// Panics if the bitvectors are of different length. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let a = 0b01100110; - /// let b = 0b01010100; - /// let res = 0b11001101; - /// - /// let mut a = BitVec::from_bytes(&[a]); - /// let b = BitVec::from_bytes(&[b]); - /// - /// assert!(a.xnor(&b)); - /// assert_eq!(a, BitVec::from_bytes(&[res])); - /// ``` - #[inline] - pub fn xnor(&mut self, other: &Self) -> bool { - self.ensure_invariant(); - debug_assert!(other.is_last_block_fixed()); - self.fix_last_block_with_ones(); - let result = self.process(other, |w1, w2| !(w1 ^ w2)); - self.fix_last_block(); - result - } - - /// Returns `true` if all bits are 1. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::from_elem(5, true); - /// assert_eq!(bv.all(), true); - /// - /// bv.set(1, false); - /// assert_eq!(bv.all(), false); - /// ``` - #[inline] - pub fn all(&self) -> bool { - self.ensure_invariant(); - let mut last_word = !B::zero(); - // Check that every block but the last is all-ones... - self.blocks().all(|elem| { - let tmp = last_word; - last_word = elem; - tmp == !B::zero() - // and then check the last one has enough ones - }) && (last_word == mask_for_bits(self.nbits)) - } - - /// Returns the number of ones in the binary representation. - /// - /// Also known as the - /// [Hamming weight](https://en.wikipedia.org/wiki/Hamming_weight). - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::from_elem(100, true); - /// assert_eq!(bv.count_ones(), 100); - /// - /// bv.set(50, false); - /// assert_eq!(bv.count_ones(), 99); - /// ``` - #[inline] - pub fn count_ones(&self) -> u64 { - self.ensure_invariant(); - // Add the number of ones of each block. - self.blocks().map(|elem| elem.count_ones() as u64).sum() - } - - /// Returns the number of zeros in the binary representation. - /// - /// Also known as the opposite of - /// [Hamming weight](https://en.wikipedia.org/wiki/Hamming_weight). - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::from_elem(100, false); - /// assert_eq!(bv.count_zeros(), 100); - /// - /// bv.set(50, true); - /// assert_eq!(bv.count_zeros(), 99); - /// ``` - #[inline] - pub fn count_zeros(&self) -> u64 { - self.ensure_invariant(); - // Add the number of zeros of each block. - let extra_zeros = (B::bits() - (self.len() % B::bits())) % B::bits(); - self.blocks() - .map(|elem| elem.count_zeros() as u64) - .sum::() - - extra_zeros as u64 - } - - /// Returns an iterator over the elements of the vector in order. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let bv = BitVec::from_bytes(&[0b01110100, 0b10010010]); - /// assert_eq!(bv.iter().filter(|x| *x).count(), 7); - /// ``` - #[inline] - pub fn iter(&self) -> Iter<'_, B> { - self.ensure_invariant(); - Iter { - bit_vec: self, - range: 0..self.nbits, - } - } - - /// Returns an iterator over mutable smart pointers to the elements of the vector in order. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut a = BitVec::from_elem(8, false); - /// a.iter_mut().enumerate().for_each(|(index, mut bit)| { - /// *bit = if index % 2 == 1 { true } else { false }; - /// }); - /// assert!(a.eq_vec(&[ - /// false, true, false, true, false, true, false, true - /// ])); - /// ``` - #[inline] - pub fn iter_mut(&mut self) -> IterMut<'_, B> { - self.ensure_invariant(); - let nbits = self.nbits; - IterMut { - vec: Rc::new(RefCell::new(self)), - range: 0..nbits, - } - } - - /// Moves all bits from `other` into `Self`, leaving `other` empty. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut a = BitVec::from_bytes(&[0b10000000]); - /// let mut b = BitVec::from_bytes(&[0b01100001]); - /// - /// a.append(&mut b); - /// - /// assert_eq!(a.len(), 16); - /// assert_eq!(b.len(), 0); - /// assert!(a.eq_vec(&[true, false, false, false, false, false, false, false, - /// false, true, true, false, false, false, false, true])); - /// ``` - pub fn append(&mut self, other: &mut Self) { - self.ensure_invariant(); - debug_assert!(other.is_last_block_fixed()); - - let b = self.len() % B::bits(); - let o = other.len() % B::bits(); - let will_overflow = (b + o > B::bits()) || (o == 0 && b != 0); - - self.nbits += other.len(); - other.nbits = 0; - - if b == 0 { - self.storage.append(&mut other.storage); - } else { - self.storage.reserve(other.storage.len()); - - for block in other.storage.drain(..) { - { - let last = self.storage.last_mut().unwrap(); - *last |= block << b; - } - self.storage.push(block >> (B::bits() - b)); - } - - // Remove additional block if the last shift did not overflow - if !will_overflow { - self.storage.pop(); - } - } - } - - /// Splits the `BitVec` into two at the given bit, - /// retaining the first half in-place and returning the second one. - /// - /// # Panics - /// - /// Panics if `at` is out of bounds. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// let mut a = BitVec::new(); - /// a.push(true); - /// a.push(false); - /// a.push(false); - /// a.push(true); - /// - /// let b = a.split_off(2); - /// - /// assert_eq!(a.len(), 2); - /// assert_eq!(b.len(), 2); - /// assert!(a.eq_vec(&[true, false])); - /// assert!(b.eq_vec(&[false, true])); - /// ``` - pub fn split_off(&mut self, at: usize) -> Self { - self.ensure_invariant(); - assert!(at <= self.len(), "`at` out of bounds"); - - let mut other = BitVec::::default(); - - if at == 0 { - mem::swap(self, &mut other); - return other; - } else if at == self.len() { - return other; - } - - let w = at / B::bits(); - let b = at % B::bits(); - other.nbits = self.nbits - at; - self.nbits = at; - if b == 0 { - // Split at block boundary - other.storage = self.storage.split_off(w); - } else { - other.storage.reserve(self.storage.len() - w); - - { - let mut iter = self.storage[w..].iter(); - let mut last = *iter.next().unwrap(); - for &cur in iter { - other.storage.push((last >> b) | (cur << (B::bits() - b))); - last = cur; - } - other.storage.push(last >> b); - } - - self.storage.truncate(w + 1); - self.fix_last_block(); - } - - other - } - - /// Returns `true` if all bits are 0. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::from_elem(10, false); - /// assert_eq!(bv.none(), true); - /// - /// bv.set(3, true); - /// assert_eq!(bv.none(), false); - /// ``` - #[inline] - pub fn none(&self) -> bool { - self.blocks().all(|w| w == B::zero()) - } - - /// Returns `true` if any bit is 1. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::from_elem(10, false); - /// assert_eq!(bv.any(), false); - /// - /// bv.set(3, true); - /// assert_eq!(bv.any(), true); - /// ``` - #[inline] - pub fn any(&self) -> bool { - !self.none() - } - - /// Organises the bits into bytes, such that the first bit in the - /// `BitVec` becomes the high-order bit of the first byte. If the - /// size of the `BitVec` is not a multiple of eight then trailing bits - /// will be filled-in with `false`. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::from_elem(3, true); - /// bv.set(1, false); - /// - /// assert_eq!(bv.to_bytes(), [0b10100000]); - /// - /// let mut bv = BitVec::from_elem(9, false); - /// bv.set(2, true); - /// bv.set(8, true); - /// - /// assert_eq!(bv.to_bytes(), [0b00100000, 0b10000000]); - /// ``` - pub fn to_bytes(&self) -> Vec { - self.ensure_invariant(); - - let len = self.nbits / 8 + if self.nbits % 8 == 0 { 0 } else { 1 }; - let mut result = Vec::with_capacity(len); - - for byte_idx in 0..len { - let mut byte = 0u8; - for bit_idx in 0..8 { - let offset = byte_idx * 8 + bit_idx; - if offset < self.nbits && self[offset] { - byte |= 1 << bit_idx; - } - } - result.push(util::reverse_bits(byte)); - } - - result - } - - /// Compares a `BitVec` to a slice of `bool`s. - /// Both the `BitVec` and slice must have the same length. - /// - /// # Panics - /// - /// Panics if the `BitVec` and slice are of different length. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let bv = BitVec::from_bytes(&[0b10100000]); - /// - /// assert!(bv.eq_vec(&[true, false, true, false, - /// false, false, false, false])); - /// ``` - #[inline] - pub fn eq_vec(&self, v: &[bool]) -> bool { - assert_eq!(self.nbits, v.len()); - self.iter().zip(v.iter().cloned()).all(|(b1, b2)| b1 == b2) - } - - /// Shortens a `BitVec`, dropping excess elements. - /// - /// If `len` is greater than the vector's current length, this has no - /// effect. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::from_bytes(&[0b01001011]); - /// bv.truncate(2); - /// assert!(bv.eq_vec(&[false, true])); - /// ``` - #[inline] - pub fn truncate(&mut self, len: usize) { - self.ensure_invariant(); - if len < self.len() { - self.nbits = len; - // This fixes (2). - self.storage.truncate(blocks_for_bits::(len)); - self.fix_last_block(); - } - } - - /// Reserves capacity for at least `additional` more bits to be inserted in the given - /// `BitVec`. The collection may reserve more space to avoid frequent reallocations. - /// - /// # Panics - /// - /// Panics if the new capacity overflows `usize`. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::from_elem(3, false); - /// bv.reserve(10); - /// assert_eq!(bv.len(), 3); - /// assert!(bv.capacity() >= 13); - /// ``` - #[inline] - pub fn reserve(&mut self, additional: usize) { - let desired_cap = self - .len() - .checked_add(additional) - .expect("capacity overflow"); - let storage_len = self.storage.len(); - if desired_cap > self.capacity() { - self.storage - .reserve(blocks_for_bits::(desired_cap) - storage_len); - } - } - - /// Reserves the minimum capacity for exactly `additional` more bits to be inserted in the - /// given `BitVec`. Does nothing if the capacity is already sufficient. - /// - /// Note that the allocator may give the collection more space than it requests. Therefore - /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future - /// insertions are expected. - /// - /// # Panics - /// - /// Panics if the new capacity overflows `usize`. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::from_elem(3, false); - /// bv.reserve(10); - /// assert_eq!(bv.len(), 3); - /// assert!(bv.capacity() >= 13); - /// ``` - #[inline] - pub fn reserve_exact(&mut self, additional: usize) { - let desired_cap = self - .len() - .checked_add(additional) - .expect("capacity overflow"); - let storage_len = self.storage.len(); - if desired_cap > self.capacity() { - self.storage - .reserve_exact(blocks_for_bits::(desired_cap) - storage_len); - } - } - - /// Returns the capacity in bits for this bit vector. Inserting any - /// element less than this amount will not trigger a resizing. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::new(); - /// bv.reserve(10); - /// assert!(bv.capacity() >= 10); - /// ``` - #[inline] - pub fn capacity(&self) -> usize { - self.storage.capacity().saturating_mul(B::bits()) - } - - /// Grows the `BitVec` in-place, adding `n` copies of `value` to the `BitVec`. - /// - /// # Panics - /// - /// Panics if the new len overflows a `usize`. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::from_bytes(&[0b01001011]); - /// bv.grow(2, true); - /// assert_eq!(bv.len(), 10); - /// assert_eq!(bv.to_bytes(), [0b01001011, 0b11000000]); - /// ``` - pub fn grow(&mut self, n: usize, value: bool) { - self.ensure_invariant(); - - // Note: we just bulk set all the bits in the last word in this fn in multiple places - // which is technically wrong if not all of these bits are to be used. However, at the end - // of this fn we call `fix_last_block` at the end of this fn, which should fix this. - - let new_nbits = self.nbits.checked_add(n).expect("capacity overflow"); - let new_nblocks = blocks_for_bits::(new_nbits); - let full_value = if value { !B::zero() } else { B::zero() }; - - // Correct the old tail word, setting or clearing formerly unused bits - let num_cur_blocks = blocks_for_bits::(self.nbits); - if self.nbits % B::bits() > 0 { - let mask = mask_for_bits::(self.nbits); - if value { - let block = &mut self.storage[num_cur_blocks - 1]; - *block |= !mask; - } else { - // Extra bits are already zero by invariant. - } - } - - // Fill in words after the old tail word - let stop_idx = cmp::min(self.storage.len(), new_nblocks); - for idx in num_cur_blocks..stop_idx { - self.storage[idx] = full_value; - } - - // Allocate new words, if needed - if new_nblocks > self.storage.len() { - let to_add = new_nblocks - self.storage.len(); - self.storage.extend(iter::repeat_n(full_value, to_add)); - } - - // Adjust internal bit count - self.nbits = new_nbits; - - self.fix_last_block(); - } - - /// Removes the last bit from the `BitVec`, and returns it. Returns `None` if the `BitVec` is empty. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::from_bytes(&[0b01001001]); - /// assert_eq!(bv.pop(), Some(true)); - /// assert_eq!(bv.pop(), Some(false)); - /// assert_eq!(bv.len(), 6); - /// ``` - #[inline] - pub fn pop(&mut self) -> Option { - self.ensure_invariant(); - - if self.is_empty() { - None - } else { - let i = self.nbits - 1; - let ret = self[i]; - // (3) - self.set(i, false); - self.nbits = i; - if self.nbits % B::bits() == 0 { - // (2) - self.storage.pop(); - } - Some(ret) - } - } - - /// Pushes a `bool` onto the end. - /// - /// # Examples - /// - /// ``` - /// use bit_vec::BitVec; - /// - /// let mut bv = BitVec::new(); - /// bv.push(true); - /// bv.push(false); - /// assert!(bv.eq_vec(&[true, false])); - /// ``` - #[inline] - pub fn push(&mut self, elem: bool) { - if self.nbits % B::bits() == 0 { - self.storage.push(B::zero()); - } - let insert_pos = self.nbits; - self.nbits = self.nbits.checked_add(1).expect("Capacity overflow"); - self.set(insert_pos, elem); - } - - /// Returns the total number of bits in this vector - #[inline] - pub fn len(&self) -> usize { - self.nbits - } - - /// Sets the number of bits that this `BitVec` considers initialized. - /// - /// # Safety - /// - /// Almost certainly can cause bad stuff. Only really intended for `BitSet`. - #[inline] - pub unsafe fn set_len(&mut self, len: usize) { - self.nbits = len; - } - - /// Returns true if there are no bits in this vector - #[inline] - pub fn is_empty(&self) -> bool { - self.len() == 0 - } - - /// Clears all bits in this vector. - #[inline] - #[deprecated(since = "0.9.0", note = "please use `.fill(false)` instead")] - pub fn clear(&mut self) { - self.ensure_invariant(); - for w in &mut self.storage { - *w = B::zero(); - } - } - - /// Assigns all bits in this vector to the given boolean value. - /// - /// # Invariants - /// - /// - After a call to `.fill(true)`, the result of [`all`] is `true`. - /// - After a call to `.fill(false)`, the result of [`none`] is `true`. - /// - /// [`all`]: Self::all - /// [`none`]: Self::none - #[inline] - pub fn fill(&mut self, bit: bool) { - self.ensure_invariant(); - let block = if bit { !B::zero() } else { B::zero() }; - for w in &mut self.storage { - *w = block; - } - if bit { - self.fix_last_block(); - } - } - - /// Shrinks the capacity of the underlying storage as much as - /// possible. - /// - /// It will drop down as close as possible to the length but the - /// allocator may still inform the underlying storage that there - /// is space for a few more elements/bits. - pub fn shrink_to_fit(&mut self) { - self.storage.shrink_to_fit(); - } - - /// Inserts a given bit at index `at`, shifting all bits after by one - /// - /// # Panics - /// Panics if `at` is out of bounds for `BitVec`'s length (that is, if `at > BitVec::len()`) - /// - /// # Examples - ///``` - /// use bit_vec::BitVec; - /// - /// let mut b = BitVec::new(); - /// - /// b.push(true); - /// b.push(true); - /// b.insert(1, false); - /// - /// assert!(b.eq_vec(&[true, false, true])); - ///``` - /// - /// # Time complexity - /// Takes O([`len`]) time. All items after the insertion index must be - /// shifted to the right. In the worst case, all elements are shifted when - /// the insertion index is 0. - /// - /// [`len`]: Self::len - pub fn insert(&mut self, at: usize, bit: bool) { - assert!( - at <= self.nbits, - "insertion index (is {at}) should be <= len (is {nbits})", - nbits = self.nbits - ); - self.ensure_invariant(); - - let last_block_bits = self.nbits % B::bits(); - let block_at = at / B::bits(); // needed block - let bit_at = at % B::bits(); // index within the block - - if last_block_bits == 0 { - self.storage.push(B::zero()); - } - - self.nbits += 1; - - let mut carry = self.storage[block_at] >> (B::bits() - 1); - let lsbits_mask = (B::one() << bit_at) - B::one(); - let set_bit = if bit { B::one() } else { B::zero() } << bit_at; - self.storage[block_at] = (self.storage[block_at] & lsbits_mask) - | ((self.storage[block_at] & !lsbits_mask) << 1) - | set_bit; - - for block_ref in &mut self.storage[block_at + 1..] { - let curr_carry = *block_ref >> (B::bits() - 1); - *block_ref = *block_ref << 1 | carry; - carry = curr_carry; - } - } - - /// Remove a bit at index `at`, shifting all bits after by one. - /// - /// # Panics - /// Panics if `at` is out of bounds for `BitVec`'s length (that is, if `at >= BitVec::len()`) - /// - /// # Examples - ///``` - /// use bit_vec::BitVec; - /// - /// let mut b = BitVec::new(); - /// - /// b.push(true); - /// b.push(false); - /// b.push(false); - /// b.push(true); - /// assert!(!b.remove(1)); - /// - /// assert!(b.eq_vec(&[true, false, true])); - ///``` - /// - /// # Time complexity - /// Takes O([`len`]) time. All items after the removal index must be - /// shifted to the left. In the worst case, all elements are shifted when - /// the removal index is 0. - /// - /// [`len`]: Self::len - pub fn remove(&mut self, at: usize) -> bool { - assert!( - at < self.nbits, - "removal index (is {at}) should be < len (is {nbits})", - nbits = self.nbits - ); - self.ensure_invariant(); - - self.nbits -= 1; - - let last_block_bits = self.nbits % B::bits(); - let block_at = at / B::bits(); // needed block - let bit_at = at % B::bits(); // index within the block - - let lsbits_mask = (B::one() << bit_at) - B::one(); - - let mut carry = B::zero(); - - for block_ref in self.storage[block_at + 1..].iter_mut().rev() { - let curr_carry = *block_ref & B::one(); - *block_ref = *block_ref >> 1 | (carry << (B::bits() - 1)); - carry = curr_carry; - } - - let result = (self.storage[block_at] >> bit_at) & B::one() == B::one(); - - self.storage[block_at] = (self.storage[block_at] & lsbits_mask) - | ((self.storage[block_at] & (!lsbits_mask << 1)) >> 1) - | carry << (B::bits() - 1); - - if last_block_bits == 0 { - self.storage.pop(); - } - - result - } - - /// Removes all bits in this vector. - /// - /// Note: this method is not named [`clear`] to avoid confusion whenever [`.fill(false)`] - /// is needed. - /// - /// [`clear`]: Self::clear - /// [`.fill(false)`]: Self::fill - pub fn remove_all(&mut self) { - self.storage.clear(); - self.nbits = 0; - } - - /// Appends an element if there is sufficient spare capacity, otherwise an error is returned - /// with the element. - /// - /// Unlike [`push`] this method will not reallocate when there's insufficient capacity. - /// The caller should use [`reserve`] to ensure that there is enough capacity. - /// - /// [`push`]: Self::push - /// [`reserve`]: Self::reserve - /// - /// # Examples - /// ``` - /// use bit_vec::BitVec; - /// - /// let initial_capacity = 64; - /// let mut bitvec = BitVec::with_capacity(64); - /// - /// for _ in 0..initial_capacity - 1 { - /// bitvec.push(false); - /// } - /// - /// assert_eq!(bitvec.len(), initial_capacity - 1); // there is space for only 1 bit - /// - /// assert_eq!(bitvec.push_within_capacity(true), Ok(())); // Successfully push a bit - /// assert_eq!(bitvec.len(), initial_capacity); // So we can't push within capacity anymore - /// - /// assert_eq!(bitvec.push_within_capacity(true), Err(true)); - /// assert_eq!(bitvec.len(), initial_capacity); - /// assert_eq!(bitvec.capacity(), initial_capacity); - /// ``` - /// - /// # Time Complexity - /// Takes *O(1)* time. - pub fn push_within_capacity(&mut self, bit: bool) -> Result<(), bool> { - let len = self.len(); - - if len == self.capacity() { - return Err(bit); - } - - let bits = B::bits(); - - if len % bits == 0 { - self.storage.push(B::zero()); - } - - let block_at = len / bits; - let bit_at = len % bits; - let flag = if bit { B::one() << bit_at } else { B::zero() }; - - self.nbits += 1; - - self.storage[block_at] |= flag; // set the bit - - self.ensure_invariant(); - - Ok(()) - } -} - -impl Default for BitVec { - #[inline] - fn default() -> Self { - BitVec { - storage: Vec::new(), - nbits: 0, - } - } -} - -impl FromIterator for BitVec { - #[inline] - fn from_iter>(iter: I) -> Self { - let mut ret: Self = Default::default(); - ret.extend(iter); - ret - } -} - -impl Extend for BitVec { - #[inline] - fn extend>(&mut self, iterable: I) { - self.ensure_invariant(); - let iterator = iterable.into_iter(); - let (min, _) = iterator.size_hint(); - self.reserve(min); - for element in iterator { - self.push(element) - } - } -} - -impl Clone for BitVec { - #[inline] - fn clone(&self) -> Self { - self.ensure_invariant(); - BitVec { - storage: self.storage.clone(), - nbits: self.nbits, - } - } - - #[inline] - fn clone_from(&mut self, source: &Self) { - debug_assert!(source.is_last_block_fixed()); - self.nbits = source.nbits; - self.storage.clone_from(&source.storage); - } -} - -impl PartialOrd for BitVec { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for BitVec { - #[inline] - fn cmp(&self, other: &Self) -> Ordering { - self.ensure_invariant(); - debug_assert!(other.is_last_block_fixed()); - let mut a = self.iter(); - let mut b = other.iter(); - loop { - match (a.next(), b.next()) { - (Some(x), Some(y)) => match x.cmp(&y) { - Ordering::Equal => {} - otherwise => return otherwise, - }, - (None, None) => return Ordering::Equal, - (None, _) => return Ordering::Less, - (_, None) => return Ordering::Greater, - } - } - } -} - -impl fmt::Display for BitVec { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - self.ensure_invariant(); - for bit in self { - fmt.write_char(if bit { '1' } else { '0' })?; - } - Ok(()) - } -} - -impl fmt::Debug for BitVec { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - self.ensure_invariant(); - let mut storage = String::with_capacity(self.len() + self.len() / B::bits()); - for (i, bit) in self.iter().enumerate() { - if i != 0 && i % B::bits() == 0 { - storage.push(' '); - } - storage.push(if bit { '1' } else { '0' }); - } - fmt.debug_struct("BitVec") - .field("storage", &storage) - .field("nbits", &self.nbits) - .finish() - } -} - -impl hash::Hash for BitVec { - #[inline] - fn hash(&self, state: &mut H) { - self.ensure_invariant(); - self.nbits.hash(state); - for elem in self.blocks() { - elem.hash(state); - } - } -} - -impl cmp::PartialEq for BitVec { - #[inline] - fn eq(&self, other: &Self) -> bool { - if self.nbits != other.nbits { - self.ensure_invariant(); - other.ensure_invariant(); - return false; - } - self.blocks().zip(other.blocks()).all(|(w1, w2)| w1 == w2) - } -} - -impl cmp::Eq for BitVec {} - -/// An iterator for `BitVec`. -#[derive(Clone)] -pub struct Iter<'a, B: 'a = u32> { - bit_vec: &'a BitVec, - range: Range, -} - -#[derive(Debug)] -pub struct MutBorrowedBit<'a, B: 'a + BitBlock> { - vec: Rc>>, - index: usize, - #[cfg(debug_assertions)] - old_value: bool, - new_value: bool, -} - -/// An iterator for mutable references to the bits in a `BitVec`. -pub struct IterMut<'a, B: 'a + BitBlock = u32> { - vec: Rc>>, - range: Range, -} - -impl<'a, B: 'a + BitBlock> IterMut<'a, B> { - fn get(&mut self, index: Option) -> Option> { - let value = (*self.vec).borrow().get(index?)?; - Some(MutBorrowedBit { - vec: self.vec.clone(), - index: index?, - #[cfg(debug_assertions)] - old_value: value, - new_value: value, - }) - } -} - -impl Deref for MutBorrowedBit<'_, B> { - type Target = bool; - - fn deref(&self) -> &Self::Target { - &self.new_value - } -} - -impl DerefMut for MutBorrowedBit<'_, B> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.new_value - } -} - -impl Drop for MutBorrowedBit<'_, B> { - fn drop(&mut self) { - let mut vec = (*self.vec).borrow_mut(); - #[cfg(debug_assertions)] - debug_assert_eq!( - Some(self.old_value), - vec.get(self.index), - "Mutably-borrowed bit was modified externally!" - ); - vec.set(self.index, self.new_value); - } -} - -impl Iterator for Iter<'_, B> { - type Item = bool; - - #[inline] - fn next(&mut self) -> Option { - // NB: indexing is slow for extern crates when it has to go through &TRUE or &FALSE - // variables. get is more direct, and unwrap is fine since we're sure of the range. - self.range.next().map(|i| self.bit_vec.get(i).unwrap()) - } - - fn nth(&mut self, n: usize) -> Option { - // This override is used by the compiler to optimize Iterator::skip. - // Without this, the default implementation of Iterator::nth is used, which walks over - // the whole iterator up to n. - self.range.nth(n).and_then(|i| self.bit_vec.get(i)) - } - - fn size_hint(&self) -> (usize, Option) { - self.range.size_hint() - } -} - -impl<'a, B: BitBlock> Iterator for IterMut<'a, B> { - type Item = MutBorrowedBit<'a, B>; - - #[inline] - fn next(&mut self) -> Option { - let index = self.range.next(); - self.get(index) - } - - fn size_hint(&self) -> (usize, Option) { - self.range.size_hint() - } -} - -impl DoubleEndedIterator for Iter<'_, B> { - #[inline] - fn next_back(&mut self) -> Option { - self.range.next_back().map(|i| self.bit_vec.get(i).unwrap()) - } -} - -impl DoubleEndedIterator for IterMut<'_, B> { - #[inline] - fn next_back(&mut self) -> Option { - let index = self.range.next_back(); - self.get(index) - } -} - -impl ExactSizeIterator for Iter<'_, B> {} - -impl ExactSizeIterator for IterMut<'_, B> {} - -impl<'a, B: BitBlock> IntoIterator for &'a BitVec { - type Item = bool; - type IntoIter = Iter<'a, B>; - - #[inline] - fn into_iter(self) -> Iter<'a, B> { - self.iter() - } -} - -pub struct IntoIter { - bit_vec: BitVec, - range: Range, -} - -impl Iterator for IntoIter { - type Item = bool; - - #[inline] - fn next(&mut self) -> Option { - self.range.next().map(|i| self.bit_vec.get(i).unwrap()) - } -} - -impl DoubleEndedIterator for IntoIter { - #[inline] - fn next_back(&mut self) -> Option { - self.range.next_back().map(|i| self.bit_vec.get(i).unwrap()) - } -} - -impl ExactSizeIterator for IntoIter {} - -impl IntoIterator for BitVec { - type Item = bool; - type IntoIter = IntoIter; - - #[inline] - fn into_iter(self) -> IntoIter { - let nbits = self.nbits; - IntoIter { - bit_vec: self, - range: 0..nbits, - } - } -} - -/// An iterator over the blocks of a `BitVec`. -#[derive(Clone)] -pub struct Blocks<'a, B: 'a> { - iter: slice::Iter<'a, B>, -} - -impl Iterator for Blocks<'_, B> { - type Item = B; - - #[inline] - fn next(&mut self) -> Option { - self.iter.next().cloned() - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} - -impl DoubleEndedIterator for Blocks<'_, B> { - #[inline] - fn next_back(&mut self) -> Option { - self.iter.next_back().cloned() - } -} - -impl ExactSizeIterator for Blocks<'_, B> {} - -#[cfg(test)] -mod tests { - #![allow(clippy::shadow_reuse)] - #![allow(clippy::shadow_same)] - #![allow(clippy::shadow_unrelated)] - - use super::{BitVec, Iter, Vec}; - - // This is stupid, but I want to differentiate from a "random" 32 - const U32_BITS: usize = 32; - - #[test] - fn test_display_output() { - assert_eq!(format!("{}", BitVec::new()), ""); - assert_eq!(format!("{}", BitVec::from_elem(1, true)), "1"); - assert_eq!(format!("{}", BitVec::from_elem(8, false)), "00000000") - } - - #[test] - fn test_debug_output() { - assert_eq!( - format!("{:?}", BitVec::new()), - "BitVec { storage: \"\", nbits: 0 }" - ); - assert_eq!( - format!("{:?}", BitVec::from_elem(1, true)), - "BitVec { storage: \"1\", nbits: 1 }" - ); - assert_eq!( - format!("{:?}", BitVec::from_elem(8, false)), - "BitVec { storage: \"00000000\", nbits: 8 }" - ); - assert_eq!( - format!("{:?}", BitVec::from_elem(33, true)), - "BitVec { storage: \"11111111111111111111111111111111 1\", nbits: 33 }" - ); - assert_eq!( - format!( - "{:?}", - BitVec::from_bytes(&[0b111, 0b000, 0b1110, 0b0001, 0b11111111, 0b00000000]) - ), - "BitVec { storage: \"00000111000000000000111000000001 1111111100000000\", nbits: 48 }" - ) - } - - #[test] - fn test_0_elements() { - let act = BitVec::new(); - let exp = Vec::new(); - assert!(act.eq_vec(&exp)); - assert!(act.none() && act.all()); - } - - #[test] - fn test_1_element() { - let mut act = BitVec::from_elem(1, false); - assert!(act.eq_vec(&[false])); - assert!(act.none() && !act.all()); - act = BitVec::from_elem(1, true); - assert!(act.eq_vec(&[true])); - assert!(!act.none() && act.all()); - } - - #[test] - fn test_2_elements() { - let mut b = BitVec::from_elem(2, false); - b.set(0, true); - b.set(1, false); - assert_eq!(format!("{}", b), "10"); - assert!(!b.none() && !b.all()); - } - - #[test] - fn test_10_elements() { - // all 0 - - let mut act = BitVec::from_elem(10, false); - assert!( - (act.eq_vec(&[false, false, false, false, false, false, false, false, false, false])) - ); - assert!(act.none() && !act.all()); - // all 1 - - act = BitVec::from_elem(10, true); - assert!((act.eq_vec(&[true, true, true, true, true, true, true, true, true, true]))); - assert!(!act.none() && act.all()); - // mixed - - act = BitVec::from_elem(10, false); - act.set(0, true); - act.set(1, true); - act.set(2, true); - act.set(3, true); - act.set(4, true); - assert!((act.eq_vec(&[true, true, true, true, true, false, false, false, false, false]))); - assert!(!act.none() && !act.all()); - // mixed - - act = BitVec::from_elem(10, false); - act.set(5, true); - act.set(6, true); - act.set(7, true); - act.set(8, true); - act.set(9, true); - assert!((act.eq_vec(&[false, false, false, false, false, true, true, true, true, true]))); - assert!(!act.none() && !act.all()); - // mixed - - act = BitVec::from_elem(10, false); - act.set(0, true); - act.set(3, true); - act.set(6, true); - act.set(9, true); - assert!((act.eq_vec(&[true, false, false, true, false, false, true, false, false, true]))); - assert!(!act.none() && !act.all()); - } - - #[test] - fn test_31_elements() { - // all 0 - - let mut act = BitVec::from_elem(31, false); - assert!(act.eq_vec(&[ - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false - ])); - assert!(act.none() && !act.all()); - // all 1 - - act = BitVec::from_elem(31, true); - assert!(act.eq_vec(&[ - true, true, true, true, true, true, true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, true, true, true, true, true, true, - true, true, true - ])); - assert!(!act.none() && act.all()); - // mixed - - act = BitVec::from_elem(31, false); - act.set(0, true); - act.set(1, true); - act.set(2, true); - act.set(3, true); - act.set(4, true); - act.set(5, true); - act.set(6, true); - act.set(7, true); - assert!(act.eq_vec(&[ - true, true, true, true, true, true, true, true, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false - ])); - assert!(!act.none() && !act.all()); - // mixed - - act = BitVec::from_elem(31, false); - act.set(16, true); - act.set(17, true); - act.set(18, true); - act.set(19, true); - act.set(20, true); - act.set(21, true); - act.set(22, true); - act.set(23, true); - assert!(act.eq_vec(&[ - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, true, true, true, true, true, true, true, true, false, - false, false, false, false, false, false - ])); - assert!(!act.none() && !act.all()); - // mixed - - act = BitVec::from_elem(31, false); - act.set(24, true); - act.set(25, true); - act.set(26, true); - act.set(27, true); - act.set(28, true); - act.set(29, true); - act.set(30, true); - assert!(act.eq_vec(&[ - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, - true, true, true, true, true, true, true - ])); - assert!(!act.none() && !act.all()); - // mixed - - act = BitVec::from_elem(31, false); - act.set(3, true); - act.set(17, true); - act.set(30, true); - assert!(act.eq_vec(&[ - false, false, false, true, false, false, false, false, false, false, false, false, - false, false, false, false, false, true, false, false, false, false, false, false, - false, false, false, false, false, false, true - ])); - assert!(!act.none() && !act.all()); - } - - #[test] - fn test_32_elements() { - // all 0 - - let mut act = BitVec::from_elem(32, false); - assert!(act.eq_vec(&[ - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false - ])); - assert!(act.none() && !act.all()); - // all 1 - - act = BitVec::from_elem(32, true); - assert!(act.eq_vec(&[ - true, true, true, true, true, true, true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, true, true, true, true, true, true, - true, true, true, true - ])); - assert!(!act.none() && act.all()); - // mixed - - act = BitVec::from_elem(32, false); - act.set(0, true); - act.set(1, true); - act.set(2, true); - act.set(3, true); - act.set(4, true); - act.set(5, true); - act.set(6, true); - act.set(7, true); - assert!(act.eq_vec(&[ - true, true, true, true, true, true, true, true, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false - ])); - assert!(!act.none() && !act.all()); - // mixed - - act = BitVec::from_elem(32, false); - act.set(16, true); - act.set(17, true); - act.set(18, true); - act.set(19, true); - act.set(20, true); - act.set(21, true); - act.set(22, true); - act.set(23, true); - assert!(act.eq_vec(&[ - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, true, true, true, true, true, true, true, true, false, - false, false, false, false, false, false, false - ])); - assert!(!act.none() && !act.all()); - // mixed - - act = BitVec::from_elem(32, false); - act.set(24, true); - act.set(25, true); - act.set(26, true); - act.set(27, true); - act.set(28, true); - act.set(29, true); - act.set(30, true); - act.set(31, true); - assert!(act.eq_vec(&[ - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, - true, true, true, true, true, true, true, true - ])); - assert!(!act.none() && !act.all()); - // mixed - - act = BitVec::from_elem(32, false); - act.set(3, true); - act.set(17, true); - act.set(30, true); - act.set(31, true); - assert!(act.eq_vec(&[ - false, false, false, true, false, false, false, false, false, false, false, false, - false, false, false, false, false, true, false, false, false, false, false, false, - false, false, false, false, false, false, true, true - ])); - assert!(!act.none() && !act.all()); - } - - #[test] - fn test_33_elements() { - // all 0 - - let mut act = BitVec::from_elem(33, false); - assert!(act.eq_vec(&[ - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false - ])); - assert!(act.none() && !act.all()); - // all 1 - - act = BitVec::from_elem(33, true); - assert!(act.eq_vec(&[ - true, true, true, true, true, true, true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, true, true, true, true, true, true, - true, true, true, true, true - ])); - assert!(!act.none() && act.all()); - // mixed - - act = BitVec::from_elem(33, false); - act.set(0, true); - act.set(1, true); - act.set(2, true); - act.set(3, true); - act.set(4, true); - act.set(5, true); - act.set(6, true); - act.set(7, true); - assert!(act.eq_vec(&[ - true, true, true, true, true, true, true, true, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false - ])); - assert!(!act.none() && !act.all()); - // mixed - - act = BitVec::from_elem(33, false); - act.set(16, true); - act.set(17, true); - act.set(18, true); - act.set(19, true); - act.set(20, true); - act.set(21, true); - act.set(22, true); - act.set(23, true); - assert!(act.eq_vec(&[ - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, true, true, true, true, true, true, true, true, false, - false, false, false, false, false, false, false, false - ])); - assert!(!act.none() && !act.all()); - // mixed - - act = BitVec::from_elem(33, false); - act.set(24, true); - act.set(25, true); - act.set(26, true); - act.set(27, true); - act.set(28, true); - act.set(29, true); - act.set(30, true); - act.set(31, true); - assert!(act.eq_vec(&[ - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, - true, true, true, true, true, true, true, true, false - ])); - assert!(!act.none() && !act.all()); - // mixed - - act = BitVec::from_elem(33, false); - act.set(3, true); - act.set(17, true); - act.set(30, true); - act.set(31, true); - act.set(32, true); - assert!(act.eq_vec(&[ - false, false, false, true, false, false, false, false, false, false, false, false, - false, false, false, false, false, true, false, false, false, false, false, false, - false, false, false, false, false, false, true, true, true - ])); - assert!(!act.none() && !act.all()); - } - - #[test] - fn test_equal_differing_sizes() { - let v0 = BitVec::from_elem(10, false); - let v1 = BitVec::from_elem(11, false); - assert_ne!(v0, v1); - } - - #[test] - fn test_equal_greatly_differing_sizes() { - let v0 = BitVec::from_elem(10, false); - let v1 = BitVec::from_elem(110, false); - assert_ne!(v0, v1); - } - - #[test] - fn test_equal_sneaky_small() { - let mut a = BitVec::from_elem(1, false); - a.set(0, true); - - let mut b = BitVec::from_elem(1, true); - b.set(0, true); - - assert_eq!(a, b); - } - - #[test] - fn test_equal_sneaky_big() { - let mut a = BitVec::from_elem(100, false); - for i in 0..100 { - a.set(i, true); - } - - let mut b = BitVec::from_elem(100, true); - for i in 0..100 { - b.set(i, true); - } - - assert_eq!(a, b); - } - - #[test] - fn test_from_bytes() { - let bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]); - let str = concat!("10110110", "00000000", "11111111"); - assert_eq!(format!("{}", bit_vec), str); - } - - #[test] - fn test_to_bytes() { - let mut bv = BitVec::from_elem(3, true); - bv.set(1, false); - assert_eq!(bv.to_bytes(), [0b10100000]); - - let mut bv = BitVec::from_elem(9, false); - bv.set(2, true); - bv.set(8, true); - assert_eq!(bv.to_bytes(), [0b00100000, 0b10000000]); - } - - #[test] - fn test_from_bools() { - let bools = [true, false, true, true]; - let bit_vec: BitVec = bools.iter().copied().collect(); - assert_eq!(format!("{}", bit_vec), "1011"); - } - - #[test] - fn test_to_bools() { - let bools = vec![false, false, true, false, false, true, true, false]; - assert_eq!( - BitVec::from_bytes(&[0b00100110]) - .iter() - .collect::>(), - bools - ); - } - - #[test] - fn test_bit_vec_iterator() { - let bools = vec![true, false, true, true]; - let bit_vec: BitVec = bools.iter().copied().collect(); - - assert_eq!(bit_vec.iter().collect::>(), bools); - - let long: Vec<_> = (0..10000).map(|i| i % 2 == 0).collect(); - let bit_vec: BitVec = long.iter().copied().collect(); - assert_eq!(bit_vec.iter().collect::>(), long) - } - - #[test] - fn test_small_difference() { - let mut b1 = BitVec::from_elem(3, false); - let mut b2 = BitVec::from_elem(3, false); - b1.set(0, true); - b1.set(1, true); - b2.set(1, true); - b2.set(2, true); - assert!(b1.difference(&b2)); - assert!(b1[0]); - assert!(!b1[1]); - assert!(!b1[2]); - } - - #[test] - fn test_big_difference() { - let mut b1 = BitVec::from_elem(100, false); - let mut b2 = BitVec::from_elem(100, false); - b1.set(0, true); - b1.set(40, true); - b2.set(40, true); - b2.set(80, true); - assert!(b1.difference(&b2)); - assert!(b1[0]); - assert!(!b1[40]); - assert!(!b1[80]); - } - - #[test] - fn test_small_xor() { - let mut a = BitVec::from_bytes(&[0b0011]); - let b = BitVec::from_bytes(&[0b0101]); - let c = BitVec::from_bytes(&[0b0110]); - assert!(a.xor(&b)); - assert_eq!(a, c); - } - - #[test] - fn test_small_xnor() { - let mut a = BitVec::from_bytes(&[0b0011]); - let b = BitVec::from_bytes(&[0b1111_0101]); - let c = BitVec::from_bytes(&[0b1001]); - assert!(a.xnor(&b)); - assert_eq!(a, c); - } - - #[test] - fn test_small_nand() { - let mut a = BitVec::from_bytes(&[0b1111_0011]); - let b = BitVec::from_bytes(&[0b1111_0101]); - let c = BitVec::from_bytes(&[0b1110]); - assert!(a.nand(&b)); - assert_eq!(a, c); - } - - #[test] - fn test_small_nor() { - let mut a = BitVec::from_bytes(&[0b0011]); - let b = BitVec::from_bytes(&[0b1111_0101]); - let c = BitVec::from_bytes(&[0b1000]); - assert!(a.nor(&b)); - assert_eq!(a, c); - } - - #[test] - fn test_big_xor() { - let mut a = BitVec::from_bytes(&[ - // 88 bits - 0, 0, 0b00010100, 0, 0, 0, 0, 0b00110100, 0, 0, 0, - ]); - let b = BitVec::from_bytes(&[ - // 88 bits - 0, 0, 0b00010100, 0, 0, 0, 0, 0, 0, 0, 0b00110100, - ]); - let c = BitVec::from_bytes(&[ - // 88 bits - 0, 0, 0, 0, 0, 0, 0, 0b00110100, 0, 0, 0b00110100, - ]); - assert!(a.xor(&b)); - assert_eq!(a, c); - } - - #[test] - fn test_big_xnor() { - let mut a = BitVec::from_bytes(&[ - // 88 bits - 0, 0, 0b00010100, 0, 0, 0, 0, 0b00110100, 0, 0, 0, - ]); - let b = BitVec::from_bytes(&[ - // 88 bits - 0, 0, 0b00010100, 0, 0, 0, 0, 0, 0, 0, 0b00110100, - ]); - let c = BitVec::from_bytes(&[ - // 88 bits - !0, - !0, - !0, - !0, - !0, - !0, - !0, - !0b00110100, - !0, - !0, - !0b00110100, - ]); - assert!(a.xnor(&b)); - assert_eq!(a, c); - } - - #[test] - fn test_small_fill() { - let mut b = BitVec::from_elem(14, true); - assert!(!b.none() && b.all()); - b.fill(false); - assert!(b.none() && !b.all()); - b.fill(true); - assert!(!b.none() && b.all()); - } - - #[test] - fn test_big_fill() { - let mut b = BitVec::from_elem(140, true); - assert!(!b.none() && b.all()); - b.fill(false); - assert!(b.none() && !b.all()); - b.fill(true); - assert!(!b.none() && b.all()); - } - - #[test] - fn test_bit_vec_lt() { - let mut a = BitVec::from_elem(5, false); - let mut b = BitVec::from_elem(5, false); - - assert!(a >= b && b >= a); - b.set(2, true); - assert!(a < b); - a.set(3, true); - assert!(a < b); - a.set(2, true); - assert!(a >= b && b < a); - b.set(0, true); - assert!(a < b); - } - - #[test] - fn test_ord() { - let mut a = BitVec::from_elem(5, false); - let mut b = BitVec::from_elem(5, false); - - assert!(a == b); - a.set(1, true); - assert!(a > b && a >= b); - assert!(b < a && b <= a); - b.set(1, true); - b.set(2, true); - assert!(b > a && b >= a); - assert!(a < b && a <= b); - } - - #[test] - fn test_small_bit_vec_tests() { - let v = BitVec::from_bytes(&[0]); - assert!(!v.all()); - assert!(!v.any()); - assert!(v.none()); - - let v = BitVec::from_bytes(&[0b00010100]); - assert!(!v.all()); - assert!(v.any()); - assert!(!v.none()); - - let v = BitVec::from_bytes(&[0xFF]); - assert!(v.all()); - assert!(v.any()); - assert!(!v.none()); - } - - #[test] - fn test_big_bit_vec_tests() { - let v = BitVec::from_bytes(&[ - // 88 bits - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ]); - assert!(!v.all()); - assert!(!v.any()); - assert!(v.none()); - - let v = BitVec::from_bytes(&[ - // 88 bits - 0, 0, 0b00010100, 0, 0, 0, 0, 0b00110100, 0, 0, 0, - ]); - assert!(!v.all()); - assert!(v.any()); - assert!(!v.none()); - - let v = BitVec::from_bytes(&[ - // 88 bits - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - ]); - assert!(v.all()); - assert!(v.any()); - assert!(!v.none()); - } - - #[test] - fn test_bit_vec_push_pop() { - let mut s = BitVec::from_elem(5 * U32_BITS - 2, false); - assert_eq!(s.len(), 5 * U32_BITS - 2); - assert!(!s[5 * U32_BITS - 3]); - s.push(true); - s.push(true); - assert!(s[5 * U32_BITS - 2]); - assert!(s[5 * U32_BITS - 1]); - // Here the internal vector will need to be extended - s.push(false); - assert!(!s[5 * U32_BITS]); - s.push(false); - assert!(!s[5 * U32_BITS + 1]); - assert_eq!(s.len(), 5 * U32_BITS + 2); - // Pop it all off - assert_eq!(s.pop(), Some(false)); - assert_eq!(s.pop(), Some(false)); - assert_eq!(s.pop(), Some(true)); - assert_eq!(s.pop(), Some(true)); - assert_eq!(s.len(), 5 * U32_BITS - 2); - } - - #[test] - fn test_bit_vec_truncate() { - let mut s = BitVec::from_elem(5 * U32_BITS, true); - - assert_eq!(s, BitVec::from_elem(5 * U32_BITS, true)); - assert_eq!(s.len(), 5 * U32_BITS); - s.truncate(4 * U32_BITS); - assert_eq!(s, BitVec::from_elem(4 * U32_BITS, true)); - assert_eq!(s.len(), 4 * U32_BITS); - // Truncating to a size > s.len() should be a noop - s.truncate(5 * U32_BITS); - assert_eq!(s, BitVec::from_elem(4 * U32_BITS, true)); - assert_eq!(s.len(), 4 * U32_BITS); - s.truncate(3 * U32_BITS - 10); - assert_eq!(s, BitVec::from_elem(3 * U32_BITS - 10, true)); - assert_eq!(s.len(), 3 * U32_BITS - 10); - s.truncate(0); - assert_eq!(s, BitVec::from_elem(0, true)); - assert_eq!(s.len(), 0); - } - - #[test] - fn test_bit_vec_reserve() { - let mut s = BitVec::from_elem(5 * U32_BITS, true); - // Check capacity - assert!(s.capacity() >= 5 * U32_BITS); - s.reserve(2 * U32_BITS); - assert!(s.capacity() >= 7 * U32_BITS); - s.reserve(7 * U32_BITS); - assert!(s.capacity() >= 12 * U32_BITS); - s.reserve_exact(7 * U32_BITS); - assert!(s.capacity() >= 12 * U32_BITS); - s.reserve(7 * U32_BITS + 1); - assert!(s.capacity() > 12 * U32_BITS); - // Check that length hasn't changed - assert_eq!(s.len(), 5 * U32_BITS); - s.push(true); - s.push(false); - s.push(true); - assert!(s[5 * U32_BITS - 1]); - assert!(s[5 * U32_BITS]); - assert!(!s[5 * U32_BITS + 1]); - assert!(s[5 * U32_BITS + 2]); - } - - #[test] - fn test_bit_vec_grow() { - let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010]); - bit_vec.grow(32, true); - assert_eq!( - bit_vec, - BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010, 0xFF, 0xFF, 0xFF, 0xFF]) - ); - bit_vec.grow(64, false); - assert_eq!( - bit_vec, - BitVec::from_bytes(&[ - 0b10110110, 0b00000000, 0b10101010, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 - ]) - ); - bit_vec.grow(16, true); - assert_eq!( - bit_vec, - BitVec::from_bytes(&[ - 0b10110110, 0b00000000, 0b10101010, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, - 0xFF, 0xFF - ]) - ); - } - - #[test] - fn test_bit_vec_extend() { - let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]); - let ext = BitVec::from_bytes(&[0b01001001, 0b10010010, 0b10111101]); - bit_vec.extend(ext.iter()); - assert_eq!( - bit_vec, - BitVec::from_bytes(&[ - 0b10110110, 0b00000000, 0b11111111, 0b01001001, 0b10010010, 0b10111101 - ]) - ); - } - - #[test] - fn test_bit_vec_append() { - // Append to BitVec that holds a multiple of U32_BITS bits - let mut a = BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011]); - let mut b = BitVec::new(); - b.push(false); - b.push(true); - b.push(true); - - a.append(&mut b); - - assert_eq!(a.len(), 35); - assert_eq!(b.len(), 0); - assert!(b.capacity() >= 3); - - assert!(a.eq_vec(&[ - true, false, true, false, false, false, false, false, false, false, false, true, false, - false, true, false, true, false, false, true, false, false, true, false, false, false, - true, true, false, false, true, true, false, true, true - ])); - - // Append to arbitrary BitVec - let mut a = BitVec::new(); - a.push(true); - a.push(false); - - let mut b = - BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b10010101]); - - a.append(&mut b); - - assert_eq!(a.len(), 42); - assert_eq!(b.len(), 0); - assert!(b.capacity() >= 40); - - assert!(a.eq_vec(&[ - true, false, true, false, true, false, false, false, false, false, false, false, false, - true, false, false, true, false, true, false, false, true, false, false, true, false, - false, false, true, true, false, false, true, true, true, false, false, true, false, - true, false, true - ])); - - // Append to empty BitVec - let mut a = BitVec::new(); - let mut b = - BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b10010101]); - - a.append(&mut b); - - assert_eq!(a.len(), 40); - assert_eq!(b.len(), 0); - assert!(b.capacity() >= 40); - - assert!(a.eq_vec(&[ - true, false, true, false, false, false, false, false, false, false, false, true, false, - false, true, false, true, false, false, true, false, false, true, false, false, false, - true, true, false, false, true, true, true, false, false, true, false, true, false, - true - ])); - - // Append empty BitVec - let mut a = - BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b10010101]); - let mut b = BitVec::new(); - - a.append(&mut b); - - assert_eq!(a.len(), 40); - assert_eq!(b.len(), 0); - - assert!(a.eq_vec(&[ - true, false, true, false, false, false, false, false, false, false, false, true, false, - false, true, false, true, false, false, true, false, false, true, false, false, false, - true, true, false, false, true, true, true, false, false, true, false, true, false, - true - ])); - } - - #[test] - fn test_bit_vec_split_off() { - // Split at 0 - let mut a = BitVec::new(); - a.push(true); - a.push(false); - a.push(false); - a.push(true); - - let b = a.split_off(0); - - assert_eq!(a.len(), 0); - assert_eq!(b.len(), 4); - - assert!(b.eq_vec(&[true, false, false, true])); - - // Split at last bit - a.truncate(0); - a.push(true); - a.push(false); - a.push(false); - a.push(true); - - let b = a.split_off(4); - - assert_eq!(a.len(), 4); - assert_eq!(b.len(), 0); - - assert!(a.eq_vec(&[true, false, false, true])); - - // Split at block boundary - let mut a = - BitVec::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b11110011]); - - let b = a.split_off(32); - - assert_eq!(a.len(), 32); - assert_eq!(b.len(), 8); - - assert!(a.eq_vec(&[ - true, false, true, false, false, false, false, false, false, false, false, true, false, - false, true, false, true, false, false, true, false, false, true, false, false, false, - true, true, false, false, true, true - ])); - assert!(b.eq_vec(&[true, true, true, true, false, false, true, true])); - - // Don't split at block boundary - let mut a = BitVec::from_bytes(&[ - 0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b01101011, 0b10101101, - ]); - - let b = a.split_off(13); - - assert_eq!(a.len(), 13); - assert_eq!(b.len(), 35); - - assert!(a.eq_vec(&[ - true, false, true, false, false, false, false, false, false, false, false, true, false - ])); - assert!(b.eq_vec(&[ - false, true, false, true, false, false, true, false, false, true, false, false, false, - true, true, false, false, true, true, false, true, true, false, true, false, true, - true, true, false, true, false, true, true, false, true - ])); - } - - #[test] - fn test_into_iter() { - let bools = [true, false, true, true]; - let bit_vec: BitVec = bools.iter().copied().collect(); - let mut iter = bit_vec.into_iter(); - assert_eq!(Some(true), iter.next()); - assert_eq!(Some(false), iter.next()); - assert_eq!(Some(true), iter.next()); - assert_eq!(Some(true), iter.next()); - assert_eq!(None, iter.next()); - assert_eq!(None, iter.next()); - - let bit_vec: BitVec = bools.iter().copied().collect(); - let mut iter = bit_vec.into_iter(); - assert_eq!(Some(true), iter.next_back()); - assert_eq!(Some(true), iter.next_back()); - assert_eq!(Some(false), iter.next_back()); - assert_eq!(Some(true), iter.next_back()); - assert_eq!(None, iter.next_back()); - assert_eq!(None, iter.next_back()); - - let bit_vec: BitVec = bools.iter().copied().collect(); - let mut iter = bit_vec.into_iter(); - assert_eq!(Some(true), iter.next_back()); - assert_eq!(Some(true), iter.next()); - assert_eq!(Some(false), iter.next()); - assert_eq!(Some(true), iter.next_back()); - assert_eq!(None, iter.next()); - assert_eq!(None, iter.next_back()); - } - - #[test] - fn iter() { - let b = BitVec::with_capacity(10); - let _a: Iter = b.iter(); - } - - #[cfg(feature = "serde")] - #[test] - fn test_serialization() { - let bit_vec: BitVec = BitVec::new(); - let serialized = serde_json::to_string(&bit_vec).unwrap(); - let unserialized: BitVec = serde_json::from_str(&serialized[..]).unwrap(); - assert_eq!(bit_vec, unserialized); - - let bools = [true, false, true, true]; - let bit_vec: BitVec = bools.iter().copied().collect(); - let serialized = serde_json::to_string(&bit_vec).unwrap(); - let unserialized = serde_json::from_str(&serialized).unwrap(); - assert_eq!(bit_vec, unserialized); - } - - #[cfg(feature = "miniserde")] - #[test] - fn test_miniserde_serialization() { - let bit_vec: BitVec = BitVec::new(); - let serialized = miniserde::json::to_string(&bit_vec); - let unserialized = miniserde::json::from_str(&serialized[..]).unwrap(); - assert_eq!(bit_vec, unserialized); - - let bools = [true, false, true, true]; - let bit_vec: BitVec = bools.iter().copied().collect(); - let serialized = miniserde::json::to_string(&bit_vec); - let unserialized = miniserde::json::from_str(&serialized[..]).unwrap(); - assert_eq!(bit_vec, unserialized); - } - - #[cfg(feature = "borsh")] - #[test] - fn test_borsh_serialization() { - let bit_vec: BitVec = BitVec::new(); - let serialized = borsh::to_vec(&bit_vec).unwrap(); - let unserialized = borsh::from_slice(&serialized[..]).unwrap(); - assert_eq!(bit_vec, unserialized); - - let bools = [true, false, true, true]; - let bit_vec: BitVec = bools.iter().copied().collect(); - let serialized = borsh::to_vec(&bit_vec).unwrap(); - let unserialized = borsh::from_slice(&serialized[..]).unwrap(); - assert_eq!(bit_vec, unserialized); - } - - #[test] - fn test_bit_vec_unaligned_small_append() { - let mut a = BitVec::from_elem(8, false); - a.set(7, true); - - let mut b = BitVec::from_elem(16, false); - b.set(14, true); - - let mut c = BitVec::from_elem(8, false); - c.set(6, true); - c.set(7, true); - - a.append(&mut b); - a.append(&mut c); - - assert_eq!(&[1, 0, 2, 3][..], &*a.to_bytes()); - } - - #[test] - fn test_bit_vec_unaligned_large_append() { - let mut a = BitVec::from_elem(48, false); - a.set(47, true); - - let mut b = BitVec::from_elem(48, false); - b.set(46, true); - - let mut c = BitVec::from_elem(48, false); - c.set(46, true); - c.set(47, true); - - a.append(&mut b); - a.append(&mut c); - - assert_eq!( - &[ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x03 - ][..], - &*a.to_bytes() - ); - } - - #[test] - fn test_bit_vec_append_aligned_to_unaligned() { - let mut a = BitVec::from_elem(2, true); - let mut b = BitVec::from_elem(32, false); - let mut c = BitVec::from_elem(8, true); - a.append(&mut b); - a.append(&mut c); - assert_eq!(&[0xc0, 0x00, 0x00, 0x00, 0x3f, 0xc0][..], &*a.to_bytes()); - } - - #[test] - fn test_count_ones() { - for i in 0..1000 { - let mut t = BitVec::from_elem(i, true); - let mut f = BitVec::from_elem(i, false); - assert_eq!(i as u64, t.count_ones()); - assert_eq!(0_u64, f.count_ones()); - if i > 20 { - t.set(10, false); - t.set(i - 10, false); - assert_eq!(i - 2, t.count_ones() as usize); - f.set(10, true); - f.set(i - 10, true); - assert_eq!(2, f.count_ones()); - } - } - } - - #[test] - fn test_count_zeros() { - for i in 0..1000 { - let mut tbits = BitVec::from_elem(i, true); - let mut fbits = BitVec::from_elem(i, false); - assert_eq!(i as u64, fbits.count_zeros()); - assert_eq!(0_u64, tbits.count_zeros()); - if i > 20 { - fbits.set(10, true); - fbits.set(i - 10, true); - assert_eq!(i - 2, fbits.count_zeros() as usize); - tbits.set(10, false); - tbits.set(i - 10, false); - assert_eq!(2, tbits.count_zeros()); - } - } - } - - #[test] - fn test_get_mut() { - let mut a = BitVec::from_elem(3, false); - let mut a_bit_1 = a.get_mut(1).unwrap(); - assert!(!*a_bit_1); - *a_bit_1 = true; - drop(a_bit_1); - assert!(a.eq_vec(&[false, true, false])); - } - #[test] - fn test_iter_mut() { - let mut a = BitVec::from_elem(8, false); - a.iter_mut().enumerate().for_each(|(index, mut bit)| { - *bit = index % 2 == 1; - }); - assert!(a.eq_vec(&[false, true, false, true, false, true, false, true])); - } - - #[test] - fn test_insert_at_zero() { - let mut v = BitVec::new(); - - v.insert(0, false); - v.insert(0, true); - v.insert(0, false); - v.insert(0, true); - v.insert(0, false); - v.insert(0, true); - - assert_eq!(v.len(), 6); - assert_eq!(v.storage().len(), 1); - assert!(v.eq_vec(&[true, false, true, false, true, false])); - } - - #[test] - fn test_insert_at_end() { - let mut v = BitVec::new(); - - v.insert(v.len(), true); - v.insert(v.len(), false); - v.insert(v.len(), true); - v.insert(v.len(), false); - v.insert(v.len(), true); - v.insert(v.len(), false); - - assert_eq!(v.storage().len(), 1); - assert_eq!(v.len(), 6); - assert!(v.eq_vec(&[true, false, true, false, true, false])); - } - - #[test] - fn test_insert_at_block_boundaries() { - let mut v = BitVec::from_elem(32, false); - - assert_eq!(v.storage().len(), 1); - - v.insert(31, true); - - assert_eq!(v.len(), 33); - - assert!(matches!(v.get(31), Some(true))); - assert!(v.eq_vec(&[ - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, true, false - ])); - - assert_eq!(v.storage().len(), 2); - } - - #[test] - fn test_insert_at_block_boundaries_1() { - let mut v = BitVec::from_elem(64, false); - - assert_eq!(v.storage().len(), 2); - - v.insert(63, true); - - assert_eq!(v.len(), 65); - - assert!(matches!(v.get(63), Some(true))); - assert!(v.eq_vec(&[ - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, true, false - ])); - - assert_eq!(v.storage().len(), 3); - } - - #[test] - fn test_push_within_capacity_with_suffice_cap() { - let mut v = BitVec::from_elem(16, true); - - assert!(v.push_within_capacity(false).is_ok()); - - for i in 0..16 { - assert_eq!(v.get(i), Some(true)); - } - - assert_eq!(v.get(16), Some(false)); - assert_eq!(v.len(), 17); - } - - #[test] - fn test_push_within_capacity_at_brink() { - let mut v = BitVec::from_elem(31, true); - - assert!(v.push_within_capacity(false).is_ok()); - - assert_eq!(v.get(31), Some(false)); - assert_eq!(v.len(), v.capacity()); - assert_eq!(v.len(), 32); - - assert_eq!(v.push_within_capacity(false), Err(false)); - assert_eq!(v.capacity(), 32); - - for i in 0..31 { - assert_eq!(v.get(i), Some(true)); - } - assert_eq!(v.get(31), Some(false)); - } - - #[test] - fn test_push_within_capacity_at_brink_with_mul_blocks() { - let mut v = BitVec::from_elem(95, true); - - assert!(v.push_within_capacity(false).is_ok()); - - assert_eq!(v.get(95), Some(false)); - assert_eq!(v.len(), v.capacity()); - assert_eq!(v.len(), 96); - - assert_eq!(v.push_within_capacity(false), Err(false)); - assert_eq!(v.capacity(), 96); - - for i in 0..95 { - assert_eq!(v.get(i), Some(true)); - } - assert_eq!(v.get(95), Some(false)); - } - - #[test] - fn test_push_within_capacity_storage_push() { - let mut v = BitVec::with_capacity(64); - - for _ in 0..32 { - v.push(true); - } - - assert_eq!(v.len(), 32); - - assert!(v.push_within_capacity(false).is_ok()); - - assert_eq!(v.len(), 33); - - for i in 0..32 { - assert_eq!(v.get(i), Some(true)); - } - assert_eq!(v.get(32), Some(false)); - } - - #[test] - fn test_insert_remove() { - // two primes for no common divisors with 32 - let mut v = BitVec::from_fn(1024, |i| i % 11 < 7); - for i in 0..1024 { - let result = v.remove(i); - v.insert(i, result); - assert_eq!(result, i % 11 < 7); - } - - for i in 0..1024 { - v.insert(i, false); - v.remove(i); - } - - for i in 0..1024 { - v.insert(i, true); - v.remove(i); - } - - for (i, result) in v.into_iter().enumerate() { - assert_eq!(result, i % 11 < 7); - } - } - - #[test] - fn test_remove_last() { - let mut v = BitVec::from_fn(1025, |i| i % 11 < 7); - assert_eq!(v.len(), 1025); - assert_eq!(v.remove(1024), 1024 % 11 < 7); - assert_eq!(v.len(), 1024); - assert_eq!(v.storage().len(), 1024 / 32); - } - - #[test] - fn test_remove_all() { - let v = BitVec::from_elem(1024, false); - for _ in 0..1024 { - let mut v2 = v.clone(); - v2.remove_all(); - assert_eq!(v2.len(), 0); - assert_eq!(v2.get(0), None); - assert_eq!(v2, BitVec::new()); - } - } -} +mod vec; + +mod local_prelude { + pub use crate::block::BitBlock; + pub use crate::container::BitContainer; + pub use crate::vec::BitVec; + + #[cfg(all(not(feature = "std"), feature = "borsh"))] + pub use alloc::borrow::ToOwned; + #[cfg(all(not(feature = "std"), feature = "miniserde"))] + pub use alloc::boxed::Box; + #[cfg(not(feature = "std"))] + pub use alloc::rc::Rc; + #[cfg(not(feature = "std"))] + pub use alloc::string::String; + #[cfg(not(feature = "std"))] + pub use alloc::vec::Vec; + + #[cfg(all(feature = "std", feature = "borsh"))] + pub use std::borrow::ToOwned; + #[cfg(all(feature = "std", feature = "miniserde"))] + pub use std::boxed::Box; + #[cfg(feature = "std")] + pub use std::rc::Rc; + #[cfg(feature = "std")] + pub use std::string::String; + #[cfg(feature = "std")] + pub use std::vec::Vec; +} + +pub use block::BitBlock; +pub use blocks::Blocks; +pub use container::BitContainer; +pub use iter::Iter; +pub use smart_mut::IterMut; +pub use vec::BitVec; diff --git a/vec/src/serde.rs b/vec/src/serde.rs new file mode 100644 index 0000000..f4e23f4 --- /dev/null +++ b/vec/src/serde.rs @@ -0,0 +1,161 @@ +use crate::local_prelude::*; + +#[cfg(any(feature = "serde", feature = "borsh"))] +use core::{error, fmt}; + +#[cfg(any(feature = "serde", feature = "borsh", feature = "miniserde"))] +#[cfg_attr(feature = "serde", derive(serde::Deserialize))] +#[cfg_attr(feature = "borsh", derive(borsh::BorshDeserialize))] +#[cfg(any(feature = "serde", feature = "borsh"))] +pub struct UncheckedBitVec = Vec> { + /// Internal representation of the bit vector + pub(crate) storage: C, + /// The number of valid bits in the internal representation + pub(crate) nbits: usize, +} + +#[cfg(feature = "serde")] +impl<'de, C: BitContainer> serde::Deserialize<'de> for BitVec +where + C: serde::Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + use serde::de::Error; + UncheckedBitVec::::deserialize(deserializer).and_then(|unchecked| { + let result = BitVec { + storage: unchecked.storage, + nbits: unchecked.nbits, + }; + if !result.storage_len_matches_nbits() { + Err(D::Error::custom(DeserializeError::StorageLenMismatch)) + } else if !result.is_last_block_fixed() { + Err(D::Error::custom(DeserializeError::TrailingBits)) + } else { + Ok(result) + } + }) + } +} + +#[cfg(feature = "borsh")] +impl borsh::BorshDeserialize for BitVec +where + C: borsh::BorshDeserialize, +{ + fn deserialize_reader(reader: &mut R) -> borsh::io::Result { + UncheckedBitVec::::deserialize_reader(reader).and_then(|unchecked| { + let result = BitVec { + storage: unchecked.storage, + nbits: unchecked.nbits, + }; + if !result.storage_len_matches_nbits() { + Err(borsh::io::Error::other( + DeserializeError::StorageLenMismatch, + )) + } else if !result.is_last_block_fixed() { + Err(borsh::io::Error::other(DeserializeError::TrailingBits)) + } else { + Ok(result) + } + }) + } +} + +#[cfg(feature = "miniserde")] +miniserde::make_place!(Place); + +#[cfg(feature = "miniserde")] +struct BitVecBuilder<'a, C: BitContainer> { + storage: Option, + nbits: Option, + out: &'a mut Option>, +} + +#[cfg(feature = "miniserde")] +impl miniserde::de::Visitor for Place> +where + C: miniserde::Deserialize, + C::Block: miniserde::Deserialize, +{ + fn map(&mut self) -> miniserde::Result> { + Ok(Box::new(BitVecBuilder { + storage: None, + nbits: None, + out: &mut self.out, + })) + } +} + +#[cfg(feature = "miniserde")] +impl miniserde::de::Map for BitVecBuilder<'_, C> +where + C: miniserde::Deserialize, +{ + fn key(&mut self, k: &str) -> miniserde::Result<&mut dyn miniserde::de::Visitor> { + match k { + "storage" => Ok(miniserde::Deserialize::begin(&mut self.storage)), + "nbits" => Ok(miniserde::Deserialize::begin(&mut self.nbits)), + _ => Ok(::ignore()), + } + } + + fn finish(&mut self) -> miniserde::Result<()> { + let storage = self.storage.take().ok_or(miniserde::Error)?; + let nbits = self.nbits.take().ok_or(miniserde::Error)?; + let result = BitVec { storage, nbits }; + if !result.storage_len_matches_nbits() || !result.is_last_block_fixed() { + Err(miniserde::Error) + } else { + *self.out = Some(result); + Ok(()) + } + } +} + +#[cfg(feature = "miniserde")] +impl miniserde::Deserialize for BitVec +where + C: miniserde::Deserialize, + C::Block: miniserde::Deserialize, +{ + fn begin(out: &mut Option) -> &mut dyn miniserde::de::Visitor { + Place::new(out) + } +} + +#[cfg(any(feature = "serde", feature = "borsh"))] +#[derive(Debug)] +pub enum DeserializeError { + StorageLenMismatch, + TrailingBits, +} + +#[cfg(any(feature = "serde", feature = "borsh"))] +impl fmt::Display for DeserializeError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.simple_description()) + } +} + +#[cfg(feature = "borsh")] +impl From for String { + fn from(value: DeserializeError) -> Self { + value.simple_description().to_owned() + } +} + +#[cfg(any(feature = "serde", feature = "borsh"))] +impl error::Error for DeserializeError {} + +#[cfg(any(feature = "serde", feature = "borsh"))] +impl DeserializeError { + fn simple_description(&self) -> &str { + match self { + DeserializeError::TrailingBits => "some out of bounds trailing bits are set", + DeserializeError::StorageLenMismatch => "nbits and storage length isnt same", + } + } +} diff --git a/vec/src/smart_mut.rs b/vec/src/smart_mut.rs new file mode 100644 index 0000000..ece2f1c --- /dev/null +++ b/vec/src/smart_mut.rs @@ -0,0 +1,164 @@ +use crate::local_prelude::*; +use core::cell::RefCell; +use core::ops; + +/// An iterator for mutable references to the bits in a `BitVec`. +pub struct IterMut<'a, B: 'a + BitBlock = u32, C: 'a + BitContainer = Vec> { + pub(crate) vec: Rc>>, + range: ops::Range, +} + +impl<'a, C: BitContainer> Iterator for IterMut<'a, C::Block, C> { + type Item = MutBorrowedBit<'a, C::Block, C>; + + #[inline] + fn next(&mut self) -> Option { + let index = self.range.next(); + self.get(index) + } + + fn size_hint(&self) -> (usize, Option) { + self.range.size_hint() + } +} + +impl DoubleEndedIterator for IterMut<'_, C::Block, C> { + #[inline] + fn next_back(&mut self) -> Option { + let index = self.range.next_back(); + self.get(index) + } +} + +impl ExactSizeIterator for IterMut<'_, C::Block, C> {} + +#[derive(Debug)] +pub struct MutBorrowedBit<'a, B: 'a + BitBlock, C: 'a + BitContainer = Vec> { + vec: Rc>>, + index: usize, + #[cfg(debug_assertions)] + old_value: bool, + new_value: bool, +} + +impl ops::Deref for MutBorrowedBit<'_, C::Block, C> { + type Target = bool; + + fn deref(&self) -> &Self::Target { + &self.new_value + } +} + +impl ops::DerefMut for MutBorrowedBit<'_, C::Block, C> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.new_value + } +} + +impl<'a, B: 'a + BitBlock, C: 'a + BitContainer> Drop for MutBorrowedBit<'a, B, C> { + fn drop(&mut self) { + let mut vec = (*self.vec).borrow_mut(); + #[cfg(debug_assertions)] + debug_assert_eq!( + Some(self.old_value), + vec.get(self.index), + "Mutably-borrowed bit was modified externally!" + ); + vec.set(self.index, self.new_value); + } +} + +impl<'a, C: 'a + BitContainer> IterMut<'a, C::Block, C> { + fn get(&mut self, index: Option) -> Option> { + let value = (*self.vec).borrow().get(index?)?; + Some(MutBorrowedBit { + vec: self.vec.clone(), + index: index?, + #[cfg(debug_assertions)] + old_value: value, + new_value: value, + }) + } +} + +impl BitVec { + /// Retrieves a smart pointer to the value at index `i`, or `None` if the index is out of bounds. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::from_bytes(&[0b01100000]); + /// *bv.get_mut(0).unwrap() = true; + /// *bv.get_mut(1).unwrap() = false; + /// assert!(bv.get_mut(100).is_none()); + /// assert_eq!(bv, BitVec::from_bytes(&[0b10100000])); + /// ``` + #[inline] + pub fn get_mut(&mut self, index: usize) -> Option> { + self.get(index).map(move |value| MutBorrowedBit { + vec: Rc::new(RefCell::new(self)), + index, + #[cfg(debug_assertions)] + old_value: value, + new_value: value, + }) + } + + /// Retrieves a smart pointer to the value at index `i`, without doing bounds checking. + /// + /// # Safety + /// + /// Calling this method with out-of-bounds `index` may cause undefined behavior even when + /// the result is not used. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::from_bytes(&[0b01100000]); + /// unsafe { + /// *bv.get_unchecked_mut(0) = true; + /// *bv.get_unchecked_mut(1) = false; + /// } + /// assert_eq!(bv, BitVec::from_bytes(&[0b10100000])); + /// ``` + #[inline] + pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> MutBorrowedBit<'_, C::Block, C> { + let value = self.get_unchecked(index); + MutBorrowedBit { + #[cfg(debug_assertions)] + old_value: value, + new_value: value, + vec: Rc::new(RefCell::new(self)), + index, + } + } + + /// Returns an iterator over mutable smart pointers to the elements of the vector in order. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut a = BitVec::from_elem(8, false); + /// a.iter_mut().enumerate().for_each(|(index, mut bit)| { + /// *bit = if index % 2 == 1 { true } else { false }; + /// }); + /// assert!(a.eq_vec(&[ + /// false, true, false, true, false, true, false, true + /// ])); + /// ``` + #[inline] + pub fn iter_mut(&mut self) -> IterMut<'_, C::Block, C> { + self.ensure_invariant(); + let nbits = self.nbits; + IterMut { + vec: Rc::new(RefCell::new(self)), + range: 0..nbits, + } + } +} diff --git a/vec/src/store.rs b/vec/src/store.rs new file mode 100644 index 0000000..825922f --- /dev/null +++ b/vec/src/store.rs @@ -0,0 +1,263 @@ +use crate::local_prelude::*; + +#[allow(clippy::len_without_is_empty)] +pub trait BitStore: Clone { + type Block: BitBlock; + type Alloc: Default; + fn new_in(alloc: Self::Alloc) -> Self; + fn slice(&self) -> &[Self::Block]; + fn slice_mut(&mut self) -> &mut [Self::Block]; + fn len(&self) -> usize { + self.slice().len() + } + fn pop(&mut self) -> Option; + fn drain>(&mut self, range: R) -> impl Iterator; + fn capacity(&self) -> usize; + fn append(&mut self, other: &mut Self); + fn reserve(&mut self, additional: usize); + fn push(&mut self, value: Self::Block); + fn split_off(&mut self, at: usize) -> Self; + fn truncate(&mut self, len: usize); + fn reserve_exact(&mut self, len: usize); + fn shrink_to_fit(&mut self); + fn extend(&mut self, iter: T) + where + T: IntoIterator; + fn with_capacity(capacity: usize) -> Self; + fn clear(&mut self); + fn with_capacity_in(capacity: usize, alloc: Self::Alloc) -> Self; +} + +#[cfg(not(feature = "allocator_api"))] +impl BitStore for Vec { + type Block = T; + type Alloc = (); + + fn new_in(_alloc: Self::Alloc) -> Self { + Vec::new() + } + + fn slice(&self) -> &[Self::Block] { + &self[..] + } + + fn slice_mut(&mut self) -> &mut [Self::Block] { + &mut self[..] + } + + fn pop(&mut self) -> Option { + Vec::pop(self) + } + + fn drain>(&mut self, range: R) -> impl Iterator { + Vec::drain(self, range) + } + + fn capacity(&self) -> usize { + Vec::capacity(self) + } + + fn append(&mut self, other: &mut Self) { + Vec::append(self, other); + } + + fn reserve(&mut self, additional: usize) { + Vec::reserve(self, additional); + } + + fn push(&mut self, value: Self::Block) { + Vec::push(self, value); + } + + fn split_off(&mut self, at: usize) -> Self { + Vec::split_off(self, at) + } + + fn truncate(&mut self, len: usize) { + Vec::truncate(self, len); + } + + fn reserve_exact(&mut self, len: usize) { + Vec::reserve_exact(self, len); + } + + fn shrink_to_fit(&mut self) { + Vec::shrink_to_fit(self); + } + + fn extend(&mut self, iter: I) + where + I: IntoIterator, + { + Extend::extend(self, iter); + } + + fn with_capacity_in(capacity: usize, _alloc: Self::Alloc) -> Self { + Vec::with_capacity(capacity) + } + + fn with_capacity(capacity: usize) -> Self { + Vec::with_capacity(capacity) + } + + fn clear(&mut self) { + Vec::clear(self) + } +} + +#[cfg(feature = "allocator_api")] +impl BitStore for Vec +where + A: core::alloc::Allocator + Clone + Default, +{ + type Block = T; + type Alloc = A; + + fn new_in(alloc: Self::Alloc) -> Self { + Vec::new_in(alloc) + } + + fn slice(&self) -> &[Self::Block] { + &self[..] + } + + fn slice_mut(&mut self) -> &mut [Self::Block] { + &mut self[..] + } + + fn pop(&mut self) -> Option { + Vec::pop(self) + } + + fn drain>(&mut self, range: R) -> impl Iterator { + Vec::drain(self, range) + } + + fn capacity(&self) -> usize { + Vec::capacity(self) + } + + fn append(&mut self, other: &mut Self) { + Vec::append(self, other); + } + + fn reserve(&mut self, additional: usize) { + Vec::reserve(self, additional); + } + + fn push(&mut self, value: Self::Block) { + Vec::push(self, value); + } + + fn split_off(&mut self, at: usize) -> Self { + Vec::split_off(self, at) + } + + fn truncate(&mut self, len: usize) { + Vec::truncate(self, len); + } + + fn reserve_exact(&mut self, len: usize) { + Vec::reserve_exact(self, len); + } + + fn shrink_to_fit(&mut self) { + Vec::shrink_to_fit(self); + } + + fn extend(&mut self, iter: I) + where + I: IntoIterator, + { + Extend::extend(self, iter); + } + + fn with_capacity_in(capacity: usize, alloc: A) -> Self { + Vec::with_capacity_in(capacity, alloc) + } + + fn with_capacity(capacity: usize) -> Self { + Vec::with_capacity_in(capacity, A::default()) + } +} + +#[cfg(feature = "smallvec")] +impl BitStore for smallvec::SmallVec +where + A::Item: BitBlock, +{ + type Block = A::Item; + type Alloc = (); + + fn slice(&self) -> &[Self::Block] { + &self[..] + } + + fn slice_mut(&mut self) -> &mut [Self::Block] { + &mut self[..] + } + + fn pop(&mut self) -> Option { + self.pop() + } + + fn drain>(&mut self, range: R) -> impl Iterator { + self.drain(range) + } + + fn capacity(&self) -> usize { + self.capacity() + } + + fn append(&mut self, other: &mut Self) { + self.append(other); + } + + fn reserve(&mut self, additional: usize) { + self.reserve(additional); + } + + fn push(&mut self, value: Self::Block) { + self.push(value); + } + + fn split_off(&mut self, at: usize) -> Self { + // TODO + self.to_vec().split_off(at).into() + } + + fn truncate(&mut self, len: usize) { + self.truncate(len); + } + + fn reserve_exact(&mut self, len: usize) { + self.reserve_exact(len); + } + + fn shrink_to_fit(&mut self) { + self.shrink_to_fit(); + } + + fn extend(&mut self, iter: I) + where + I: IntoIterator, + { + iter::Extend::extend(self, iter); + } + + fn with_capacity(capacity: usize) -> Self { + smallvec::SmallVec::with_capacity(capacity) + } + + fn clear(&mut self) { + self.clear(); + } + + fn new_in(_alloc: ()) -> Self { + smallvec::SmallVec::new() + } + + fn with_capacity_in(capacity: usize, _alloc: ()) -> Self { + smallvec::SmallVec::with_capacity(capacity) + } +} diff --git a/vec/src/vec.rs b/vec/src/vec.rs new file mode 100644 index 0000000..06e9285 --- /dev/null +++ b/vec/src/vec.rs @@ -0,0 +1,1758 @@ +use crate::local_prelude::*; +use crate::util; +use core::cmp::Ordering; +use core::fmt::Write; +use core::{cmp, fmt, hash, iter, mem, ops}; + +/// The bitvector type. +/// +/// # Examples +/// +/// ``` +/// use bit_vec::BitVec; +/// +/// let mut bv = BitVec::from_elem(10, false); +/// +/// // insert all primes less than 10 +/// bv.set(2, true); +/// bv.set(3, true); +/// bv.set(5, true); +/// bv.set(7, true); +/// println!("{:?}", bv); +/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count()); +/// +/// // flip all values in bitvector, producing non-primes less than 10 +/// bv.negate(); +/// println!("{:?}", bv); +/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count()); +/// +/// // reset bitvector to empty +/// bv.fill(false); +/// println!("{:?}", bv); +/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count()); +/// ``` +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize))] +#[cfg_attr(feature = "miniserde", derive(miniserde::Serialize))] +pub struct BitVec = Vec> { + /// Internal representation of the bit vector + pub(crate) storage: C, + /// The number of valid bits in the internal representation + pub(crate) nbits: usize, +} + +// FIXME(Gankro): NopeNopeNopeNopeNope (wait for IndexGet to be a thing) +impl ops::Index for BitVec { + type Output = bool; + + #[inline] + fn index(&self, i: usize) -> &bool { + if self.get(i).expect("index out of bounds") { + &true + } else { + &false + } + } +} + +/// Computes how many blocks are needed to store that many bits +fn blocks_for_bits(bits: usize) -> usize { + // If we want 17 bits, dividing by 32 will produce 0. So we add 1 to make sure we + // reserve enough. But if we want exactly a multiple of 32, this will actually allocate + // one too many. So we need to check if that's the case. We can do that by computing if + // bitwise AND by `32 - 1` is 0. But LLVM should be able to optimize the semantically + // superior modulo operator on a power of two to this. + // + // Note that we can technically avoid this branch with the expression + // `(nbits + U32_BITS - 1) / 32::BITS`, but if nbits is almost usize::MAX this will overflow. + if bits % B::BITS == 0 { + bits / B::BITS + } else { + bits / B::BITS + 1 + } +} + +/// Computes the bitmask for the final word of the vector +fn mask_for_bits(bits: usize) -> B { + // Note especially that a perfect multiple of U32_BITS should mask all 1s. + (!B::ZERO) >> ((B::BITS - bits % B::BITS) % B::BITS) +} + +impl BitVec { + /// Creates an empty `BitVec`. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// let mut bv = BitVec::new(); + /// ``` + #[inline] + pub fn new() -> Self { + Default::default() + } + + /// Creates a `BitVec` that holds `nbits` elements, setting each element + /// to `bit`. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::from_elem(10, false); + /// assert_eq!(bv.len(), 10); + /// for x in bv.iter() { + /// assert_eq!(x, false); + /// } + /// ``` + #[inline] + pub fn from_elem(len: usize, bit: bool) -> Self { + BitVec::::from_elem_general(len, bit) + } + + /// Constructs a new, empty `BitVec` with the specified capacity. + /// + /// The bitvector will be able to hold at least `capacity` bits without + /// reallocating. If `capacity` is 0, it will not allocate. + /// + /// It is important to note that this function does not specify the + /// *length* of the returned bitvector, but only the *capacity*. + #[inline] + pub fn with_capacity(capacity: usize) -> Self { + BitVec::::with_capacity_general(capacity) + } + + /// Transforms a byte-vector into a `BitVec`. Each byte becomes eight bits, + /// with the most significant bits of each byte coming first. Each + /// bit becomes `true` if equal to 1 or `false` if equal to 0. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let bv = BitVec::from_bytes(&[0b10100000, 0b00010010]); + /// assert!(bv.eq_vec(&[true, false, true, false, + /// false, false, false, false, + /// false, false, false, true, + /// false, false, true, false])); + /// ``` + pub fn from_bytes(bytes: &[u8]) -> Self { + BitVec::::from_bytes_general(bytes) + } + + /// Creates a `BitVec` of the specified length where the value at each index + /// is `f(index)`. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let bv = BitVec::from_fn(5, |i| { i % 2 == 0 }); + /// assert!(bv.eq_vec(&[true, false, true, false, true])); + /// ``` + #[inline] + pub fn from_fn(len: usize, f: F) -> Self + where + F: FnMut(usize) -> bool, + { + BitVec::::from_fn_general(len, f) + } +} + +impl BitVec { + /// Creates an empty `BitVec`. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// let mut bv = BitVec::::new_general(); + /// ``` + #[inline] + pub fn new_general() -> Self { + Default::default() + } + + /// Creates an empty `BitVec` using the provided allocator. + #[inline] + pub fn new_general_in(alloc: C::Alloc) -> Self { + Self::with_capacity_general_in(0, alloc) + } + + /// Creates a `BitVec` that holds `nbits` elements, setting each element + /// to `bit`. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::::from_elem_general(10, false); + /// assert_eq!(bv.len(), 10); + /// for x in bv.iter() { + /// assert_eq!(x, false); + /// } + /// ``` + #[inline] + pub fn from_elem_general(len: usize, bit: bool) -> Self { + let nblocks = blocks_for_bits::(len); + let mut storage: C = C::with_capacity(nblocks); + storage.extend(iter::repeat_n( + if bit { !C::ZERO } else { C::ZERO }, + nblocks, + )); + let mut bit_vec = BitVec { + storage, + nbits: len, + }; + bit_vec.fix_last_block(); + bit_vec + } + + /// Constructs a new, empty `BitVec` with the specified capacity. + /// + /// The bitvector will be able to hold at least `capacity` bits without + /// reallocating. If `capacity` is 0, it will not allocate. + /// + /// It is important to note that this function does not specify the + /// *length* of the returned bitvector, but only the *capacity*. + #[inline] + pub fn with_capacity_general(capacity: usize) -> Self { + BitVec { + storage: C::with_capacity(blocks_for_bits::(capacity)), + nbits: 0, + } + } + + /// Constructs a new, empty `BitVec` with the specified capacity. + /// + /// The bitvector will be able to hold at least `capacity` bits without + /// reallocating. If `capacity` is 0, it will not allocate. + /// + /// It is important to note that this function does not specify the + /// *length* of the returned bitvector, but only the *capacity*. + #[inline] + pub fn with_capacity_general_in(capacity: usize, alloc: C::Alloc) -> Self { + BitVec { + storage: C::with_capacity_in(blocks_for_bits::(capacity), alloc), + nbits: 0, + } + } + + /// Transforms a byte-vector into a `BitVec`. Each byte becomes eight bits, + /// with the most significant bits of each byte coming first. Each + /// bit becomes `true` if equal to 1 or `false` if equal to 0. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let bv = BitVec::::from_bytes_general(&[0b10100000, 0b00010010]); + /// assert!(bv.eq_vec(&[true, false, true, false, + /// false, false, false, false, + /// false, false, false, true, + /// false, false, true, false])); + /// ``` + pub fn from_bytes_general(bytes: &[u8]) -> Self { + let len = bytes + .len() + .checked_mul(u8::BITS as usize) + .expect("capacity overflow"); + let mut bit_vec = BitVec::::with_capacity_general(len); + let complete_words = bytes.len() / C::BYTES; + let extra_bytes = bytes.len() % C::BYTES; + + bit_vec.nbits = len; + + for i in 0..complete_words { + let mut accumulator = C::ZERO; + for idx in 0..C::BYTES { + accumulator |= + C::Block::from_byte(util::reverse_bits(bytes[i * C::BYTES + idx])) << (idx * 8) + } + bit_vec.storage.push(accumulator); + } + + if extra_bytes > 0 { + let mut last_word = C::ZERO; + for (i, &byte) in bytes[complete_words * C::BYTES..].iter().enumerate() { + last_word |= C::Block::from_byte(util::reverse_bits(byte)) << (i * 8); + } + bit_vec.storage.push(last_word); + } + + bit_vec + } + + /// Creates a `BitVec` of the specified length where the value at each index + /// is `f(index)`. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let bv = BitVec::::from_fn_general(5, |i| { i % 2 == 0 }); + /// assert!(bv.eq_vec(&[true, false, true, false, true])); + /// ``` + #[inline] + pub fn from_fn_general(len: usize, mut f: F) -> Self + where + F: FnMut(usize) -> bool, + { + let mut bit_vec = BitVec::from_elem_general(len, false); + for i in 0..len { + bit_vec.set(i, f(i)); + } + bit_vec + } + + /// Applies the given operation to the blocks of self and other, and sets + /// self to be the result. This relies on the caller not to corrupt the + /// last word. + #[inline] + fn process(&mut self, other: &BitVec, mut op: F) -> bool + where + F: FnMut(C::Block, C::Block) -> C::Block, + { + assert_eq!(self.len(), other.len()); + debug_assert_eq!(self.storage.len(), other.storage.len()); + let mut changed_bits = C::ZERO; + for (a, b) in self.blocks_mut().zip(other.blocks()) { + let w = op(*a, b); + changed_bits |= *a ^ w; + *a = w; + } + changed_bits != C::ZERO + } + + /// Exposes the raw block storage of this `BitVec`. + /// + /// Only really intended for `BitSet`. + #[inline] + pub fn storage(&self) -> &[C::Block] { + self.storage.slice() + } + + /// Exposes the raw block storage of this `BitVec`. + /// + /// # Safety + /// + /// Can probably cause unsafety. Only really intended for `BitSet`. + #[inline] + pub unsafe fn storage_mut(&mut self) -> &mut C { + &mut self.storage + } + + /// Helper for procedures involving spare space in the last block. + #[inline] + fn last_block_with_mask(&self) -> Option<(C::Block, C::Block)> { + let extra_bits = self.len() % C::BITS; + if extra_bits > 0 { + let mask = (C::ONE << extra_bits) - C::ONE; + let storage_len = self.storage.len(); + Some((self.storage.slice()[storage_len - 1], mask)) + } else { + None + } + } + + /// Helper for procedures involving spare space in the last block. + #[inline] + fn last_block_mut_with_mask(&mut self) -> Option<(&mut C::Block, C::Block)> { + let extra_bits = self.len() % C::BITS; + if extra_bits > 0 { + let mask = (C::ONE << extra_bits) - C::ONE; + let storage_len = self.storage.len(); + Some((&mut self.storage.slice_mut()[storage_len - 1], mask)) + } else { + None + } + } + + /// An operation might screw up the unused bits in the last block of the + /// `BitVec`. As per (3), it's assumed to be all 0s. This method fixes it up. + fn fix_last_block(&mut self) { + if let Some((last_block, used_bits)) = self.last_block_mut_with_mask() { + *last_block = *last_block & used_bits; + } + } + + /// Operations such as change detection for xnor, nor and nand are easiest + /// to implement when unused bits are all set to 1s. + fn fix_last_block_with_ones(&mut self) { + if let Some((last_block, used_bits)) = self.last_block_mut_with_mask() { + *last_block |= !used_bits; + } + } + + /// Check whether last block's invariant is fine. + pub(crate) fn is_last_block_fixed(&self) -> bool { + if let Some((last_block, used_bits)) = self.last_block_with_mask() { + last_block & !used_bits == C::ZERO + } else { + true + } + } + + /// Checks whether our `nbits` fits within our storage. + pub(crate) fn storage_len_matches_nbits(&self) -> bool { + self.storage.len() == blocks_for_bits::(self.nbits) + } + + /// Ensure the invariant for the last block. + /// + /// An operation might screw up the unused bits in the last block of the + /// `BitVec`. + /// + /// This method fails in case the last block is not fixed. The check + /// is skipped outside testing. + #[inline] + pub(crate) fn ensure_invariant(&self) { + if cfg!(test) { + debug_assert!(self.storage_len_matches_nbits()); + debug_assert!(self.is_last_block_fixed()); + } + } + + /// Retrieves the value at index `i`, or `None` if the index is out of bounds. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let bv = BitVec::from_bytes(&[0b01100000]); + /// assert_eq!(bv.get(0), Some(false)); + /// assert_eq!(bv.get(1), Some(true)); + /// assert_eq!(bv.get(100), None); + /// + /// // Can also use array indexing + /// assert_eq!(bv[1], true); + /// ``` + #[inline] + pub fn get(&self, i: usize) -> Option { + self.ensure_invariant(); + if i >= self.nbits { + return None; + } + let w = i / C::BITS; + let b = i % C::BITS; + self.storage + .slice() + .get(w) + .map(|&block| (block & (C::ONE << b)) != C::ZERO) + } + + /// Retrieves the value at index `i`, without doing bounds checking. + /// + /// For a safe alternative, see `get`. + /// + /// # Safety + /// + /// Calling this method with an out-of-bounds index is undefined behavior + /// even if the resulting reference is not used. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let bv = BitVec::from_bytes(&[0b01100000]); + /// unsafe { + /// assert_eq!(bv.get_unchecked(0), false); + /// assert_eq!(bv.get_unchecked(1), true); + /// } + /// ``` + #[inline] + pub unsafe fn get_unchecked(&self, i: usize) -> bool { + self.ensure_invariant(); + let w = i / C::BITS; + let b = i % C::BITS; + let block = *self.storage.slice().get_unchecked(w); + block & (C::ONE << b) != C::ZERO + } + + /// Sets the value of a bit at an index `i`. + /// + /// # Panics + /// + /// Panics if `i` is out of bounds. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::from_elem(5, false); + /// bv.set(3, true); + /// assert_eq!(bv[3], true); + /// ``` + #[inline] + pub fn set(&mut self, i: usize, x: bool) { + self.ensure_invariant(); + assert!( + i < self.nbits, + "index out of bounds: {:?} >= {:?}", + i, + self.nbits + ); + let w = i / C::BITS; + let b = i % C::BITS; + let flag = C::ONE << b; + let val = if x { + self.storage.slice()[w] | flag + } else { + self.storage.slice()[w] & !flag + }; + self.storage.slice_mut()[w] = val; + } + + /// Sets all bits to 1. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let before = 0b01100000; + /// let after = 0b11111111; + /// + /// let mut bv = BitVec::from_bytes(&[before]); + /// bv.set_all(); + /// assert_eq!(bv, BitVec::from_bytes(&[after])); + /// ``` + #[inline] + #[deprecated(since = "0.9.0", note = "please use `.fill(true)` instead")] + pub fn set_all(&mut self) { + self.ensure_invariant(); + for w in self.storage.slice_mut() { + *w = !C::ZERO; + } + self.fix_last_block(); + } + + /// Flips all bits. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let before = 0b01100000; + /// let after = 0b10011111; + /// + /// let mut bv = BitVec::from_bytes(&[before]); + /// bv.negate(); + /// assert_eq!(bv, BitVec::from_bytes(&[after])); + /// ``` + #[inline] + pub fn negate(&mut self) { + self.ensure_invariant(); + for w in self.storage.slice_mut() { + *w = !*w; + } + self.fix_last_block(); + } + + /// Calculates the union of two bitvectors. This acts like the bitwise `or` + /// function. + /// + /// Sets `self` to the union of `self` and `other`. Both bitvectors must be + /// the same length. Returns `true` if `self` changed. + /// + /// # Panics + /// + /// Panics if the bitvectors are of different lengths. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let a = 0b01100100; + /// let b = 0b01011010; + /// let res = 0b01111110; + /// + /// let mut a = BitVec::from_bytes(&[a]); + /// let b = BitVec::from_bytes(&[b]); + /// + /// assert!(a.union(&b)); + /// assert_eq!(a, BitVec::from_bytes(&[res])); + /// ``` + #[deprecated(since = "0.7.0", note = "Please use the 'or' function instead")] + #[inline] + pub fn union(&mut self, other: &Self) -> bool { + self.or(other) + } + + /// Calculates the intersection of two bitvectors. This acts like the + /// bitwise `and` function. + /// + /// Sets `self` to the intersection of `self` and `other`. Both bitvectors + /// must be the same length. Returns `true` if `self` changed. + /// + /// # Panics + /// + /// Panics if the bitvectors are of different lengths. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let a = 0b01100100; + /// let b = 0b01011010; + /// let res = 0b01000000; + /// + /// let mut a = BitVec::from_bytes(&[a]); + /// let b = BitVec::from_bytes(&[b]); + /// + /// assert!(a.intersect(&b)); + /// assert_eq!(a, BitVec::from_bytes(&[res])); + /// ``` + #[deprecated(since = "0.7.0", note = "Please use the 'and' function instead")] + #[inline] + pub fn intersect(&mut self, other: &Self) -> bool { + self.and(other) + } + + /// Calculates the bitwise `or` of two bitvectors. + /// + /// Sets `self` to the union of `self` and `other`. Both bitvectors must be + /// the same length. Returns `true` if `self` changed. + /// + /// # Panics + /// + /// Panics if the bitvectors are of different lengths. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let a = 0b01100100; + /// let b = 0b01011010; + /// let res = 0b01111110; + /// + /// let mut a = BitVec::from_bytes(&[a]); + /// let b = BitVec::from_bytes(&[b]); + /// + /// assert!(a.or(&b)); + /// assert_eq!(a, BitVec::from_bytes(&[res])); + /// ``` + #[inline] + pub fn or(&mut self, other: &Self) -> bool { + self.ensure_invariant(); + debug_assert!(other.is_last_block_fixed()); + self.process(other, |w1, w2| w1 | w2) + } + + /// Calculates the bitwise `and` of two bitvectors. + /// + /// Sets `self` to the intersection of `self` and `other`. Both bitvectors + /// must be the same length. Returns `true` if `self` changed. + /// + /// # Panics + /// + /// Panics if the bitvectors are of different lengths. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let a = 0b01100100; + /// let b = 0b01011010; + /// let res = 0b01000000; + /// + /// let mut a = BitVec::from_bytes(&[a]); + /// let b = BitVec::from_bytes(&[b]); + /// + /// assert!(a.and(&b)); + /// assert_eq!(a, BitVec::from_bytes(&[res])); + /// ``` + #[inline] + pub fn and(&mut self, other: &Self) -> bool { + self.ensure_invariant(); + debug_assert!(other.is_last_block_fixed()); + self.process(other, |w1, w2| w1 & w2) + } + + /// Calculates the difference between two bitvectors. + /// + /// Sets each element of `self` to the value of that element minus the + /// element of `other` at the same index. Both bitvectors must be the same + /// length. Returns `true` if `self` changed. + /// + /// # Panics + /// + /// Panics if the bitvectors are of different length. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let a = 0b01100100; + /// let b = 0b01011010; + /// let a_b = 0b00100100; // a - b + /// let b_a = 0b00011010; // b - a + /// + /// let mut bva = BitVec::from_bytes(&[a]); + /// let bvb = BitVec::from_bytes(&[b]); + /// + /// assert!(bva.difference(&bvb)); + /// assert_eq!(bva, BitVec::from_bytes(&[a_b])); + /// + /// let bva = BitVec::from_bytes(&[a]); + /// let mut bvb = BitVec::from_bytes(&[b]); + /// + /// assert!(bvb.difference(&bva)); + /// assert_eq!(bvb, BitVec::from_bytes(&[b_a])); + /// ``` + #[inline] + pub fn difference(&mut self, other: &Self) -> bool { + self.ensure_invariant(); + debug_assert!(other.is_last_block_fixed()); + self.process(other, |w1, w2| w1 & !w2) + } + + /// Calculates the xor of two bitvectors. + /// + /// Sets `self` to the xor of `self` and `other`. Both bitvectors must be + /// the same length. Returns `true` if `self` changed. + /// + /// # Panics + /// + /// Panics if the bitvectors are of different length. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let a = 0b01100110; + /// let b = 0b01010100; + /// let res = 0b00110010; + /// + /// let mut a = BitVec::from_bytes(&[a]); + /// let b = BitVec::from_bytes(&[b]); + /// + /// assert!(a.xor(&b)); + /// assert_eq!(a, BitVec::from_bytes(&[res])); + /// ``` + #[inline] + pub fn xor(&mut self, other: &Self) -> bool { + self.ensure_invariant(); + debug_assert!(other.is_last_block_fixed()); + self.process(other, |w1, w2| w1 ^ w2) + } + + /// Calculates the nand of two bitvectors. + /// + /// Sets `self` to the nand of `self` and `other`. Both bitvectors must be + /// the same length. Returns `true` if `self` changed. + /// + /// # Panics + /// + /// Panics if the bitvectors are of different length. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let a = 0b01100110; + /// let b = 0b01010100; + /// let res = 0b10111011; + /// + /// let mut a = BitVec::from_bytes(&[a]); + /// let b = BitVec::from_bytes(&[b]); + /// + /// assert!(a.nand(&b)); + /// assert_eq!(a, BitVec::from_bytes(&[res])); + /// ``` + #[inline] + pub fn nand(&mut self, other: &Self) -> bool { + self.ensure_invariant(); + debug_assert!(other.is_last_block_fixed()); + self.fix_last_block_with_ones(); + let result = self.process(other, |w1, w2| !(w1 & w2)); + self.fix_last_block(); + result + } + + /// Calculates the nor of two bitvectors. + /// + /// Sets `self` to the nor of `self` and `other`. Both bitvectors must be + /// the same length. Returns `true` if `self` changed. + /// + /// # Panics + /// + /// Panics if the bitvectors are of different length. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let a = 0b01100110; + /// let b = 0b01010100; + /// let res = 0b10001001; + /// + /// let mut a = BitVec::from_bytes(&[a]); + /// let b = BitVec::from_bytes(&[b]); + /// + /// assert!(a.nor(&b)); + /// assert_eq!(a, BitVec::from_bytes(&[res])); + /// ``` + #[inline] + pub fn nor(&mut self, other: &Self) -> bool { + self.ensure_invariant(); + debug_assert!(other.is_last_block_fixed()); + self.fix_last_block_with_ones(); + let result = self.process(other, |w1, w2| !(w1 | w2)); + self.fix_last_block(); + result + } + + /// Calculates the xnor of two bitvectors. + /// + /// Sets `self` to the xnor of `self` and `other`. Both bitvectors must be + /// the same length. Returns `true` if `self` changed. + /// + /// # Panics + /// + /// Panics if the bitvectors are of different length. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let a = 0b01100110; + /// let b = 0b01010100; + /// let res = 0b11001101; + /// + /// let mut a = BitVec::from_bytes(&[a]); + /// let b = BitVec::from_bytes(&[b]); + /// + /// assert!(a.xnor(&b)); + /// assert_eq!(a, BitVec::from_bytes(&[res])); + /// ``` + #[inline] + pub fn xnor(&mut self, other: &Self) -> bool { + self.ensure_invariant(); + debug_assert!(other.is_last_block_fixed()); + self.fix_last_block_with_ones(); + let result = self.process(other, |w1, w2| !(w1 ^ w2)); + self.fix_last_block(); + result + } + + /// Returns `true` if all bits are 1. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::from_elem(5, true); + /// assert_eq!(bv.all(), true); + /// + /// bv.set(1, false); + /// assert_eq!(bv.all(), false); + /// ``` + #[inline] + pub fn all(&self) -> bool { + self.ensure_invariant(); + let mut last_word = !C::ZERO; + // Check that every block but the last is all-ones... + self.blocks().all(|elem| { + let tmp = last_word; + last_word = elem; + tmp == !C::ZERO + // and then check the last one has enough ones + }) && (last_word == mask_for_bits::(self.nbits)) + } + + /// Returns the number of ones in the binary representation. + /// + /// Also known as the + /// [Hamming weight](https://en.wikipedia.org/wiki/Hamming_weight). + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::from_elem(100, true); + /// assert_eq!(bv.count_ones(), 100); + /// + /// bv.set(50, false); + /// assert_eq!(bv.count_ones(), 99); + /// ``` + #[inline] + pub fn count_ones(&self) -> u64 { + self.ensure_invariant(); + // Add the number of ones of each block. + self.blocks().map(|elem| elem.count_ones() as u64).sum() + } + + /// Returns the number of zeros in the binary representation. + /// + /// Also known as the opposite of + /// [Hamming weight](https://en.wikipedia.org/wiki/Hamming_weight). + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::from_elem(100, false); + /// assert_eq!(bv.count_zeros(), 100); + /// + /// bv.set(50, true); + /// assert_eq!(bv.count_zeros(), 99); + /// ``` + #[inline] + pub fn count_zeros(&self) -> u64 { + self.ensure_invariant(); + // Add the number of zeros of each block. + let extra_zeros = (C::BITS - (self.len() % C::BITS)) % C::BITS; + self.blocks() + .map(|elem| elem.count_zeros() as u64) + .sum::() + - extra_zeros as u64 + } + + /// Moves all bits from `other` into `Self`, leaving `other` empty. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut a = BitVec::from_bytes(&[0b10000000]); + /// let mut b = BitVec::from_bytes(&[0b01100001]); + /// + /// a.append(&mut b); + /// + /// assert_eq!(a.len(), 16); + /// assert_eq!(b.len(), 0); + /// assert!(a.eq_vec(&[true, false, false, false, false, false, false, false, + /// false, true, true, false, false, false, false, true])); + /// ``` + pub fn append(&mut self, other: &mut Self) { + self.ensure_invariant(); + debug_assert!(other.is_last_block_fixed()); + + let b = self.len() % C::BITS; + let o = other.len() % C::BITS; + let will_overflow = (b + o > C::BITS) || (o == 0 && b != 0); + + self.nbits += other.len(); + other.nbits = 0; + + if b == 0 { + self.storage.append(&mut other.storage); + } else { + self.storage.reserve(other.storage.len()); + + for block in other.storage.drain(..) { + { + let last = self.storage.slice_mut().last_mut().unwrap(); + *last |= block << b; + } + self.storage.push(block >> (C::BITS - b)); + } + + // Remove additional block if the last shift did not overflow + if !will_overflow { + self.storage.pop(); + } + } + } + + /// Splits the `BitVec` into two at the given bit, + /// retaining the first half in-place and returning the second one. + /// + /// # Panics + /// + /// Panics if `at` is out of bounds. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// let mut a = BitVec::new(); + /// a.push(true); + /// a.push(false); + /// a.push(false); + /// a.push(true); + /// + /// let b = a.split_off(2); + /// + /// assert_eq!(a.len(), 2); + /// assert_eq!(b.len(), 2); + /// assert!(a.eq_vec(&[true, false])); + /// assert!(b.eq_vec(&[false, true])); + /// ``` + pub fn split_off(&mut self, at: usize) -> Self { + self.ensure_invariant(); + assert!(at <= self.len(), "`at` out of bounds"); + + let mut other = BitVec::::new_general(); + + if at == 0 { + mem::swap(self, &mut other); + return other; + } else if at == self.len() { + return other; + } + + let w = at / C::BITS; + let b = at % C::BITS; + other.nbits = self.nbits - at; + self.nbits = at; + if b == 0 { + // Split at block boundary + other.storage = self.storage.split_off(w); + } else { + other.storage.reserve(self.storage.len() - w); + + { + let mut iter = self.storage.slice()[w..].iter(); + let mut last = *iter.next().unwrap(); + for &cur in iter { + other.storage.push((last >> b) | (cur << (C::BITS - b))); + last = cur; + } + other.storage.push(last >> b); + } + + self.storage.truncate(w + 1); + self.fix_last_block(); + } + + other + } + + /// Returns `true` if all bits are 0. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::from_elem(10, false); + /// assert_eq!(bv.none(), true); + /// + /// bv.set(3, true); + /// assert_eq!(bv.none(), false); + /// ``` + #[inline] + pub fn none(&self) -> bool { + self.blocks().all(|w| w == C::ZERO) + } + + /// Returns `true` if any bit is 1. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::from_elem(10, false); + /// assert_eq!(bv.any(), false); + /// + /// bv.set(3, true); + /// assert_eq!(bv.any(), true); + /// ``` + #[inline] + pub fn any(&self) -> bool { + !self.none() + } + + /// Organises the bits into bytes, such that the first bit in the + /// `BitVec` becomes the high-order bit of the first byte. If the + /// size of the `BitVec` is not a multiple of eight then trailing bits + /// will be filled-in with `false`. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::from_elem(3, true); + /// bv.set(1, false); + /// + /// assert_eq!(bv.to_bytes(), [0b10100000]); + /// + /// let mut bv = BitVec::from_elem(9, false); + /// bv.set(2, true); + /// bv.set(8, true); + /// + /// assert_eq!(bv.to_bytes(), [0b00100000, 0b10000000]); + /// ``` + pub fn to_bytes(&self) -> Vec { + static REVERSE_TABLE: [u8; 256] = { + let mut tbl = [0u8; 256]; + let mut i: u8 = 0; + loop { + tbl[i as usize] = i.reverse_bits(); + if i == 255 { + break; + } + i += 1; + } + tbl + }; + self.ensure_invariant(); + + let len = self.nbits / 8 + if self.nbits % 8 == 0 { 0 } else { 1 }; + let mut result = Vec::with_capacity(len); + + for byte_idx in 0..len { + let mut byte = 0u8; + for bit_idx in 0..8 { + let offset = byte_idx * 8 + bit_idx; + if offset < self.nbits && self[offset] { + byte |= 1 << bit_idx; + } + } + result.push(REVERSE_TABLE[byte as usize]); + } + + result + } + + /// Compares a `BitVec` to a slice of `bool`s. + /// Both the `BitVec` and slice must have the same length. + /// + /// # Panics + /// + /// Panics if the `BitVec` and slice are of different length. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let bv = BitVec::from_bytes(&[0b10100000]); + /// + /// assert!(bv.eq_vec(&[true, false, true, false, + /// false, false, false, false])); + /// ``` + #[inline] + pub fn eq_vec(&self, v: &[bool]) -> bool { + assert_eq!(self.nbits, v.len()); + self.iter().zip(v.iter().cloned()).all(|(b1, b2)| b1 == b2) + } + + /// Shortens a `BitVec`, dropping excess elements. + /// + /// If `len` is greater than the vector's current length, this has no + /// effect. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::from_bytes(&[0b01001011]); + /// bv.truncate(2); + /// assert!(bv.eq_vec(&[false, true])); + /// ``` + #[inline] + pub fn truncate(&mut self, len: usize) { + self.ensure_invariant(); + if len < self.len() { + self.nbits = len; + // This fixes (2). + self.storage.truncate(blocks_for_bits::(len)); + self.fix_last_block(); + } + } + + /// Reserves capacity for at least `additional` more bits to be inserted in the given + /// `BitVec`. The collection may reserve more space to avoid frequent reallocations. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `usize`. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::from_elem(3, false); + /// bv.reserve(10); + /// assert_eq!(bv.len(), 3); + /// assert!(bv.capacity() >= 13); + /// ``` + #[inline] + pub fn reserve(&mut self, additional: usize) { + let desired_cap = self + .len() + .checked_add(additional) + .expect("capacity overflow"); + let storage_len = self.storage.len(); + if desired_cap > self.capacity() { + self.storage + .reserve(blocks_for_bits::(desired_cap) - storage_len); + } + } + + /// Reserves the minimum capacity for exactly `additional` more bits to be inserted in the + /// given `BitVec`. Does nothing if the capacity is already sufficient. + /// + /// Note that the allocator may give the collection more space than it requests. Therefore + /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future + /// insertions are expected. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `usize`. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::from_elem(3, false); + /// bv.reserve(10); + /// assert_eq!(bv.len(), 3); + /// assert!(bv.capacity() >= 13); + /// ``` + #[inline] + pub fn reserve_exact(&mut self, additional: usize) { + let desired_cap = self + .len() + .checked_add(additional) + .expect("capacity overflow"); + let storage_len = self.storage.len(); + if desired_cap > self.capacity() { + self.storage + .reserve_exact(blocks_for_bits::(desired_cap) - storage_len); + } + } + + /// Returns the capacity in bits for this bit vector. Inserting any + /// element less than this amount will not trigger a resizing. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::new(); + /// bv.reserve(10); + /// assert!(bv.capacity() >= 10); + /// ``` + #[inline] + pub fn capacity(&self) -> usize { + self.storage.capacity().saturating_mul(C::BITS) + } + + /// Grows the `BitVec` in-place, adding `n` copies of `value` to the `BitVec`. + /// + /// # Panics + /// + /// Panics if the new len overflows a `usize`. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::from_bytes(&[0b01001011]); + /// bv.grow(2, true); + /// assert_eq!(bv.len(), 10); + /// assert_eq!(bv.to_bytes(), [0b01001011, 0b11000000]); + /// ``` + pub fn grow(&mut self, n: usize, value: bool) { + self.ensure_invariant(); + + // Note: we just bulk set all the bits in the last word in this fn in multiple places + // which is technically wrong if not all of these bits are to be used. However, at the end + // of this fn we call `fix_last_block` at the end of this fn, which should fix this. + + let new_nbits = self.nbits.checked_add(n).expect("capacity overflow"); + let new_nblocks = blocks_for_bits::(new_nbits); + let full_value = if value { !C::ZERO } else { C::ZERO }; + + // Correct the old tail word, setting or clearing formerly unused bits + let num_cur_blocks = blocks_for_bits::(self.nbits); + if self.nbits % C::BITS > 0 { + let mask = mask_for_bits::(self.nbits); + if value { + let block = &mut self.storage.slice_mut()[num_cur_blocks - 1]; + *block |= !mask; + } else { + // Extra bits are already zero by invariant. + } + } + + // Fill in words after the old tail word + let stop_idx = cmp::min(self.storage.len(), new_nblocks); + for idx in num_cur_blocks..stop_idx { + self.storage.slice_mut()[idx] = full_value; + } + + // Allocate new words, if needed + if new_nblocks > self.storage.len() { + let to_add = new_nblocks - self.storage.len(); + self.storage.extend(iter::repeat_n(full_value, to_add)); + } + + // Adjust internal bit count + self.nbits = new_nbits; + + self.fix_last_block(); + } + + /// Removes the last bit from the `BitVec`, and returns it. Returns `None` if the `BitVec` is empty. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::from_bytes(&[0b01001001]); + /// assert_eq!(bv.pop(), Some(true)); + /// assert_eq!(bv.pop(), Some(false)); + /// assert_eq!(bv.len(), 6); + /// ``` + #[inline] + pub fn pop(&mut self) -> Option { + self.ensure_invariant(); + + if self.is_empty() { + None + } else { + let i = self.nbits - 1; + let ret = self[i]; + // (3) + self.set(i, false); + self.nbits = i; + if self.nbits % C::BITS == 0 { + // (2) + self.storage.pop(); + } + Some(ret) + } + } + + /// Pushes a `bool` onto the end. + /// + /// # Examples + /// + /// ``` + /// use bit_vec::BitVec; + /// + /// let mut bv = BitVec::new(); + /// bv.push(true); + /// bv.push(false); + /// assert!(bv.eq_vec(&[true, false])); + /// ``` + #[inline] + pub fn push(&mut self, elem: bool) { + if self.nbits % C::BITS == 0 { + self.storage.push(C::ZERO); + } + let insert_pos = self.nbits; + self.nbits = self.nbits.checked_add(1).expect("Capacity overflow"); + self.set(insert_pos, elem); + } + + /// Returns the total number of bits in this vector + #[inline] + pub fn len(&self) -> usize { + self.nbits + } + + /// Sets the number of bits that this `BitVec` considers initialized. + /// + /// # Safety + /// + /// Almost certainly can cause bad stuff. Only really intended for `BitSet`. + #[inline] + pub unsafe fn set_len(&mut self, len: usize) { + self.nbits = len; + } + + /// Returns true if there are no bits in this vector + #[inline] + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Clears all bits in this vector. + #[inline] + #[deprecated(since = "0.9.0", note = "please use `.fill(false)` instead")] + pub fn clear(&mut self) { + self.ensure_invariant(); + for w in self.storage.slice_mut() { + *w = C::ZERO; + } + } + + /// Assigns all bits in this vector to the given boolean value. + /// + /// # Invariants + /// + /// - After a call to `.fill(true)`, the result of [`all`] is `true`. + /// - After a call to `.fill(false)`, the result of [`none`] is `true`. + /// + /// [`all`]: Self::all + /// [`none`]: Self::none + #[inline] + pub fn fill(&mut self, bit: bool) { + self.ensure_invariant(); + let block = if bit { !C::ZERO } else { C::ZERO }; + for w in self.storage.slice_mut() { + *w = block; + } + if bit { + self.fix_last_block(); + } + } + + /// Shrinks the capacity of the underlying storage as much as + /// possible. + /// + /// It will drop down as close as possible to the length but the + /// allocator may still inform the underlying storage that there + /// is space for a few more elements/bits. + pub fn shrink_to_fit(&mut self) { + self.storage.shrink_to_fit(); + } + + /// Inserts a given bit at index `at`, shifting all bits after by one + /// + /// # Panics + /// Panics if `at` is out of bounds for `BitVec`'s length (that is, if `at > BitVec::len()`) + /// + /// # Examples + ///``` + /// use bit_vec::BitVec; + /// + /// let mut b = BitVec::new(); + /// + /// b.push(true); + /// b.push(true); + /// b.insert(1, false); + /// + /// assert!(b.eq_vec(&[true, false, true])); + ///``` + /// + /// # Time complexity + /// Takes O([`len`]) time. All items after the insertion index must be + /// shifted to the right. In the worst case, all elements are shifted when + /// the insertion index is 0. + /// + /// [`len`]: Self::len + pub fn insert(&mut self, at: usize, bit: bool) { + assert!( + at <= self.nbits, + "insertion index (is {at}) should be <= len (is {nbits})", + nbits = self.nbits + ); + self.ensure_invariant(); + + let last_block_bits = self.nbits % C::BITS; + let block_at = at / C::BITS; // needed block + let bit_at = at % C::BITS; // index within the block + + if last_block_bits == 0 { + self.storage.push(C::ZERO); + } + + self.nbits += 1; + + let mut carry = self.storage.slice()[block_at] >> (C::BITS - 1); + let lsbits_mask = (C::ONE << bit_at) - C::ONE; + let set_bit = if bit { C::ONE } else { C::ZERO } << bit_at; + self.storage.slice_mut()[block_at] = (self.storage.slice()[block_at] & lsbits_mask) + | ((self.storage.slice()[block_at] & !lsbits_mask) << 1) + | set_bit; + + for block_ref in &mut self.storage.slice_mut()[block_at + 1..] { + let curr_carry = *block_ref >> (C::BITS - 1); + *block_ref = *block_ref << 1 | carry; + carry = curr_carry; + } + } + + /// Remove a bit at index `at`, shifting all bits after by one. + /// + /// # Panics + /// Panics if `at` is out of bounds for `BitVec`'s length (that is, if `at >= BitVec::len()`) + /// + /// # Examples + ///``` + /// use bit_vec::BitVec; + /// + /// let mut b = BitVec::new(); + /// + /// b.push(true); + /// b.push(false); + /// b.push(false); + /// b.push(true); + /// assert!(!b.remove(1)); + /// + /// assert!(b.eq_vec(&[true, false, true])); + ///``` + /// + /// # Time complexity + /// Takes O([`len`]) time. All items after the removal index must be + /// shifted to the left. In the worst case, all elements are shifted when + /// the removal index is 0. + /// + /// [`len`]: Self::len + pub fn remove(&mut self, at: usize) -> bool { + assert!( + at < self.nbits, + "removal index (is {at}) should be < len (is {nbits})", + nbits = self.nbits + ); + self.ensure_invariant(); + + self.nbits -= 1; + + let last_block_bits = self.nbits % C::BITS; + let block_at = at / C::BITS; // needed block + let bit_at = at % C::BITS; // index within the block + + let lsbits_mask = (C::ONE << bit_at) - C::ONE; + + let mut carry = C::ZERO; + + for block_ref in self.storage.slice_mut()[block_at + 1..].iter_mut().rev() { + let curr_carry = *block_ref & C::ONE; + *block_ref = *block_ref >> 1 | (carry << (C::BITS - 1)); + carry = curr_carry; + } + + // Note: this is equivalent to `.get_unchecked(at)`, but we do + // not want to introduce unsafe code here. + let result = (self.storage.slice()[block_at] >> bit_at) & C::ONE == C::ONE; + + self.storage.slice_mut()[block_at] = (self.storage.slice()[block_at] & lsbits_mask) + | ((self.storage.slice()[block_at] & (!lsbits_mask << 1)) >> 1) + | carry << (C::BITS - 1); + + if last_block_bits == 0 { + self.storage.pop(); + } + + result + } + + /// Removes all bits in this vector. + /// + /// Note: this method is not named [`clear`] to avoid confusion whenever [`.fill(false)`] + /// is needed. + /// + /// [`clear`]: Self::clear + /// [`.fill(false)`]: Self::fill + pub fn remove_all(&mut self) { + self.storage.clear(); + self.nbits = 0; + } + + /// Appends an element if there is sufficient spare capacity, otherwise an error is returned + /// with the element. + /// + /// Unlike [`push`] this method will not reallocate when there's insufficient capacity. + /// The caller should use [`reserve`] to ensure that there is enough capacity. + /// + /// [`push`]: Self::push + /// [`reserve`]: Self::reserve + /// + /// # Examples + /// ``` + /// use bit_vec::BitVec; + /// + /// let initial_capacity = 64; + /// let mut bitvec = BitVec::with_capacity(64); + /// + /// for _ in 0..initial_capacity - 1 { + /// bitvec.push(false); + /// } + /// + /// assert_eq!(bitvec.len(), initial_capacity - 1); // there is space for only 1 bit + /// + /// assert_eq!(bitvec.push_within_capacity(true), Ok(())); // Successfully push a bit + /// assert_eq!(bitvec.len(), initial_capacity); // So we can't push within capacity anymore + /// + /// assert_eq!(bitvec.push_within_capacity(true), Err(true)); + /// assert_eq!(bitvec.len(), initial_capacity); + /// assert_eq!(bitvec.capacity(), initial_capacity); + /// ``` + /// + /// # Time Complexity + /// Takes *O(1)* time. + pub fn push_within_capacity(&mut self, bit: bool) -> Result<(), bool> { + let len = self.len(); + + if len == self.capacity() { + return Err(bit); + } + + let bits = C::BITS; + + if len % bits == 0 { + self.storage.push(C::ZERO); + } + + let block_at = len / bits; + let bit_at = len % bits; + let flag = if bit { C::ONE << bit_at } else { C::ZERO }; + + self.ensure_invariant(); + + self.nbits += 1; + + self.storage.slice_mut()[block_at] = self.storage.slice()[block_at] | flag; // set the bit + + Ok(()) + } +} + +impl Default for BitVec { + #[inline] + fn default() -> Self { + BitVec { + storage: C::new_in(Default::default()), + nbits: 0, + } + } +} + +impl FromIterator for BitVec { + #[inline] + fn from_iter>(iter: I) -> Self { + let mut ret: Self = Default::default(); + ret.extend(iter); + ret + } +} + +impl Extend for BitVec { + #[inline] + fn extend>(&mut self, iterable: I) { + self.ensure_invariant(); + let iterator = iterable.into_iter(); + let (min, _) = iterator.size_hint(); + self.reserve(min); + for element in iterator { + self.push(element) + } + } +} + +impl Clone for BitVec { + #[inline] + fn clone(&self) -> Self { + self.ensure_invariant(); + BitVec { + storage: self.storage.clone(), + nbits: self.nbits, + } + } + + #[inline] + fn clone_from(&mut self, source: &Self) { + debug_assert!(source.is_last_block_fixed()); + self.nbits = source.nbits; + self.storage.clone_from(&source.storage); + } +} + +impl PartialOrd for BitVec { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for BitVec { + #[inline] + fn cmp(&self, other: &Self) -> Ordering { + self.ensure_invariant(); + debug_assert!(other.is_last_block_fixed()); + let mut a = self.iter(); + let mut b = other.iter(); + loop { + match (a.next(), b.next()) { + (Some(x), Some(y)) => match x.cmp(&y) { + Ordering::Equal => {} + otherwise => return otherwise, + }, + (None, None) => return Ordering::Equal, + (None, _) => return Ordering::Less, + (_, None) => return Ordering::Greater, + } + } + } +} + +impl fmt::Display for BitVec { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + self.ensure_invariant(); + for bit in self { + fmt.write_char(if bit { '1' } else { '0' })?; + } + Ok(()) + } +} + +impl fmt::Debug for BitVec { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + self.ensure_invariant(); + let mut storage = String::with_capacity(self.len() + self.len() / C::BITS); + for (i, bit) in self.iter().enumerate() { + if i != 0 && i % C::BITS == 0 { + storage.push(' '); + } + storage.push(if bit { '1' } else { '0' }); + } + fmt.debug_struct("BitVec") + .field("storage", &storage) + .field("nbits", &self.nbits) + .finish() + } +} + +impl hash::Hash for BitVec { + #[inline] + fn hash(&self, state: &mut H) { + self.ensure_invariant(); + self.nbits.hash(state); + for elem in self.blocks() { + elem.hash(state); + } + } +} + +impl cmp::PartialEq for BitVec { + #[inline] + fn eq(&self, other: &Self) -> bool { + if self.nbits != other.nbits { + self.ensure_invariant(); + other.ensure_invariant(); + return false; + } + self.blocks().zip(other.blocks()).all(|(w1, w2)| w1 == w2) + } +} + +impl cmp::Eq for BitVec {} diff --git a/vec/tests/vec.rs b/vec/tests/vec.rs new file mode 100644 index 0000000..ad623e7 --- /dev/null +++ b/vec/tests/vec.rs @@ -0,0 +1,1410 @@ +#[cfg(test)] +#[generic_tests::define] +mod tests { + #![allow(clippy::shadow_reuse)] + #![allow(clippy::shadow_same)] + #![allow(clippy::shadow_unrelated)] + #![allow(clippy::extra_unused_type_parameters)] + + use bit_vec::{BitContainer, BitVec, Iter}; + + // This is stupid, but I want to differentiate from a "random" 32 + const U32_BITS: usize = 32; + + #[test] + fn test_display_output() { + assert_eq!(format!("{}", BitVec::::new_general()), ""); + assert_eq!( + format!("{}", BitVec::::from_elem_general(1, true)), + "1" + ); + assert_eq!( + format!("{}", BitVec::::from_elem_general(8, false)), + "00000000" + ) + } + + #[test] + fn test_debug_output() { + assert_eq!( + format!("{:?}", BitVec::::new_general()), + "BitVec { storage: \"\", nbits: 0 }" + ); + assert_eq!( + format!("{:?}", BitVec::::from_elem_general(1, true)), + "BitVec { storage: \"1\", nbits: 1 }" + ); + assert_eq!( + format!("{:?}", BitVec::::from_elem_general(8, false)), + "BitVec { storage: \"00000000\", nbits: 8 }" + ); + assert_eq!( + format!("{:?}", BitVec::::from_elem_general(33, true)).replace(" ", ""), + "BitVec{storage:\"111111111111111111111111111111111\",nbits:33}" + ); + assert_eq!( + format!( + "{:?}", + BitVec::::from_bytes_general(&[ + 0b111, 0b000, 0b1110, 0b0001, 0b11111111, 0b00000000 + ]) + ) + .replace(" ", ""), + "BitVec{storage:\"000001110000000000001110000000011111111100000000\",nbits:48}" + ) + } + + #[test] + fn test_0_elements() { + let act = BitVec::::new_general(); + let exp = Vec::new(); + assert!(act.eq_vec(&exp)); + assert!(act.none() && act.all()); + } + + #[test] + fn test_1_element() { + let mut act = BitVec::::from_elem_general(1, false); + assert!(act.eq_vec(&[false])); + assert!(act.none() && !act.all()); + act = BitVec::::from_elem_general(1, true); + assert!(act.eq_vec(&[true])); + assert!(!act.none() && act.all()); + } + + #[test] + fn test_2_elements() { + let mut b = BitVec::::from_elem_general(2, false); + b.set(0, true); + b.set(1, false); + assert_eq!(format!("{}", b), "10"); + assert!(!b.none() && !b.all()); + } + + #[test] + fn test_10_elements() { + // all 0 + + let mut act = BitVec::::from_elem_general(10, false); + assert!( + (act.eq_vec(&[false, false, false, false, false, false, false, false, false, false])) + ); + assert!(act.none() && !act.all()); + // all 1 + + act = BitVec::::from_elem_general(10, true); + assert!((act.eq_vec(&[true, true, true, true, true, true, true, true, true, true]))); + assert!(!act.none() && act.all()); + // mixed + + act = BitVec::::from_elem_general(10, false); + act.set(0, true); + act.set(1, true); + act.set(2, true); + act.set(3, true); + act.set(4, true); + assert!((act.eq_vec(&[true, true, true, true, true, false, false, false, false, false]))); + assert!(!act.none() && !act.all()); + // mixed + + act = BitVec::::from_elem_general(10, false); + act.set(5, true); + act.set(6, true); + act.set(7, true); + act.set(8, true); + act.set(9, true); + assert!((act.eq_vec(&[false, false, false, false, false, true, true, true, true, true]))); + assert!(!act.none() && !act.all()); + // mixed + + act = BitVec::::from_elem_general(10, false); + act.set(0, true); + act.set(3, true); + act.set(6, true); + act.set(9, true); + assert!((act.eq_vec(&[true, false, false, true, false, false, true, false, false, true]))); + assert!(!act.none() && !act.all()); + } + + #[test] + fn test_31_elements() { + // all 0 + + let mut act = BitVec::::from_elem_general(31, false); + assert!(act.eq_vec(&[ + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false + ])); + assert!(act.none() && !act.all()); + // all 1 + + act = BitVec::::from_elem_general(31, true); + assert!(act.eq_vec(&[ + true, true, true, true, true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, true, true, true, true, + true, true, true + ])); + assert!(!act.none() && act.all()); + // mixed + + act = BitVec::::from_elem_general(31, false); + act.set(0, true); + act.set(1, true); + act.set(2, true); + act.set(3, true); + act.set(4, true); + act.set(5, true); + act.set(6, true); + act.set(7, true); + assert!(act.eq_vec(&[ + true, true, true, true, true, true, true, true, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false + ])); + assert!(!act.none() && !act.all()); + // mixed + + act = BitVec::::from_elem_general(31, false); + act.set(16, true); + act.set(17, true); + act.set(18, true); + act.set(19, true); + act.set(20, true); + act.set(21, true); + act.set(22, true); + act.set(23, true); + assert!(act.eq_vec(&[ + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, true, true, true, true, true, true, true, true, false, + false, false, false, false, false, false + ])); + assert!(!act.none() && !act.all()); + // mixed + + act = BitVec::::from_elem_general(31, false); + act.set(24, true); + act.set(25, true); + act.set(26, true); + act.set(27, true); + act.set(28, true); + act.set(29, true); + act.set(30, true); + assert!(act.eq_vec(&[ + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + true, true, true, true, true, true, true + ])); + assert!(!act.none() && !act.all()); + // mixed + + act = BitVec::::from_elem_general(31, false); + act.set(3, true); + act.set(17, true); + act.set(30, true); + assert!(act.eq_vec(&[ + false, false, false, true, false, false, false, false, false, false, false, false, + false, false, false, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, true + ])); + assert!(!act.none() && !act.all()); + } + + #[test] + fn test_32_elements() { + // all 0 + + let mut act = BitVec::::from_elem_general(32, false); + assert!(act.eq_vec(&[ + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false + ])); + assert!(act.none() && !act.all()); + // all 1 + + act = BitVec::::from_elem_general(32, true); + assert!(act.eq_vec(&[ + true, true, true, true, true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, true, true, true, true, + true, true, true, true + ])); + assert!(!act.none() && act.all()); + // mixed + + act = BitVec::::from_elem_general(32, false); + act.set(0, true); + act.set(1, true); + act.set(2, true); + act.set(3, true); + act.set(4, true); + act.set(5, true); + act.set(6, true); + act.set(7, true); + assert!(act.eq_vec(&[ + true, true, true, true, true, true, true, true, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false + ])); + assert!(!act.none() && !act.all()); + // mixed + + act = BitVec::::from_elem_general(32, false); + act.set(16, true); + act.set(17, true); + act.set(18, true); + act.set(19, true); + act.set(20, true); + act.set(21, true); + act.set(22, true); + act.set(23, true); + assert!(act.eq_vec(&[ + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, true, true, true, true, true, true, true, true, false, + false, false, false, false, false, false, false + ])); + assert!(!act.none() && !act.all()); + // mixed + + act = BitVec::::from_elem_general(32, false); + act.set(24, true); + act.set(25, true); + act.set(26, true); + act.set(27, true); + act.set(28, true); + act.set(29, true); + act.set(30, true); + act.set(31, true); + assert!(act.eq_vec(&[ + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + true, true, true, true, true, true, true, true + ])); + assert!(!act.none() && !act.all()); + // mixed + + act = BitVec::::from_elem_general(32, false); + act.set(3, true); + act.set(17, true); + act.set(30, true); + act.set(31, true); + assert!(act.eq_vec(&[ + false, false, false, true, false, false, false, false, false, false, false, false, + false, false, false, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, true, true + ])); + assert!(!act.none() && !act.all()); + } + + #[test] + fn test_33_elements() { + // all 0 + + let mut act = BitVec::::from_elem_general(33, false); + assert!(act.eq_vec(&[ + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false + ])); + assert!(act.none() && !act.all()); + // all 1 + + act = BitVec::::from_elem_general(33, true); + assert!(act.eq_vec(&[ + true, true, true, true, true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true, true, true, true, true, + true, true, true, true, true + ])); + assert!(!act.none() && act.all()); + // mixed + + act = BitVec::::from_elem_general(33, false); + act.set(0, true); + act.set(1, true); + act.set(2, true); + act.set(3, true); + act.set(4, true); + act.set(5, true); + act.set(6, true); + act.set(7, true); + assert!(act.eq_vec(&[ + true, true, true, true, true, true, true, true, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false + ])); + assert!(!act.none() && !act.all()); + // mixed + + act = BitVec::::from_elem_general(33, false); + act.set(16, true); + act.set(17, true); + act.set(18, true); + act.set(19, true); + act.set(20, true); + act.set(21, true); + act.set(22, true); + act.set(23, true); + assert!(act.eq_vec(&[ + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, true, true, true, true, true, true, true, true, false, + false, false, false, false, false, false, false, false + ])); + assert!(!act.none() && !act.all()); + // mixed + + act = BitVec::::from_elem_general(33, false); + act.set(24, true); + act.set(25, true); + act.set(26, true); + act.set(27, true); + act.set(28, true); + act.set(29, true); + act.set(30, true); + act.set(31, true); + assert!(act.eq_vec(&[ + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + true, true, true, true, true, true, true, true, false + ])); + assert!(!act.none() && !act.all()); + // mixed + + act = BitVec::::from_elem_general(33, false); + act.set(3, true); + act.set(17, true); + act.set(30, true); + act.set(31, true); + act.set(32, true); + assert!(act.eq_vec(&[ + false, false, false, true, false, false, false, false, false, false, false, false, + false, false, false, false, false, true, false, false, false, false, false, false, + false, false, false, false, false, false, true, true, true + ])); + assert!(!act.none() && !act.all()); + } + + #[test] + fn test_equal_differing_sizes() { + let v0 = BitVec::::from_elem_general(10, false); + let v1 = BitVec::::from_elem_general(11, false); + assert_ne!(v0, v1); + } + + #[test] + fn test_equal_greatly_differing_sizes() { + let v0 = BitVec::::from_elem_general(10, false); + let v1 = BitVec::::from_elem_general(110, false); + assert_ne!(v0, v1); + } + + #[test] + fn test_equal_sneaky_small() { + let mut a = BitVec::::from_elem_general(1, false); + a.set(0, true); + + let mut b = BitVec::::from_elem_general(1, true); + b.set(0, true); + + assert_eq!(a, b); + } + + #[test] + fn test_equal_sneaky_big() { + let mut a = BitVec::::from_elem_general(100, false); + for i in 0..100 { + a.set(i, true); + } + + let mut b = BitVec::::from_elem_general(100, true); + for i in 0..100 { + b.set(i, true); + } + + assert_eq!(a, b); + } + + #[test] + fn test_from_bytes() { + let bit_vec = + BitVec::::from_bytes_general(&[0b10110110, 0b00000000, 0b11111111]); + let str = concat!("10110110", "00000000", "11111111"); + assert_eq!(format!("{}", bit_vec), str); + } + + #[test] + fn test_to_bytes() { + let mut bv = BitVec::::from_elem_general(3, true); + bv.set(1, false); + assert_eq!(bv.to_bytes(), [0b10100000]); + + let mut bv = BitVec::::from_elem_general(9, false); + bv.set(2, true); + bv.set(8, true); + assert_eq!(bv.to_bytes(), [0b00100000, 0b10000000]); + } + + #[test] + fn test_from_bools() { + let bools = [true, false, true, true]; + let bit_vec: BitVec = bools.iter().copied().collect(); + assert_eq!(format!("{}", bit_vec), "1011"); + } + + #[test] + fn test_to_bools() { + let bools = vec![false, false, true, false, false, true, true, false]; + assert_eq!( + BitVec::::from_bytes_general(&[0b00100110]) + .iter() + .collect::>(), + bools + ); + } + + #[test] + fn test_bit_vec_iterator() { + let bools = vec![true, false, true, true]; + let bit_vec: BitVec = bools.iter().copied().collect(); + + assert_eq!(bit_vec.iter().collect::>(), bools); + + let long: Vec<_> = (0..10000).map(|i| i % 2 == 0).collect(); + let bit_vec: BitVec = long.iter().copied().collect(); + assert_eq!(bit_vec.iter().collect::>(), long) + } + + #[test] + fn test_small_difference() { + let mut b1 = BitVec::::from_elem_general(3, false); + let mut b2 = BitVec::::from_elem_general(3, false); + b1.set(0, true); + b1.set(1, true); + b2.set(1, true); + b2.set(2, true); + assert!(b1.difference(&b2)); + assert!(b1[0]); + assert!(!b1[1]); + assert!(!b1[2]); + } + + #[test] + fn test_big_difference() { + let mut b1 = BitVec::::from_elem_general(100, false); + let mut b2 = BitVec::::from_elem_general(100, false); + b1.set(0, true); + b1.set(40, true); + b2.set(40, true); + b2.set(80, true); + assert!(b1.difference(&b2)); + assert!(b1[0]); + assert!(!b1[40]); + assert!(!b1[80]); + } + + #[test] + fn test_small_xor() { + let mut a = BitVec::::from_bytes_general(&[0b0011]); + let b = BitVec::::from_bytes_general(&[0b0101]); + let c = BitVec::::from_bytes_general(&[0b0110]); + assert!(a.xor(&b)); + assert_eq!(a, c); + } + + #[test] + fn test_small_xnor() { + let mut a = BitVec::::from_bytes_general(&[0b0011]); + let b = BitVec::::from_bytes_general(&[0b1111_0101]); + let c = BitVec::::from_bytes_general(&[0b1001]); + assert!(a.xnor(&b)); + assert_eq!(a, c); + } + + #[test] + fn test_small_nand() { + let mut a = BitVec::::from_bytes_general(&[0b1111_0011]); + let b = BitVec::::from_bytes_general(&[0b1111_0101]); + let c = BitVec::::from_bytes_general(&[0b1110]); + assert!(a.nand(&b)); + assert_eq!(a, c); + } + + #[test] + fn test_small_nor() { + let mut a = BitVec::::from_bytes_general(&[0b0011]); + let b = BitVec::::from_bytes_general(&[0b1111_0101]); + let c = BitVec::::from_bytes_general(&[0b1000]); + assert!(a.nor(&b)); + assert_eq!(a, c); + } + + #[test] + fn test_big_xor() { + let mut a = BitVec::::from_bytes_general(&[ + // 88 bits + 0, 0, 0b00010100, 0, 0, 0, 0, 0b00110100, 0, 0, 0, + ]); + let b = BitVec::::from_bytes_general(&[ + // 88 bits + 0, 0, 0b00010100, 0, 0, 0, 0, 0, 0, 0, 0b00110100, + ]); + let c = BitVec::::from_bytes_general(&[ + // 88 bits + 0, 0, 0, 0, 0, 0, 0, 0b00110100, 0, 0, 0b00110100, + ]); + assert!(a.xor(&b)); + assert_eq!(a, c); + } + + #[test] + fn test_big_xnor() { + let mut a = BitVec::::from_bytes_general(&[ + // 88 bits + 0, 0, 0b00010100, 0, 0, 0, 0, 0b00110100, 0, 0, 0, + ]); + let b = BitVec::::from_bytes_general(&[ + // 88 bits + 0, 0, 0b00010100, 0, 0, 0, 0, 0, 0, 0, 0b00110100, + ]); + let c = BitVec::::from_bytes_general(&[ + // 88 bits + !0, + !0, + !0, + !0, + !0, + !0, + !0, + !0b00110100, + !0, + !0, + !0b00110100, + ]); + assert!(a.xnor(&b)); + assert_eq!(a, c); + } + + #[test] + fn test_small_fill() { + let mut b = BitVec::::from_elem_general(14, true); + assert!(!b.none() && b.all()); + b.fill(false); + assert!(b.none() && !b.all()); + b.fill(true); + assert!(!b.none() && b.all()); + } + + #[test] + fn test_big_fill() { + let mut b = BitVec::::from_elem_general(140, true); + assert!(!b.none() && b.all()); + b.fill(false); + assert!(b.none() && !b.all()); + b.fill(true); + assert!(!b.none() && b.all()); + } + + #[test] + fn test_bit_vec_lt() { + let mut a = BitVec::::from_elem_general(5, false); + let mut b = BitVec::::from_elem_general(5, false); + + assert!(a >= b && b >= a); + b.set(2, true); + assert!(a < b); + a.set(3, true); + assert!(a < b); + a.set(2, true); + assert!(a >= b && b < a); + b.set(0, true); + assert!(a < b); + } + + #[test] + fn test_ord() { + let mut a = BitVec::::from_elem_general(5, false); + let mut b = BitVec::::from_elem_general(5, false); + + assert!(a == b); + a.set(1, true); + assert!(a > b && a >= b); + assert!(b < a && b <= a); + b.set(1, true); + b.set(2, true); + assert!(b > a && b >= a); + assert!(a < b && a <= b); + } + + #[test] + fn test_small_bit_vec_tests() { + let v = BitVec::::from_bytes_general(&[0]); + assert!(!v.all()); + assert!(!v.any()); + assert!(v.none()); + + let v = BitVec::::from_bytes_general(&[0b00010100]); + assert!(!v.all()); + assert!(v.any()); + assert!(!v.none()); + + let v = BitVec::::from_bytes_general(&[0xFF]); + assert!(v.all()); + assert!(v.any()); + assert!(!v.none()); + } + + #[test] + fn test_big_bit_vec_tests() { + let v = BitVec::::from_bytes_general(&[ + // 88 bits + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]); + assert!(!v.all()); + assert!(!v.any()); + assert!(v.none()); + + let v = BitVec::::from_bytes_general(&[ + // 88 bits + 0, 0, 0b00010100, 0, 0, 0, 0, 0b00110100, 0, 0, 0, + ]); + assert!(!v.all()); + assert!(v.any()); + assert!(!v.none()); + + let v = BitVec::::from_bytes_general(&[ + // 88 bits + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + ]); + assert!(v.all()); + assert!(v.any()); + assert!(!v.none()); + } + + #[test] + fn test_bit_vec_push_pop() { + let mut s = BitVec::::from_elem_general(5 * U32_BITS - 2, false); + assert_eq!(s.len(), 5 * U32_BITS - 2); + assert!(!s[5 * U32_BITS - 3]); + s.push(true); + s.push(true); + assert!(s[5 * U32_BITS - 2]); + assert!(s[5 * U32_BITS - 1]); + // Here the internal vector will need to be extended + s.push(false); + assert!(!s[5 * U32_BITS]); + s.push(false); + assert!(!s[5 * U32_BITS + 1]); + assert_eq!(s.len(), 5 * U32_BITS + 2); + // Pop it all off + assert_eq!(s.pop(), Some(false)); + assert_eq!(s.pop(), Some(false)); + assert_eq!(s.pop(), Some(true)); + assert_eq!(s.pop(), Some(true)); + assert_eq!(s.len(), 5 * U32_BITS - 2); + } + + #[test] + fn test_bit_vec_truncate() { + let mut s = BitVec::::from_elem_general(5 * U32_BITS, true); + + assert_eq!( + s, + BitVec::::from_elem_general(5 * U32_BITS, true) + ); + assert_eq!(s.len(), 5 * U32_BITS); + s.truncate(4 * U32_BITS); + assert_eq!( + s, + BitVec::::from_elem_general(4 * U32_BITS, true) + ); + assert_eq!(s.len(), 4 * U32_BITS); + // Truncating to a size > s.len() should be a noop + s.truncate(5 * U32_BITS); + assert_eq!( + s, + BitVec::::from_elem_general(4 * U32_BITS, true) + ); + assert_eq!(s.len(), 4 * U32_BITS); + s.truncate(3 * U32_BITS - 10); + assert_eq!( + s, + BitVec::::from_elem_general(3 * U32_BITS - 10, true) + ); + assert_eq!(s.len(), 3 * U32_BITS - 10); + s.truncate(0); + assert_eq!(s, BitVec::::from_elem_general(0, true)); + assert_eq!(s.len(), 0); + } + + #[test] + fn test_bit_vec_reserve() { + let mut s = BitVec::::from_elem_general(5 * U32_BITS, true); + // Check capacity + assert!(s.capacity() >= 5 * U32_BITS); + s.reserve(2 * U32_BITS); + assert!(s.capacity() >= 7 * U32_BITS); + s.reserve(7 * U32_BITS); + assert!(s.capacity() >= 12 * U32_BITS); + s.reserve_exact(7 * U32_BITS); + assert!(s.capacity() >= 12 * U32_BITS); + s.reserve(7 * U32_BITS + 1); + assert!(s.capacity() > 12 * U32_BITS); + // Check that length hasn't changed + assert_eq!(s.len(), 5 * U32_BITS); + s.push(true); + s.push(false); + s.push(true); + assert!(s[5 * U32_BITS - 1]); + assert!(s[5 * U32_BITS]); + assert!(!s[5 * U32_BITS + 1]); + assert!(s[5 * U32_BITS + 2]); + } + + #[test] + fn test_bit_vec_grow() { + let mut bit_vec = + BitVec::::from_bytes_general(&[0b10110110, 0b00000000, 0b10101010]); + bit_vec.grow(32, true); + assert_eq!( + bit_vec, + BitVec::::from_bytes_general(&[ + 0b10110110, 0b00000000, 0b10101010, 0xFF, 0xFF, 0xFF, 0xFF + ]) + ); + bit_vec.grow(64, false); + assert_eq!( + bit_vec, + BitVec::::from_bytes_general(&[ + 0b10110110, 0b00000000, 0b10101010, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 + ]) + ); + bit_vec.grow(16, true); + assert_eq!( + bit_vec, + BitVec::::from_bytes_general(&[ + 0b10110110, 0b00000000, 0b10101010, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, + 0xFF, 0xFF + ]) + ); + } + + #[test] + fn test_bit_vec_extend() { + let mut bit_vec = + BitVec::::from_bytes_general(&[0b10110110, 0b00000000, 0b11111111]); + let ext = BitVec::::from_bytes_general(&[0b01001001, 0b10010010, 0b10111101]); + bit_vec.extend(ext.iter()); + assert_eq!( + bit_vec, + BitVec::::from_bytes_general(&[ + 0b10110110, 0b00000000, 0b11111111, 0b01001001, 0b10010010, 0b10111101 + ]) + ); + } + + #[test] + fn test_bit_vec_append() { + // Append to BitVec that holds a multiple of U32_BITS bits + let mut a = BitVec::::from_bytes_general(&[ + 0b10100000, 0b00010010, 0b10010010, 0b00110011, + ]); + let mut b = BitVec::::new_general(); + b.push(false); + b.push(true); + b.push(true); + + a.append(&mut b); + + assert_eq!(a.len(), 35); + assert_eq!(b.len(), 0); + assert!(b.capacity() >= 3); + + assert!(a.eq_vec(&[ + true, false, true, false, false, false, false, false, false, false, false, true, false, + false, true, false, true, false, false, true, false, false, true, false, false, false, + true, true, false, false, true, true, false, true, true + ])); + + // Append to arbitrary BitVec + let mut a = BitVec::::new_general(); + a.push(true); + a.push(false); + + let mut b = BitVec::::from_bytes_general(&[ + 0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b10010101, + ]); + + a.append(&mut b); + + assert_eq!(a.len(), 42); + assert_eq!(b.len(), 0); + assert!(b.capacity() >= 40); + + assert!(a.eq_vec(&[ + true, false, true, false, true, false, false, false, false, false, false, false, false, + true, false, false, true, false, true, false, false, true, false, false, true, false, + false, false, true, true, false, false, true, true, true, false, false, true, false, + true, false, true + ])); + + // Append to empty BitVec + let mut a = BitVec::::new_general(); + let mut b = BitVec::::from_bytes_general(&[ + 0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b10010101, + ]); + + a.append(&mut b); + + assert_eq!(a.len(), 40); + assert_eq!(b.len(), 0); + assert!(b.capacity() >= 40); + + assert!(a.eq_vec(&[ + true, false, true, false, false, false, false, false, false, false, false, true, false, + false, true, false, true, false, false, true, false, false, true, false, false, false, + true, true, false, false, true, true, true, false, false, true, false, true, false, + true + ])); + + // Append empty BitVec + let mut a = BitVec::::from_bytes_general(&[ + 0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b10010101, + ]); + let mut b = BitVec::::new_general(); + + a.append(&mut b); + + assert_eq!(a.len(), 40); + assert_eq!(b.len(), 0); + + assert!(a.eq_vec(&[ + true, false, true, false, false, false, false, false, false, false, false, true, false, + false, true, false, true, false, false, true, false, false, true, false, false, false, + true, true, false, false, true, true, true, false, false, true, false, true, false, + true + ])); + } + + #[test] + fn test_bit_vec_split_off() { + // Split at 0 + let mut a = BitVec::::new_general(); + a.push(true); + a.push(false); + a.push(false); + a.push(true); + + let b = a.split_off(0); + + assert_eq!(a.len(), 0); + assert_eq!(b.len(), 4); + + assert!(b.eq_vec(&[true, false, false, true])); + + // Split at last bit + a.truncate(0); + a.push(true); + a.push(false); + a.push(false); + a.push(true); + + let b = a.split_off(4); + + assert_eq!(a.len(), 4); + assert_eq!(b.len(), 0); + + assert!(a.eq_vec(&[true, false, false, true])); + + // Split at block boundary + let mut a = BitVec::::from_bytes_general(&[ + 0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b11110011, + ]); + + let b = a.split_off(32); + + assert_eq!(a.len(), 32); + assert_eq!(b.len(), 8); + + assert!(a.eq_vec(&[ + true, false, true, false, false, false, false, false, false, false, false, true, false, + false, true, false, true, false, false, true, false, false, true, false, false, false, + true, true, false, false, true, true + ])); + assert!(b.eq_vec(&[true, true, true, true, false, false, true, true])); + + // Don't split at block boundary + let mut a = BitVec::::from_bytes_general(&[ + 0b10100000, 0b00010010, 0b10010010, 0b00110011, 0b01101011, 0b10101101, + ]); + + let b = a.split_off(13); + + assert_eq!(a.len(), 13); + assert_eq!(b.len(), 35); + + assert!(a.eq_vec(&[ + true, false, true, false, false, false, false, false, false, false, false, true, false + ])); + assert!(b.eq_vec(&[ + false, true, false, true, false, false, true, false, false, true, false, false, false, + true, true, false, false, true, true, false, true, true, false, true, false, true, + true, true, false, true, false, true, true, false, true + ])); + } + + #[test] + fn test_into_iter() { + let bools = [true, false, true, true]; + let bit_vec: BitVec = bools.iter().copied().collect(); + let mut iter = bit_vec.into_iter(); + assert_eq!(Some(true), iter.next()); + assert_eq!(Some(false), iter.next()); + assert_eq!(Some(true), iter.next()); + assert_eq!(Some(true), iter.next()); + assert_eq!(None, iter.next()); + assert_eq!(None, iter.next()); + + let bit_vec: BitVec = bools.iter().copied().collect(); + let mut iter = bit_vec.into_iter(); + assert_eq!(Some(true), iter.next_back()); + assert_eq!(Some(true), iter.next_back()); + assert_eq!(Some(false), iter.next_back()); + assert_eq!(Some(true), iter.next_back()); + assert_eq!(None, iter.next_back()); + assert_eq!(None, iter.next_back()); + + let bit_vec: BitVec = bools.iter().copied().collect(); + let mut iter = bit_vec.into_iter(); + assert_eq!(Some(true), iter.next_back()); + assert_eq!(Some(true), iter.next()); + assert_eq!(Some(false), iter.next()); + assert_eq!(Some(true), iter.next_back()); + assert_eq!(None, iter.next()); + assert_eq!(None, iter.next_back()); + } + + #[test] + fn test_iter() { + let b = BitVec::::with_capacity_general(10); + let _a: Iter = b.iter(); + } + + #[cfg(feature = "serde")] + #[test] + fn test_serialization() + where + C: BitContainer serde::Deserialize<'a>> + + serde::Serialize + + for<'a> serde::Deserialize<'a>, + { + let bit_vec = BitVec::::new_general(); + let serialized = serde_json::to_string(&bit_vec).unwrap(); + let unserialized: BitVec = serde_json::from_str(&serialized[..]).unwrap(); + assert_eq!(bit_vec, unserialized); + + let bools: [bool; 4] = [true, false, true, true]; + let bit_vec: BitVec = bools.into_iter().collect(); + let serialized = serde_json::to_string(&bit_vec).unwrap(); + let unserialized = serde_json::from_str(&serialized).unwrap(); + assert_eq!(bit_vec, unserialized); + } + + #[cfg(all(feature = "miniserde", not(feature = "smallvec")))] + #[test] + fn test_miniserde_serialization() + where + C: BitContainer + + miniserde::Serialize + + miniserde::Deserialize, + { + let bit_vec = BitVec::::new_general(); + let serialized = miniserde::json::to_string(&bit_vec); + let unserialized: BitVec = miniserde::json::from_str(&serialized[..]).unwrap(); + assert_eq!(bit_vec, unserialized); + + let bools = vec![true, false, true, true]; + let bit_vec: BitVec = bools.iter().map(|n| *n).collect(); + let serialized = miniserde::json::to_string(&bit_vec); + let unserialized = miniserde::json::from_str(&serialized[..]).unwrap(); + assert_eq!(bit_vec, unserialized); + } + + #[cfg(all(feature = "borsh", not(feature = "smallvec")))] + #[test] + fn test_borsh_serialization() + where + C: BitContainer + + borsh::BorshSerialize + + borsh::BorshDeserialize, + { + let bit_vec = BitVec::::new_general(); + let serialized = borsh::to_vec(&bit_vec).unwrap(); + let unserialized: BitVec = borsh::from_slice(&serialized[..]).unwrap(); + assert_eq!(bit_vec, unserialized); + + let bools = vec![true, false, true, true]; + let bit_vec: BitVec = bools.iter().map(|n| *n).collect(); + let serialized = borsh::to_vec(&bit_vec).unwrap(); + let unserialized = borsh::from_slice(&serialized[..]).unwrap(); + assert_eq!(bit_vec, unserialized); + } + + #[test] + fn test_bit_vec_unaligned_small_append() { + let mut a = BitVec::::from_elem_general(8, false); + a.set(7, true); + + let mut b = BitVec::::from_elem_general(16, false); + b.set(14, true); + + let mut c = BitVec::::from_elem_general(8, false); + c.set(6, true); + c.set(7, true); + + a.append(&mut b); + a.append(&mut c); + + assert_eq!(&[1, 0, 2, 3][..], &*a.to_bytes()); + } + + #[test] + fn test_bit_vec_unaligned_large_append() { + let mut a = BitVec::::from_elem_general(48, false); + a.set(47, true); + + let mut b = BitVec::::from_elem_general(48, false); + b.set(46, true); + + let mut c = BitVec::::from_elem_general(48, false); + c.set(46, true); + c.set(47, true); + + a.append(&mut b); + a.append(&mut c); + + assert_eq!( + &[ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03 + ][..], + &*a.to_bytes() + ); + } + + #[test] + fn test_bit_vec_append_aligned_to_unaligned() { + let mut a = BitVec::::from_elem_general(2, true); + let mut b = BitVec::::from_elem_general(32, false); + let mut c = BitVec::::from_elem_general(8, true); + a.append(&mut b); + a.append(&mut c); + assert_eq!(&[0xc0, 0x00, 0x00, 0x00, 0x3f, 0xc0][..], &*a.to_bytes()); + } + + #[test] + fn test_count_ones() { + for i in 0..1000 { + let mut t = BitVec::::from_elem_general(i, true); + let mut f = BitVec::::from_elem_general(i, false); + assert_eq!(i as u64, t.count_ones()); + assert_eq!(0_u64, f.count_ones()); + if i > 20 { + t.set(10, false); + t.set(i - 10, false); + assert_eq!(i - 2, t.count_ones() as usize); + f.set(10, true); + f.set(i - 10, true); + assert_eq!(2, f.count_ones()); + } + } + } + + #[test] + fn test_count_zeros() { + for i in 0..1000 { + let mut tbits = BitVec::::from_elem_general(i, true); + let mut fbits = BitVec::::from_elem_general(i, false); + assert_eq!(i as u64, fbits.count_zeros()); + assert_eq!(0_u64, tbits.count_zeros()); + if i > 20 { + fbits.set(10, true); + fbits.set(i - 10, true); + assert_eq!(i - 2, fbits.count_zeros() as usize); + tbits.set(10, false); + tbits.set(i - 10, false); + assert_eq!(2, tbits.count_zeros()); + } + } + } + + #[test] + fn test_get_mut() { + let mut a = BitVec::::from_elem_general(3, false); + let mut a_bit_1 = a.get_mut(1).unwrap(); + assert!(!*a_bit_1); + *a_bit_1 = true; + drop(a_bit_1); + assert!(a.eq_vec(&[false, true, false])); + } + + #[test] + fn test_iter_mut() { + let mut a = BitVec::::from_elem_general(8, false); + a.iter_mut().enumerate().for_each(|(index, mut bit)| { + *bit = index % 2 == 1; + }); + assert!(a.eq_vec(&[false, true, false, true, false, true, false, true])); + } + + #[test] + fn test_insert_at_zero() { + let mut v = BitVec::::new_general(); + + v.insert(0, false); + v.insert(0, true); + v.insert(0, false); + v.insert(0, true); + v.insert(0, false); + v.insert(0, true); + + assert_eq!(v.len(), 6); + assert_eq!(v.storage().len(), 1); + assert!(v.eq_vec(&[true, false, true, false, true, false])); + } + + #[test] + fn test_insert_at_end() { + let mut v = BitVec::::new_general(); + + v.insert(v.len(), true); + v.insert(v.len(), false); + v.insert(v.len(), true); + v.insert(v.len(), false); + v.insert(v.len(), true); + v.insert(v.len(), false); + + assert_eq!(v.storage().len(), 1); + assert_eq!(v.len(), 6); + assert!(v.eq_vec(&[true, false, true, false, true, false])); + } + + #[test] + fn test_insert_at_block_boundaries() { + let mut v = BitVec::::from_elem_general(32, false); + + assert_eq!(v.storage().len(), (4 / C::BYTES).max(1)); + + v.insert(31, true); + + assert_eq!(v.len(), 33); + + assert!(matches!(v.get(31), Some(true))); + assert!(v.eq_vec(&[ + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, true, false + ])); + + assert_eq!(v.storage().len(), 1 + 4 / C::BYTES); + } + + #[test] + fn test_insert_at_block_boundaries_1() { + let mut v = BitVec::::from_elem_general(64, false); + + assert_eq!(v.storage().len(), 8 / C::BYTES); + + v.insert(63, true); + + assert_eq!(v.len(), 65); + + assert!(matches!(v.get(63), Some(true))); + assert!(v.eq_vec(&[ + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, true, false + ])); + + assert_eq!(v.storage().len(), 1 + 8 / C::BYTES); + } + + #[test] + fn test_push_within_capacity_with_suffice_cap() { + let mut v = BitVec::::from_elem_general(16, true); + + if C::BYTES > 2 { + assert!(v.push_within_capacity(false).is_ok()); + } + + for i in 0..16 { + assert_eq!(v.get(i), Some(true)); + } + + if C::BYTES > 2 { + assert_eq!(v.get(16), Some(false)); + assert_eq!(v.len(), 17); + } + } + + #[test] + fn test_push_within_capacity_at_brink() { + let mut v = BitVec::::from_elem_general(31, true); + + assert!(v.push_within_capacity(false).is_ok()); + + assert_eq!(v.get(31), Some(false)); + if v.capacity() < 256 { + assert_eq!(if C::BYTES == 8 { 64 } else { v.len() }, v.capacity()); + } + assert_eq!(v.len(), 32); + + if v.capacity() < 256 { + assert_eq!( + v.push_within_capacity(false), + if C::BYTES == 8 { Ok(()) } else { Err(false) } + ); + assert_eq!(v.capacity(), if C::BYTES == 8 { 64 } else { 32 }); + } + + for i in 0..31 { + assert_eq!(v.get(i), Some(true)); + } + assert_eq!(v.get(31), Some(false)); + } + + #[test] + fn test_push_within_capacity_at_brink_with_mul_blocks() { + let mut v = BitVec::::from_elem_general(95, true); + + assert!(v.push_within_capacity(false).is_ok()); + + assert_eq!(v.get(95), Some(false)); + if C::BYTES <= 4 && v.capacity() < 256 { + assert_eq!(v.len(), v.capacity()); + } + assert_eq!(v.len(), 96); + + if C::BYTES == 8 { + assert_eq!(v.push_within_capacity(false), Ok(())); + if v.capacity() < 256 { + assert_eq!(v.capacity(), 128); + } + } else if v.capacity() < 256 { + assert_eq!(v.push_within_capacity(false), Err(false)); + assert_eq!(v.capacity(), 96); + } + + for i in 0..95 { + assert_eq!(v.get(i), Some(true)); + } + assert_eq!(v.get(95), Some(false)); + } + + #[test] + fn test_push_within_capacity_storage_push() { + let mut v = BitVec::::with_capacity_general(64); + + for _ in 0..32 { + v.push(true); + } + + assert_eq!(v.len(), 32); + + assert!(v.push_within_capacity(false).is_ok()); + + assert_eq!(v.len(), 33); + + for i in 0..32 { + assert_eq!(v.get(i), Some(true)); + } + assert_eq!(v.get(32), Some(false)); + } + + #[test] + fn test_insert_remove() { + // two primes for no common divisors with 32 + let mut v = BitVec::::from_fn_general(1024, |i| i % 11 < 7); + for i in 0..1024 { + let result = v.remove(i); + v.insert(i, result); + assert_eq!(result, i % 11 < 7); + } + + for i in 0..1024 { + v.insert(i, false); + v.remove(i); + } + + for i in 0..1024 { + v.insert(i, true); + v.remove(i); + } + + for (i, result) in v.into_iter().enumerate() { + assert_eq!(result, i % 11 < 7); + } + } + + #[test] + fn test_remove_last() { + let mut v = BitVec::::from_fn_general(1025, |i| i % 11 < 7); + assert_eq!(v.len(), 1025); + assert_eq!(v.remove(1024), 1024 % 11 < 7); + assert_eq!(v.len(), 1024); + assert_eq!(v.storage().len(), 1024 / C::BITS); + } + + #[test] + fn test_remove_all() { + let v = BitVec::::from_elem_general(1024, false); + for _ in 0..1024 { + let mut v2 = v.clone(); + v2.remove_all(); + assert_eq!(v2.len(), 0); + assert_eq!(v2.get(0), None); + assert_eq!(v2, BitVec::new_general()); + } + } + + #[instantiate_tests(>)] + mod vec32 {} + + #[cfg(feature = "smallvec")] + #[instantiate_tests(>)] + mod smallvec32x8 {} + + #[cfg(feature = "smallvec")] + #[instantiate_tests(>)] + mod smallvec64x8 {} + + #[instantiate_tests(>)] + mod native {} + + #[instantiate_tests(>)] + mod integer16 {} + + #[instantiate_tests(>)] + mod integer8 {} +} + +#[cfg(test)] +#[cfg(feature = "allocator_api")] +mod alloc_tests { + use std::alloc::Global; + use std::vec::Vec; + + use crate::BitVec; + + #[test] + fn test_new_in() { + let alloc = Global; + let mut v: BitVec> = BitVec::new_general_in(alloc); + v.push(true); + v.push(false); + assert_eq!(v.len(), 2); + assert_eq!(v.pop(), Some(false)); + assert_eq!(v.pop(), Some(true)); + } +}