Index2D and Array2D

master
Andrew Cassidy 2 years ago
parent 1abf9a6369
commit f275b1cf7a

2
.gitignore vendored

@ -1 +1,3 @@
/target
/Cargo.lock
.idea

@ -0,0 +1,98 @@
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))
}
}

@ -0,0 +1,28 @@
pub trait Index2D {
fn to_1d(&self, width: u32) -> u32 {
let (r, c) = self.to_2d(width);
r * width + c
}
fn to_2d(&self, width: u32) -> (u32, u32);
fn to_2d_offset(&self, width: u32, height: u32, r: u32, c: u32) -> Option<(u32, u32)> {
let (row, col) = self.to_2d(width);
if row >= height || col >= width {
return None;
};
Some((row + r, col + c))
}
}
impl Index2D for u32 {
fn to_2d(&self, width: u32) -> (u32, u32) {
(*self / width, *self % width)
}
}
impl Index2D for (u32, u32) {
fn to_2d(&self, _: u32) -> (u32, u32) {
*self
}
}

@ -0,0 +1,2 @@
mod array2d;
mod index2d;

@ -1,3 +0,0 @@
fn main() {
println!("Hello, world!");
}
Loading…
Cancel
Save