From c7c319e7bfd09edf5a879637bbf5eab1b9ff5280 Mon Sep 17 00:00:00 2001 From: Columbus240 <8899730+Columbus240@users.noreply.github.com> Date: Tue, 5 Jul 2022 13:36:12 +0200 Subject: [PATCH] =?UTF-8?q?Allow=20making=20instances=20of=20`BitVec`=20wi?= =?UTF-8?q?th=20`B=E2=89=A0u32`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously it was not possible to construct such instances of `BitVec` other than using the `Default` trait. --- src/lib.rs | 101 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a4a11d6..3d0a667 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -125,6 +125,7 @@ pub trait BitBlock: + BitOr + BitXor + Rem + + BitOrAssign + Eq + Ord + hash::Hash @@ -286,6 +287,90 @@ impl BitVec { /// ``` #[inline] pub fn from_elem(nbits: usize, bit: bool) -> Self { + BitVec::::from_elem_general(nbits, 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(nbits: usize) -> Self { + BitVec::::with_capacity_general(nbits) + } + + /// 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, mut 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(nbits: usize, bit: bool) -> Self { let nblocks = blocks_for_bits::(nbits); let mut bit_vec = BitVec { storage: vec![if bit { !B::zero() } else { B::zero() }; nblocks], @@ -303,7 +388,7 @@ impl BitVec { /// 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(nbits: usize) -> Self { + pub fn with_capacity_general(nbits: usize) -> Self { BitVec { storage: Vec::with_capacity(blocks_for_bits::(nbits)), nbits: 0, @@ -319,18 +404,18 @@ impl BitVec { /// ``` /// use bit_vec::BitVec; /// - /// let bv = BitVec::from_bytes(&[0b10100000, 0b00010010]); + /// 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(bytes: &[u8]) -> Self { + 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(len); + let mut bit_vec = BitVec::with_capacity_general(len); let complete_words = bytes.len() / B::bytes(); let extra_bytes = bytes.len() % B::bytes(); @@ -363,23 +448,21 @@ impl BitVec { /// ``` /// use bit_vec::BitVec; /// - /// let bv = BitVec::from_fn(5, |i| { i % 2 == 0 }); + /// 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(len: usize, mut f: F) -> Self + pub fn from_fn_general(len: usize, mut f: F) -> Self where F: FnMut(usize) -> bool, { - let mut bit_vec = BitVec::from_elem(len, false); + let mut bit_vec = BitVec::from_elem_general(len, false); for i in 0..len { bit_vec.set(i, f(i)); } bit_vec } -} -impl BitVec { /// 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.