pub struct Board<T> {
stride: usize,
buffer: Box<[T]>,
}
impl<T> Board<T> {
pub fn filled(shape: (usize, usize), value: T) -> Self
where
T: Clone,
{
let (width, height) = shape;
Self {
stride: width,
buffer: vec![value; width * height].into_boxed_slice(),
}
}
pub fn flat(&self) -> &[T] {
&self.buffer
}
}
impl<T> std::ops::Index<usize> for Board<T> {
type Output = [T];
fn index(&self, index: usize) -> &Self::Output {
&self.buffer[index * self.stride..(index + 1) * self.stride]
}
}
impl<T> std::ops::IndexMut<usize> for Board<T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.buffer[index * self.stride..(index + 1) * self.stride]
}
}
pub struct Iter<'a, T> {
board: &'a Board<T>,
i: usize,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a [T];
fn next(&mut self) -> Option<Self::Item> {
if self.i < self.board.buffer.len() {
let i = self.i;
self.i = i + self.board.stride;
Some(&self.board.buffer[i..self.i])
} else {
None
}
}
}
impl<'a, T> IntoIterator for &'a Board<T> {
type Item = &'a [T];
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
Iter {
board: self,
i: 0,
}
}
}