use core::slice;
use std::ops::Index;
#[derive(Default, Clone, Debug)]
pub struct Matrix {
rows: Vec<Vec<usize>>,
}
impl Matrix {
pub fn len(&self) -> usize {
self.rows.len()
}
pub fn is_empty(&self) -> bool {
self.rows.len() == 0
}
pub fn with_capacity(capacity: usize) -> Self {
Matrix {
rows: Vec::with_capacity(capacity),
}
}
pub fn push_row_single_value(&mut self, idx: usize) {
self.rows.push(vec![idx])
}
pub(crate) fn push_row_empty(&mut self) {
self.rows.push(vec![])
}
pub fn to_evals(&self) -> Vec<(usize, usize)> {
let mut evals = Vec::with_capacity(self.rows.len());
for (i, cols) in self.rows.iter().enumerate() {
for col in cols {
evals.push((i, *col));
}
}
evals
}
pub fn get_row(&self, index: usize) -> Option<&[usize]> {
self.rows.get(index).map(Vec::as_slice)
}
pub fn iter(&self) -> CellIter<'_> {
let mut rows = self.rows.iter();
let current_row = rows.next().expect("matrix is empty").iter();
CellIter {
rows,
current_row,
current_row_idx: 0,
}
}
}
impl Index<usize> for Matrix {
type Output = [usize];
fn index(&self, index: usize) -> &Self::Output {
&self.rows[index]
}
}
pub struct CellIter<'a> {
rows: slice::Iter<'a, Vec<usize>>,
current_row: slice::Iter<'a, usize>,
current_row_idx: usize,
}
impl Iterator for CellIter<'_> {
type Item = (usize, usize);
fn next(&mut self) -> Option<Self::Item> {
let idx = self.current_row_idx;
match self.current_row.next() {
Some(c) => Some((idx, *c)),
None => {
let new_row = loop {
let row = self.rows.next()?;
self.current_row_idx += 1;
if !row.is_empty() {
break row;
}
};
let mut new_row = new_row.iter();
let next = new_row.next();
self.current_row = new_row;
next.copied().map(|j| (self.current_row_idx, j))
}
}
}
}