use hibitset::BitSet;
#[derive(Debug, Clone)]
pub struct HalfMatrix {
size: u32,
index_size: u32,
collision_matrix: BitSet,
}
impl HalfMatrix {
pub fn new(size: u32) -> Self {
if size > 5792 {
panic!("Size of HalfMatrix too big! Maximum size is 5792 and requested size is {}.", size);
}
let index_size = (size * (size + 1)) / 2;
HalfMatrix {
size,
index_size,
collision_matrix: BitSet::with_capacity(index_size),
}
}
pub fn size(&self) -> u32 {
self.size
}
pub fn enable(&mut self, row: u32, column: u32) {
self.collision_matrix.add(self.index_of(row, column));
}
pub fn disable(&mut self, row: u32, column: u32) {
self.collision_matrix.remove(self.index_of(row, column));
}
pub fn contains(&self, row: u32, column: u32) -> bool {
self.collision_matrix.contains(self.index_of(row, column))
}
pub(crate) fn index_of(&self, row: u32, column: u32) -> u32 {
let (a, b) = if row >= column {
(row, column)
} else {
(column, row)
};
let row_sum = (a * (a + 1)) / 2;
let idx = row_sum + b;
assert!(idx < self.index_size);
idx
}
}
#[cfg(test)]
mod tests {
use crate::*;
#[test]
fn index_calculation() {
let m = HalfMatrix::new(4);
assert_eq!(m.index_of(2,2), 5);
}
#[should_panic]
#[test]
fn index_of_fail() {
let m = HalfMatrix::new(1);
m.index_of(0, 1);
}
#[test]
fn index_calculation2() {
let m = HalfMatrix::new(4);
assert_eq!(m.index_of(3,2), 8);
}
#[test]
fn max_size_okay() {
let size = 5792;
HalfMatrix::new(size);
}
#[test]
#[should_panic]
fn max_size_too_big() {
let size = 5793;
HalfMatrix::new(size);
}
#[test]
fn enable() {
let mut m = HalfMatrix::new(3);
m.enable(2, 0);
m.enable(2, 2);
m.enable(0, 0);
assert!(m.contains(2,0));
assert!(m.contains(2,2));
assert!(m.contains(0,0));
assert!(!m.contains(1,0));
assert!(!m.contains(1,1));
assert!(!m.contains(2,1));
}
#[test]
fn out_of_range_swap() {
let m = HalfMatrix::new(3);
m.contains(0,1);
}
}