#![deny(unsafe_code)]
use std::fmt;
use std::hash;
use std::ops::Index;
mod inner;
mod iter;
pub use crate::inner::BitVec;
pub use crate::iter::{Iter, IntoOnes, Ones};
const BITS: usize = 8;
impl Index<usize> for BitVec {
type Output = bool;
#[inline]
fn index(&self, i: usize) -> &bool {
if self.get(i).expect("index out of bounds") {
&true
} else {
&false
}
}
}
impl BitVec {
#[inline]
pub fn count_ones(&self) -> usize {
hamming::weight(self.as_bytes()) as usize
}
#[inline]
pub fn count_ones_before(&self, bit: usize) -> usize {
assert!(bit <= self.len());
let (byte, bit) = (bit / BITS, bit % BITS);
let mask = (1 << bit) - 1;
let bytes = self.as_bytes();
hamming::weight(&bytes[..byte]) as usize
+ bytes.get(byte).map_or(0, |b| (b & mask).count_ones() as usize)
}
pub fn find_nth_bit(&self, mut n: usize) -> Option<usize> {
if n >= self.len() {
return None;
}
n += 1;
let mut bytes = self.as_bytes();
let mut byte_idx = 0;
while bytes.len() > 240 {
let ix = bytes.len() / 2;
let (first, second) = bytes.split_at(ix);
let count = hamming::weight(first) as usize;
if count >= n {
bytes = first;
} else {
n -= count;
bytes = second;
byte_idx += ix;
}
}
let i = bytes.iter().position(|&b| {
let count = b.count_ones() as usize;
if count >= n {
true
} else {
n -= count;
false
}
})?;
let mut b = bytes[i];
for _ in 1..n {
b &= b - 1;
}
assert!(b != 0);
Some((byte_idx + i) * BITS + b.trailing_zeros() as usize)
}
#[inline]
pub fn set_all(&mut self) {
for w in self.as_bytes_mut() { *w = !0; }
self.fix_last_block();
}
#[inline]
pub fn clear(&mut self) {
for w in self.as_bytes_mut() { *w = 0; }
}
#[inline]
pub fn is_empty(&self) -> bool { self.len() == 0 }
}
impl Default for BitVec {
#[inline]
fn default() -> BitVec { BitVec::new() }
}
impl fmt::Debug for BitVec {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
for bit in self {
write!(fmt, "{}", if bit { 1 } else { 0 })?;
}
Ok(())
}
}
impl hash::Hash for BitVec {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
state.write_usize(self.len());
state.write(self.as_bytes());
}
}
impl PartialEq for BitVec {
#[inline]
fn eq(&self, other: &BitVec) -> bool {
self.len() == other.len() && self.as_bytes() == other.as_bytes()
}
}
impl Eq for BitVec {}
#[cfg(test)]
mod tests {
use super::BitVec;
#[test]
fn count_ones_before() {
let len = 10000;
let ones = BitVec::from_elem(len, true);
let zeros = BitVec::from_elem(len, false);
let mut halves = zeros.clone();
for i in 0..len / 2 {
halves.set(i * 2, true);
}
for i in 0..len + 1 {
assert_eq!(ones.count_ones_before(i), i);
assert_eq!(zeros.count_ones_before(i), 0);
assert_eq!(halves.count_ones_before(i), (i + 1) / 2);
}
}
#[test]
fn find_nth_bit() {
let len = 5000;
let ones = BitVec::from_elem(len, true);
let mut halves = BitVec::from_elem(len * 2, false);
for i in 0..len {
halves.set(i * 2, true);
}
for i in 0..len {
assert_eq!(ones.find_nth_bit(i), Some(i));
assert_eq!(halves.find_nth_bit(i), Some(i * 2));
}
assert_eq!(ones.find_nth_bit(len + 1), None);
assert_eq!(halves.find_nth_bit(len + 1), None);
assert_eq!(BitVec::new().find_nth_bit(0), None);
assert_eq!(BitVec::from_elem(len, false).find_nth_bit(0), None);
}
#[test]
fn get() {
let len = 10000;
let mut halves = BitVec::from_elem(len, false);
for i in 0..len {
assert_eq!(halves.get(i), Some(false));
}
for i in 0..len / 2 {
halves.set(i * 2, true);
}
for i in 0..len {
assert_eq!(halves.get(i), Some(i % 2 == 0));
}
assert_eq!(halves.get(len), None);
}
#[test]
fn clone() {
let len = 10000;
let ones = BitVec::from_elem(len, true);
let zeros = BitVec::from_elem(len, false);
let mut halves = zeros.clone();
for i in 0..len / 2 {
halves.set(i * 2, true);
}
assert_eq!(ones.clone(), ones);
assert_eq!(zeros.clone(), zeros);
assert_eq!(halves.clone(), halves);
let mut bv = BitVec::from_elem(len, false);
bv.clone_from(&ones);
assert_eq!(bv, ones);
bv.clone_from(&zeros);
assert_eq!(bv, zeros);
bv.clone_from(&halves);
assert_eq!(bv, halves);
}
#[test]
fn len_is_empty() {
let len = 10000;
let ones = BitVec::from_elem(len, true);
let zeros = BitVec::from_elem(len, false);
let default = BitVec::default();
assert_eq!(ones.len(), len);
assert_eq!(zeros.len(), len);
assert_eq!(default.len(), 0);
assert!(!ones.is_empty());
assert!(!zeros.is_empty());
assert!(default.is_empty());
}
#[test]
fn clear_set_all() {
let len = 10000;
let ones = BitVec::from_elem(len, true);
let zeros = BitVec::from_elem(len, false);
let mut bv = ones.clone();
assert_eq!(bv, ones);
bv.clear();
assert_eq!(bv, zeros);
bv.set_all();
assert_eq!(bv, ones);
}
}