You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
2.6 KiB
Rust
99 lines
2.6 KiB
Rust
use crate::index2d::Index2D;
|
|
|
|
pub trait Container2D {
|
|
type Output;
|
|
const HEIGHT: u32;
|
|
const WIDTH: u32;
|
|
|
|
fn get<I: Index2D>(&self, i: I) -> Option<&Self::Output>;
|
|
}
|
|
|
|
pub trait Container2DMut: Container2D {
|
|
fn get_mut<I: Index2D>(&mut self, i: I) -> Option<&mut Self::Output>;
|
|
}
|
|
|
|
/// A 2D owning array of T
|
|
#[derive(Debug)]
|
|
pub struct Array2D<T, const M: u32, const N: u32> {
|
|
pub data: [[T; N as usize]; M as usize],
|
|
}
|
|
|
|
impl<T, const M: u32, const N: u32> Container2D for Array2D<T, M, N> {
|
|
type Output = T;
|
|
const HEIGHT: u32 = M;
|
|
const WIDTH: u32 = N;
|
|
|
|
fn get<I: Index2D>(&self, i: I) -> Option<&Self::Output> {
|
|
let (r, c) = i.to_2d(Self::WIDTH);
|
|
self.data.get(r)?.get(c)
|
|
}
|
|
}
|
|
|
|
impl<T, const M: u32, const N: u32> Container2DMut for Array2D<T, M, N> {
|
|
fn get_mut<I: Index2D>(&mut self, i: I) -> Option<&mut Self::Output> {
|
|
let (r, c) = i.to_2d(Self::WIDTH);
|
|
self.data.get_mut(r)?.get_mut(c)
|
|
}
|
|
}
|
|
|
|
/// A 2D immutable view into a Container2D
|
|
#[derive(Debug)]
|
|
pub struct View2D<'a, D: Container2D, const M: u32, const N: u32> {
|
|
r: u32,
|
|
c: u32,
|
|
data: &'a D,
|
|
}
|
|
|
|
impl<'a, D: Container2D, const M: u32, const N: u32> Container2D for View2D<'a, D, M, N> {
|
|
type Output = D::Output;
|
|
const HEIGHT: u32 = M;
|
|
const WIDTH: u32 = N;
|
|
|
|
fn get<I: Index2D>(&self, i: I) -> Option<&Self::Output> {
|
|
self.data.get(i.to_2d_offset(Self::WIDTH, Self::HEIGHT, self.r, self.c)?)
|
|
}
|
|
}
|
|
|
|
impl<'a, D: Container2DMut, const M: u32, const N: u32> Container2D for Slice2D<'a, D, M, N> {
|
|
type Output = D::Output;
|
|
const HEIGHT: u32 = M;
|
|
const WIDTH: u32 = N;
|
|
|
|
fn get<I: Index2D>(&self, i: I) -> Option<&Self::Output> {
|
|
self.data.get(i.to_2d_offset(Self::WIDTH, Self::HEIGHT, self.r, self.c)?)
|
|
}
|
|
}
|
|
|
|
/// A 2D mutable view into a Container2D
|
|
#[derive(Debug)]
|
|
pub struct Slice2D<'a, D: Container2DMut, const M: u32, const N: u32> {
|
|
r: u32,
|
|
c: u32,
|
|
data: &'a mut D,
|
|
}
|
|
|
|
impl<'a, D: Container2DMut, const M: u32, const N: u32> Container2DMut
|
|
for Slice2D<'a, D, M, N>
|
|
{
|
|
fn get_mut<I: Index2D>(&mut self, i: I) -> Option<&mut Self::Output> {
|
|
self.data.get_mut(i.to_2d_offset(Self::WIDTH, Self::HEIGHT, self.r, self.c)?)
|
|
}
|
|
}
|
|
|
|
// An immutable transposition of a Container2D
|
|
#[derive(Debug)]
|
|
pub struct Transpose<'a, D: Container2D> {
|
|
pub data: &'a D,
|
|
}
|
|
|
|
impl<'a, D: Container2D> Container2D for Transpose<'a, D> {
|
|
type Output = D::Output;
|
|
const HEIGHT: u32 = D::WIDTH;
|
|
const WIDTH: u32 = D::HEIGHT;
|
|
|
|
fn get<I: Index2D>(&self, i: I) -> Option<&Self::Output> {
|
|
let (r, c) = i.to_2d(Self::WIDTH);
|
|
self.data.get((c, r))
|
|
}
|
|
}
|