mirror of
https://github.com/drewcassidy/vector-victor.git
synced 2024-09-01 14:58:35 +00:00
Index2D and Array2D
This commit is contained in:
parent
1abf9a6369
commit
f275b1cf7a
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1,3 @@
|
||||
/target
|
||||
/Cargo.lock
|
||||
.idea
|
||||
|
98
src/array2d.rs
Normal file
98
src/array2d.rs
Normal file
@ -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))
|
||||
}
|
||||
}
|
28
src/index2d.rs
Normal file
28
src/index2d.rs
Normal file
@ -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
|
||||
}
|
||||
}
|
2
src/lib.rs
Normal file
2
src/lib.rs
Normal file
@ -0,0 +1,2 @@
|
||||
mod array2d;
|
||||
mod index2d;
|
@ -1,3 +0,0 @@
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
Loading…
Reference in New Issue
Block a user