use crate::types::Size;
#[derive(Clone, Debug)]
pub struct FdmLinearOpIterator {
index: Size,
dim: Vec<Size>,
coordinates: Vec<Size>,
}
impl FdmLinearOpIterator {
pub fn new(dim: Vec<Size>) -> Self {
let coordinates = vec![0; dim.len()];
FdmLinearOpIterator {
index: 0,
dim,
coordinates,
}
}
pub fn with_coordinates(dim: Vec<Size>, coordinates: Vec<Size>, index: Size) -> Self {
FdmLinearOpIterator {
index,
dim,
coordinates,
}
}
pub fn index(&self) -> Size {
self.index
}
pub fn coordinates(&self) -> &[Size] {
&self.coordinates
}
pub fn advance(&mut self) {
self.index += 1;
for i in 0..self.dim.len() {
self.coordinates[i] += 1;
if self.coordinates[i] == self.dim[i] {
self.coordinates[i] = 0;
} else {
break;
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn advance_walks_row_major_with_dimension_zero_fastest() {
let dim = vec![5, 7, 8];
let mut iter = FdmLinearOpIterator::new(dim.clone());
assert_eq!(iter.index(), 0);
assert_eq!(iter.coordinates(), [0, 0, 0]);
for m in 0..dim[2] {
for l in 0..dim[1] {
for k in 0..dim[0] {
assert_eq!(iter.coordinates(), [k, l, m]);
assert_eq!(iter.index(), k + l * dim[0] + m * dim[0] * dim[1]);
iter.advance();
}
}
}
assert_eq!(iter.index(), 5 * 7 * 8);
assert_eq!(iter.coordinates(), [0, 0, 0]);
}
}