#[cfg(test)]
mod tests;
use std::{
fmt,
ops::{Index, IndexMut}
};
use bitvec::{
order::Lsb0,
slice::{BitSlice, ChunksExact, ChunksExactMut, Iter, IterMut},
boxed::BitBox,
vec::BitVec,
};
#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
#[derive(Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct BitMatrix {
storage: BitBox<Lsb0, usize>,
height: usize,
width: usize,
}
impl BitMatrix {
pub fn new(height: usize, width: usize) -> Self {
let size = height * width;
let mut vec = BitVec::with_capacity(size);
vec.resize(size, false);
Self {
storage: vec.into_boxed_bitslice(),
height,
width
}
}
pub fn height(&self) -> usize {
self.height
}
pub fn width(&self) -> usize {
self.width
}
fn row_ix(&self, i: usize) -> usize {
i * self.width
}
pub fn iter(&self) -> Iter<Lsb0, usize> {
self.storage.iter()
}
pub fn iter_mut(&mut self) -> IterMut<Lsb0, usize> {
self.storage.iter_mut()
}
pub fn rows(&self) -> ChunksExact<Lsb0, usize> {
self.storage.chunks_exact(self.width)
}
pub fn rows_mut(&mut self) -> ChunksExactMut<Lsb0, usize> {
self.storage.chunks_exact_mut(self.width)
}
pub fn set(&mut self, (i, j): (usize, usize), value: bool) {
self[i].set(j, value);
}
pub fn set_all(&mut self, value: bool) {
self.storage.set_all(value);
}
}
impl Index<usize> for BitMatrix {
type Output = BitSlice;
fn index(&self, index: usize) -> &Self::Output {
let begin = self.row_ix(index);
let end = self.row_ix(index + 1);
&self.storage[begin .. end]
}
}
impl IndexMut<usize> for BitMatrix {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
let begin = self.row_ix(index);
let end = self.row_ix(index + 1);
&mut self.storage[begin .. end]
}
}
impl Index<(usize, usize)> for BitMatrix {
type Output = bool;
fn index(&self, (i, j): (usize, usize)) -> &Self::Output {
&self[i][j]
}
}
impl fmt::Debug for BitMatrix {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for row in self.rows() {
for item in row.into_iter() {
write!(f, "{}", *item as u8)?;
}
writeln!(f)?;
}
Ok(())
}
}