diff --git a/Cargo.toml b/Cargo.toml index 52ec6f9..73cb331 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,8 +13,12 @@ categories = ["data-structures"] [features] std = [] +bitvec-asbits = ["bitvec"] default = ["std"] [package.metadata.release] no-dev-version = true tag-name = "{{version}}" + +[dependencies] +bitvec = { version = "^0.17", optional = true } \ No newline at end of file diff --git a/src/asbits.rs b/src/asbits.rs new file mode 100644 index 0000000..e6d89af --- /dev/null +++ b/src/asbits.rs @@ -0,0 +1,66 @@ +use std::ops; + +use bitvec::slice::{BitSlice, AsBits}; +use bitvec::order::{BitOrder, Lsb0}; + +use super::FixedBitSet; +use crate::range::IndexRange; + +impl AsBits for FixedBitSet { + type Store = u32; + + fn bits(&self) -> &BitSlice { + BitSlice::from_slice(self.as_slice()) + } + + fn bits_mut(&mut self) -> &mut BitSlice { + BitSlice::from_slice_mut(self.as_mut_slice()) + } +} + +impl ops::Deref for FixedBitSet { + type Target = BitSlice; + fn deref(&self) -> &Self::Target { + self.bits() + } +} + +impl ops::DerefMut for FixedBitSet { + fn deref_mut(&mut self) -> &mut Self::Target { + self.bits_mut() + } +} + +impl ops::Index for FixedBitSet { + type Output = BitSlice; + fn index(&self, range: R) -> &Self::Output { + let start = range.start().unwrap_or(0); + let end = range.end().unwrap_or(self.len()); + &self.bits()[start..end] + } +} + +impl ops::IndexMut for FixedBitSet { + fn index_mut(&mut self, range: R) -> &mut Self::Output { + let start = range.start().unwrap_or(0); + let end = range.end().unwrap_or(self.len()); + &mut self.bits_mut()[start..end] + } +} + +#[test] +fn test_asbits() { + let mut fb = FixedBitSet::with_capacity(50); + fb.set(11, true); + fb.set(12, true); + fb.set(7, true); + fb.set(35, true); + fb.set(40, true); + + assert_eq!(fb.get(5), Some(&false)); + assert_eq!(fb[10..].get(1), Some(&true)); + fb[10..].set(2, false); + assert_eq!(fb.get(12), Some(&false)); + + assert_eq!(fb.count_ones(..), 4); +} diff --git a/src/lib.rs b/src/lib.rs index 5ad52d3..b3e97ab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,6 +28,11 @@ use core as std; mod range; +#[cfg(feature = "bitvec-asbits")] +extern crate bitvec; +#[cfg(feature = "bitvec-asbits")] +mod asbits; + use std::fmt::Write; use std::fmt::{Display, Error, Formatter, Binary};