extern crate num_traits;
use std::cmp::PartialEq;
use std::fmt;
use std::fmt::Debug;
use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
use std::mem::size_of;
use std::ops::{Index, Range};
use std::slice;
use num_traits::{PrimInt, One, Zero};
#[derive(Clone)]
pub struct Vob<T=usize> {
len: usize,
vec: Vec<T>
}
impl Vob<usize> {
pub fn new() -> Vob<usize> {
Default::default()
}
pub fn with_capacity(capacity: usize) -> Vob<usize> {
Vob {
len: 0,
vec: Vec::with_capacity(blocks_required::<usize>(capacity))
}
}
pub fn from_elem(len: usize, value: bool) -> Vob<usize> {
let mut v = Vob::with_capacity(len);
for _ in 0..blocks_required::<usize>(len) {
v.vec.push(if value { !0 } else { 0 });
}
v.len = len;
v.mask_last_block();
v
}
}
impl<T: Debug + PrimInt + One + Zero> Vob<T> {
pub fn new_with_storage_type(capacity: usize) -> Vob<T> {
Vob {
len: 0,
vec: Vec::with_capacity(capacity)
}
}
pub fn capacity(&self) -> usize {
self.vec.capacity() * bits_per_block::<T>()
}
pub fn reserve(&mut self, additional: usize) {
let cap = self.vec.capacity()
.checked_mul(bits_per_block::<T>())
.and_then(|x| x.checked_add(additional))
.expect("Overflow detected");
self.vec.reserve(blocks_required::<T>(cap));
}
pub fn shrink_to_fit(&mut self) {
self.vec.shrink_to_fit();
}
pub fn truncate(&mut self, len: usize) {
if len > self.len {
return;
}
self.len = len;
self.vec.truncate(blocks_required::<T>(len));
self.mask_last_block();
}
pub fn push(&mut self, value: bool) {
if self.len % bits_per_block::<T>() == 0 {
self.vec.push(T::zero());
}
let i = self.len;
self.len = i.checked_add(1).expect("Overflow detected");
self.set(i, value);
}
pub fn pop(&mut self) -> Option<bool> {
if self.len == 0 {
return None;
}
let v = self.get(self.len - 1);
debug_assert!(v.is_some());
self.len -= 1;
self.mask_last_block();
v
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn split_off(&mut self, at: usize) -> Vob<T> {
if at >= self.len {
return Vob::<T>::new_with_storage_type(0);
}
let mut nv = Vob::<T>::new_with_storage_type(self.len - at);
for blk in self.iter().skip(at) {
nv.push(blk);
}
self.len = at;
self.mask_last_block();
nv
}
pub fn get(&self, index: usize) -> Option<bool> {
if index >= self.len {
return None;
}
let blk = self.vec[block_offset::<T>(index)];
Some(blk & (T::one() << (index % bits_per_block::<T>())) != T::zero())
}
pub fn set(&mut self, index: usize, value: bool) -> Option<bool> {
if index >= self.len {
return None;
}
let msk = T::one() << (index % bits_per_block::<T>());
let off = block_offset::<T>(index);
let old_v = self.vec[off];
let new_v = if value {
old_v | msk
} else {
old_v & !msk
};
if new_v != old_v {
self.vec[off] = new_v;
Some(true)
} else {
Some(false)
}
}
pub fn iter(&self) -> Iter<T> {
Iter {
vob: self,
range: 0..self.len
}
}
pub fn iter_set_bits(&self) -> IterSetBits<T> {
IterSetBits {
vob: self,
range: 0..self.len
}
}
pub fn iter_unset_bits(&self) -> IterUnsetBits<T> {
IterUnsetBits {
vob: self,
range: 0..self.len
}
}
pub fn iter_storage(&self) -> StorageIter<T> {
StorageIter{iter: self.vec.iter()}
}
pub fn resize(&mut self, new_len: usize, value: bool) {
if new_len <= self.len {
self.truncate(new_len);
return
}
if value && self.len > 0 {
let off = block_offset::<T>(self.len);
let v = self.vec[off];
self.vec[off] = v | (T::max_value() << (self.len % bits_per_block::<T>()));
}
self.vec.resize(blocks_required::<T>(new_len), if value {
T::max_value()
} else {
T::zero()
});
self.len = new_len;
self.mask_last_block();
}
pub fn extend_from_slice(&mut self, other: &[bool]) {
for &blk in other.iter() {
self.push(blk);
}
}
pub fn clear(&mut self) {
self.len = 0;
self.vec.clear();
}
pub fn set_all(&mut self, value: bool) {
for blk in self.vec.iter_mut() {
*blk = if value {
T::max_value()
} else {
T::zero()
};
}
self.mask_last_block();
}
pub fn negate(&mut self) {
for blk in self.vec.iter_mut() {
*blk = !*blk;
}
self.mask_last_block();
}
pub fn and(&mut self, other: &Vob<T>) -> bool {
if self.len != other.len {
panic!("Cannot 'and' two Vobs of different length ({} {})", self.len, other.len);
}
let mut chngd = false;
for (self_blk, other_blk) in self.vec.iter_mut().zip(other.vec.iter()) {
let old_v = *self_blk;
let new_v = old_v & *other_blk;
if old_v != new_v {
*self_blk = new_v;
chngd = true;
}
}
chngd
}
pub fn or(&mut self, other: &Vob<T>) -> bool {
if self.len != other.len {
panic!("Cannot 'or' two Vobs of different length ({} {})", self.len, other.len);
}
let mut chngd = false;
for (self_blk, other_blk) in self.vec.iter_mut().zip(other.vec.iter()) {
let old_v = *self_blk;
let new_v = old_v | *other_blk;
if old_v != new_v {
*self_blk = new_v;
chngd = true;
}
}
chngd
}
pub fn xor(&mut self, other: &Vob<T>) -> bool {
if self.len != other.len {
panic!("Cannot 'xor' two Vobs of different length ({} {})", self.len, other.len);
}
let mut chngd = false;
for (self_blk, other_blk) in self.vec.iter_mut().zip(other.vec.iter()) {
let old_v = *self_blk;
let new_v = old_v ^ *other_blk;
if old_v != new_v {
*self_blk = new_v;
chngd = true;
}
}
self.mask_last_block();
chngd
}
fn mask_last_block(&mut self) {
let ub = self.len % bits_per_block::<T>();
if ub > 0 {
let msk = (T::one() << ub) - T::one();
let off = block_offset::<T>(self.len);
let old_v = self.vec[off];
let new_v = old_v & msk;
if new_v != old_v {
self.vec[off] = new_v;
}
}
}
}
impl Default for Vob<usize> {
fn default() -> Self {
Vob {
len: 0,
vec: Vec::new()
}
}
}
impl<T: Debug + One + PrimInt + Zero> Debug for Vob<T> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "Vob[")?;
for blk in self {
write!(fmt, "{}", if blk { 1 } else { 0 })?;
}
write!(fmt, "]")?;
Ok(())
}
}
impl<T: Debug + One + PrimInt + Zero> Extend<bool> for Vob<T> {
fn extend<I: IntoIterator<Item=bool>>(&mut self, iterable: I) {
let iterator = iterable.into_iter();
let (min, _) = iterator.size_hint();
self.reserve(min);
for e in iterator {
self.push(e)
}
}
}
impl FromIterator<bool> for Vob<usize> {
fn from_iter<I: IntoIterator<Item=bool>>(iter: I) -> Self {
let mut v = Vob::new();
v.extend(iter);
v
}
}
static TRUE: bool = true;
static FALSE: bool = false;
impl<T: Debug + One + PrimInt + Zero> Index<usize> for Vob<T> {
type Output = bool;
fn index(&self, index: usize) -> &bool {
match self.get(index) {
Some(true) => &TRUE,
Some(false) => &FALSE,
None => panic!("index out of bounds: the len is {} but the index is {}",
self.len,
index)
}
}
}
#[derive(Clone)]
pub struct Iter<'a, T: 'a> {
vob: &'a Vob<T>,
range: Range<usize>,
}
impl<'a, T: Debug + One + PrimInt + Zero> Iterator for Iter<'a, T> {
type Item = bool;
fn next(&mut self) -> Option<bool> {
self.range.next()
.map(|i| self.vob.get(i).unwrap())
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.range.size_hint()
}
}
impl<'a, T: Debug + One + PrimInt + Zero> DoubleEndedIterator for Iter<'a, T> {
fn next_back(&mut self) -> Option<bool> {
self.range.next_back()
.map(|i| self.vob.get(i).unwrap())
}
}
impl<'a, T: Debug + One + PrimInt + Zero> ExactSizeIterator for Iter<'a, T> { }
impl<'a, T: Debug + One + PrimInt + Zero> IntoIterator for &'a Vob<T> {
type Item = bool;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
#[derive(Clone)]
pub struct IterSetBits<'a, T: 'a> {
vob: &'a Vob<T>,
range: Range<usize>,
}
impl<'a, T: Debug + One + PrimInt + Zero> Iterator for IterSetBits<'a, T> {
type Item = usize;
fn next(&mut self) -> Option<usize> {
if let Some(mut i) = self.range.next() {
for b in block_offset::<T>(i) .. blocks_required::<T>(self.vob.len) {
let v = self.vob.vec[b];
if v != T::zero() {
let i_off = i % bits_per_block::<T>();
let tz = (v >> i_off).trailing_zeros() as usize;
if tz < bits_per_block::<T>() {
let bs = b * bits_per_block::<T>() + i_off + tz;
self.range.start = bs + 1;
return Some(bs);
}
}
i = b * bits_per_block::<T>();
}
}
self.range.start = self.range.end;
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.range.size_hint()
}
}
#[derive(Clone)]
pub struct IterUnsetBits<'a, T: 'a> {
vob: &'a Vob<T>,
range: Range<usize>,
}
impl<'a, T: Debug + One + PrimInt + Zero> Iterator for IterUnsetBits<'a, T> {
type Item = usize;
fn next(&mut self) -> Option<usize> {
if let Some(mut i) = self.range.next() {
for b in block_offset::<T>(i) .. blocks_required::<T>(self.vob.len) {
let v = self.vob.vec[b];
if v != T::max_value() {
let i_off = i % bits_per_block::<T>();
let tz = (!v >> i_off).trailing_zeros() as usize;
if tz < bits_per_block::<T>() {
let bs = b * bits_per_block::<T>() + i_off + tz;
self.range.start = bs + 1;
if bs >= self.vob.len {
break;
}
return Some(bs);
}
}
i = b * bits_per_block::<T>();
}
}
self.range.start = self.range.end;
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.range.size_hint()
}
}
impl<T: Debug + One + PrimInt + Zero> PartialEq for Vob<T> {
fn eq(&self, other: &Self) -> bool {
if self.len != other.len {
return false;
}
self.iter_storage()
.zip(other.iter_storage())
.all(|(w1, w2)| w1 == w2)
}
}
impl<T: Debug + One + PrimInt + Zero> Eq for Vob<T> {}
impl<T :Debug + Hash + One + PrimInt + Zero> Hash for Vob<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
for blk in self.iter_storage() {
blk.hash(state);
}
}
}
#[derive(Clone)]
pub struct StorageIter<'a, B: 'a> {
iter: slice::Iter<'a, B>,
}
impl<'a, T: Debug + One + PrimInt + Zero> Iterator for StorageIter<'a, T> {
type Item = T;
fn next(&mut self) -> Option<T> {
self.iter.next().cloned()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
fn bits_per_block<T>() -> usize {
size_of::<T>() * 8
}
fn block_offset<T>(off: usize) -> usize {
off / bits_per_block::<T>()
}
fn blocks_required<T>(num_bits: usize) -> usize {
num_bits / bits_per_block::<T>() + if num_bits % bits_per_block::<T>() == 0 {
0
} else {
1
}
}
#[macro_export]
macro_rules! vob {
(@single $($x:tt)*) => (());
(@count $($rest:expr),*) => (<[()]>::len(&[$(vob!(@single $rest)),*]));
($elem:expr; $n:expr) => (
$crate::Vob::from_elem($elem, $n)
);
() => (Vob::new());
($($x:expr),*) => ({
let c = vob!(@count $($x),*);
let mut vob = $crate::Vob::with_capacity(c);
$(
vob.push($x);
)*
vob
});
}
#[cfg(test)]
mod tests {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
use std::mem::size_of;
use super::{block_offset, blocks_required, Vob};
#[test]
fn test_block_offset() {
assert_eq!(block_offset::<usize>(0), 0);
assert_eq!(block_offset::<usize>(1), 0);
assert_eq!(block_offset::<usize>(2), 0);
assert_eq!(block_offset::<usize>(size_of::<usize>() * 8 - 1), 0);
assert_eq!(block_offset::<usize>(size_of::<usize>() * 8), 1);
}
#[test]
fn test_blocks_required() {
assert_eq!(blocks_required::<usize>(0), 0);
assert_eq!(blocks_required::<usize>(1), 1);
assert_eq!(blocks_required::<usize>(2), 1);
assert_eq!(blocks_required::<usize>(size_of::<usize>() * 8), 1);
assert_eq!(blocks_required::<usize>(size_of::<usize>() * 8 + 1), 2);
}
#[test]
fn test_non_usize_storage() {
let mut v = Vob::<u8>::new_with_storage_type(0);
for _ in 0..size_of::<u8>() * 8 {
v.push(true);
}
assert_eq!(v.get(0), Some(true));
assert_eq!(v.get(size_of::<u8>() * 8 - 1), Some(true));
assert_eq!(v.get(size_of::<u8>() * 8), None);
v.push(true);
assert_eq!(v.get(size_of::<u8>() * 8), Some(true));
v.set(size_of::<u8>() * 8, false);
assert_eq!(v.get(size_of::<u8>() * 8), Some(false));
assert_eq!(v.get(size_of::<u8>() * 8 + 1), None);
assert_eq!(v.set(size_of::<u8>() * 8, true), Some(true));
assert_eq!(v.set(size_of::<u8>() * 8, true), Some(false));
assert_eq!(v.get(size_of::<u8>() * 8 - 1), Some(true));
assert_eq!(v.get(size_of::<u8>() * 8 - 2), Some(true));
}
#[test]
fn test_capacity() {
assert_eq!(Vob::new().capacity(), 0);
assert_eq!(Vob::with_capacity(size_of::<usize>() * 8 + 1).capacity(),
size_of::<usize>() * 8 * 2);
}
#[test]
fn test_reserve() {
let mut v = Vob::new();
v.reserve(10);
assert_eq!(v.capacity(), size_of::<usize>() * 8);
v.reserve(size_of::<usize>() * 8);
assert_eq!(v.capacity(), size_of::<usize>() * 8 * 2);
}
#[test]
#[should_panic(expected = "Overflow detected")]
fn test_reserve_panic() {
let mut v = Vob::new();
v.reserve(5);
v.reserve(usize::max_value());
}
#[test]
fn test_beyond_a_word() {
let mut v = Vob::new();
for _ in 0..size_of::<usize>() * 8 {
v.push(true);
}
assert_eq!(v.get(0), Some(true));
assert_eq!(v.get(size_of::<usize>() * 8 - 1), Some(true));
assert_eq!(v.get(size_of::<usize>() * 8), None);
v.push(true);
assert_eq!(v.get(size_of::<usize>() * 8), Some(true));
v.set(size_of::<usize>() * 8, false);
assert_eq!(v.get(size_of::<usize>() * 8), Some(false));
assert_eq!(v.get(size_of::<usize>() * 8 + 1), None);
assert_eq!(v.set(size_of::<usize>() * 8, true), Some(true));
assert_eq!(v.set(size_of::<usize>() * 8, true), Some(false));
assert_eq!(v.get(size_of::<usize>() * 8 - 1), Some(true));
assert_eq!(v.get(size_of::<usize>() * 8 - 2), Some(true));
}
#[test]
fn test_truncate() {
let mut v = Vob::from_elem(2 * size_of::<usize>() * 8 + 1, true);
assert_eq!(v, Vob::from_elem(2 * size_of::<usize>() * 8 + 1, true));
v.truncate(2 * size_of::<usize>() * 8 + 1);
assert_eq!(v, Vob::from_elem(2 * size_of::<usize>() * 8 + 1, true));
v.truncate(3 * size_of::<usize>() * 8 + 1);
assert_eq!(v, Vob::from_elem(2 * size_of::<usize>() * 8 + 1, true));
v.truncate(0);
assert_eq!(v, Vob::new());
}
#[test]
fn test_is_empty() {
assert_eq!(vob![].is_empty(), true);
assert_eq!(vob![true].is_empty(), false);
}
#[test]
fn test_resize() {
let mut v = Vob::new();
v.resize(1, true);
assert_eq!(v[0], true);
let mut v = Vob::new();
v.push(false);
v.resize(129, true);
assert_eq!(v.len(), 129);
assert_eq!(v.get(0), Some(false));
assert_eq!(v.get(1), Some(true));
assert_eq!(v.get(128), Some(true));
v.resize(1, true);
assert_eq!(v.len(), 1);
assert_eq!(v.get(0), Some(false));
let mut v = Vob::new();
v.push(false);
v.resize(2, true);
assert_eq!(v.len(), 2);
assert_eq!(v.get(0), Some(false));
assert_eq!(v.get(1), Some(true));
}
#[test]
fn test_mask_last_block1() {
let mut v = Vob::<u64>::new_with_storage_type(0);
v.extend(vob![true, true].iter());
assert_eq!(v.vec, vec![3]);
v.vec[0] = 0xaaaaaaaa;
v.len = 7;
v.mask_last_block();
assert_eq!(v.vec, vec![42]);
v.len = 30;
v.vec[0] = 0xffffaaaa;
v.mask_last_block();
assert_eq!(v.vec, vec![1073719978]);
}
#[test]
fn test_mask_last_block2() {
let mut v = Vob::<u64>::new_with_storage_type(128);
for _ in 0..128 {
v.push(true);
}
let full_block = 0xffffffffffffffff;
assert_eq!(v.vec, vec![full_block, full_block]);
let one_zero = 0xaaaaaaaaaaaaaaaa;
v.len = 68;
v.vec[0] = one_zero;
v.vec[1] = v.vec[0];
v.mask_last_block();
assert_eq!(v.vec, vec![one_zero, 0b1010]);
}
#[test]
fn test_index() {
let v1 = vob![false, true];
assert_eq!(v1[0], false);
assert_eq!(v1[1], true);
}
#[test]
fn test_iter_set_bits() {
let mut v1 = vob![false, true, false, true];
assert_eq!(v1.iter_set_bits().collect::<Vec<usize>>(), vec![1, 3]);
v1.resize(127, false);
v1.push(true);
v1.push(false);
v1.push(true);
v1.push(true);
v1.resize(256, false);
v1.push(true);
assert_eq!(v1.iter_set_bits().collect::<Vec<usize>>(), vec![1, 3, 127, 129, 130, 256]);
}
#[test]
fn test_iter_unset_bits() {
let mut v1 = vob![false, true, false, false];
assert_eq!(v1.iter_unset_bits().collect::<Vec<usize>>(), vec![0, 2, 3]);
v1.resize(127, true);
v1.push(false);
v1.push(true);
v1.push(false);
v1.push(false);
v1.resize(256, true);
v1.push(false);
assert_eq!(v1.iter_unset_bits().collect::<Vec<usize>>(), vec![0, 2, 3, 127, 129, 130, 256]);
}
#[test]
fn test_eq() {
let v1 = Vob::<usize>::from_iter(vec![true, false]);
let v2 = Vob::from_iter(vec![true, false]);
assert_eq!(v1, v2);
let v3 = Vob::from_iter(vec![true, true]);
assert_ne!(v1, v3);
let v4 = Vob::from_iter(vec![true, false, true]);
assert_ne!(v1, v4);
}
#[test]
fn test_hash() {
fn hash<T: Hash>(t: &T) -> u64 {
let mut s = DefaultHasher::new();
t.hash(&mut s);
s.finish()
}
let v1 = vob![true, false];
let v2 = vob![false, true];
let v3 = vob![true, false];
assert_eq!(hash(&v1), hash(&v3));
assert_ne!(hash(&v1), hash(&v2));
assert_ne!(hash(&v2), hash(&v3));
}
#[test]
fn test_macros() {
let v1 = vob![true, false];
let mut v2 = Vob::new();
v2.push(true);
v2.push(false);
assert_eq!(v1, v2);
v2.set(1, true);
assert_eq!(v2, vob![2; true]);
assert_ne!(v2, vob![2; false]);
}
}