mirror of
https://github.com/drewcassidy/vector-victor.git
synced 2024-09-01 14:58:35 +00:00
More messing around
This commit is contained in:
parent
96482fb0d1
commit
6491b7c692
@ -1,99 +0,0 @@
|
||||
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))
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
180
src/containers.rs
Normal file
180
src/containers.rs
Normal file
@ -0,0 +1,180 @@
|
||||
use index::Index2D;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
pub mod index;
|
||||
pub mod iter;
|
||||
|
||||
/// This trait exists to allow structs like Slice2D to require Get2D, without
|
||||
/// storing the dimensions of the target as part of its own generic parameters
|
||||
pub trait Get2D {
|
||||
type Scalar: Sized + Copy;
|
||||
const HEIGHT: usize;
|
||||
const WIDTH: usize;
|
||||
|
||||
fn get<I: Index2D>(&self, i: I) -> Option<&Self::Scalar>;
|
||||
}
|
||||
|
||||
pub trait Get2DMut: Get2D {
|
||||
fn get_mut<I: Index2D>(&mut self, i: I) -> Option<&mut Self::Scalar>;
|
||||
}
|
||||
|
||||
pub trait Get2DSized<const M: usize, const N: usize>: Get2D {}
|
||||
|
||||
/// A 2D owning array of T
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Array2D<T, const M: usize, const N: usize>
|
||||
where
|
||||
T: Copy + 'static,
|
||||
{
|
||||
pub data: [[T; N]; M],
|
||||
}
|
||||
|
||||
impl<T, const M: usize, const N: usize> Default for Array2D<T, M, N>
|
||||
where
|
||||
T: Default + Copy,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Array2D {
|
||||
data: [[T::default(); N]; M],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy, const M: usize, const N: usize> Get2D for Array2D<T, M, N> {
|
||||
type Scalar = T;
|
||||
const HEIGHT: usize = M;
|
||||
const WIDTH: usize = N;
|
||||
|
||||
fn get<I: Index2D>(&self, i: I) -> Option<&Self::Scalar> {
|
||||
let (r, c) = i.to_2d(Self::WIDTH);
|
||||
self.data.get(r)?.get(c)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy, const M: usize, const N: usize> Get2DMut for Array2D<T, M, N> {
|
||||
fn get_mut<I: Index2D>(&mut self, i: I) -> Option<&mut Self::Scalar> {
|
||||
let (r, c) = i.to_2d(Self::WIDTH);
|
||||
self.data.get_mut(r)?.get_mut(c)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy, const M: usize, const N: usize> Get2DSized<M, N> for Array2D<T, M, N> {}
|
||||
|
||||
/// A 2D mutable view into a container
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Slice2D<'a, R, const M: usize, const N: usize>
|
||||
where
|
||||
R: Deref,
|
||||
R::Target: Get2D + 'a,
|
||||
{
|
||||
target: R,
|
||||
r: usize,
|
||||
c: usize,
|
||||
phantom: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a, R, const M: usize, const N: usize> Slice2D<'a, R, M, N>
|
||||
where
|
||||
R: Deref,
|
||||
R::Target: Get2D + 'a,
|
||||
{
|
||||
pub fn new(target: R, r: usize, c: usize) -> Self {
|
||||
Self {
|
||||
target,
|
||||
r,
|
||||
c,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R, D, const M: usize, const N: usize> Get2D for Slice2D<'a, R, M, N>
|
||||
where
|
||||
R: Deref<Target = D>,
|
||||
D: Get2D,
|
||||
{
|
||||
type Scalar = <<R as Deref>::Target as Get2D>::Scalar;
|
||||
const HEIGHT: usize = M;
|
||||
const WIDTH: usize = N;
|
||||
|
||||
fn get<I: Index2D>(&self, i: I) -> Option<&Self::Scalar> {
|
||||
self.target
|
||||
.get(i.to_2d_offset(Self::WIDTH, Self::HEIGHT, self.r, self.c)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R, D, const M: usize, const N: usize> Get2DMut for Slice2D<'a, R, M, N>
|
||||
where
|
||||
R: Deref<Target = D> + DerefMut,
|
||||
D: Get2DMut,
|
||||
{
|
||||
fn get_mut<I: Index2D>(&mut self, i: I) -> Option<&mut Self::Scalar> {
|
||||
self.target
|
||||
.get_mut(i.to_2d_offset(Self::WIDTH, Self::HEIGHT, self.r, self.c)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R, D, const M: usize, const N: usize> Get2DSized<M, N> for Slice2D<'a, R, M, N>
|
||||
where
|
||||
R: Deref<Target = D>,
|
||||
D: Get2D,
|
||||
{
|
||||
}
|
||||
|
||||
// A transposition of a 2D container
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Transpose<'a, R>
|
||||
where
|
||||
R: Deref,
|
||||
R::Target: Get2D + 'a,
|
||||
{
|
||||
target: R,
|
||||
phantom: std::marker::PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a, R> Transpose<'a, R>
|
||||
where
|
||||
R: Deref,
|
||||
R::Target: Get2D + 'a,
|
||||
{
|
||||
fn new(target: R) -> Self {
|
||||
Self {
|
||||
target,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R, D> Get2D for Transpose<'a, R>
|
||||
where
|
||||
R: Deref<Target = D>,
|
||||
D: Get2D,
|
||||
{
|
||||
type Scalar = D::Scalar;
|
||||
const HEIGHT: usize = D::WIDTH;
|
||||
const WIDTH: usize = D::HEIGHT;
|
||||
|
||||
fn get<I: Index2D>(&self, i: I) -> Option<&Self::Scalar> {
|
||||
let (r, c) = i.to_2d(Self::WIDTH);
|
||||
self.target.get((c, r))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R, D> Get2DMut for Transpose<'a, R>
|
||||
where
|
||||
R: DerefMut<Target = D>,
|
||||
D: Get2DMut,
|
||||
{
|
||||
fn get_mut<I: Index2D>(&mut self, i: I) -> Option<&mut Self::Scalar> {
|
||||
let (r, c) = i.to_2d(Self::WIDTH);
|
||||
self.target.get_mut((c, r))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R, D, const M: usize, const N: usize> Get2DSized<M, N> for Transpose<'a, R>
|
||||
where
|
||||
R: Deref<Target = D>,
|
||||
D: Get2DSized<N, M>,
|
||||
{
|
||||
}
|
34
src/containers/index.rs
Normal file
34
src/containers/index.rs
Normal file
@ -0,0 +1,34 @@
|
||||
pub trait Index2D: Copy {
|
||||
fn to_1d(&self, width: usize) -> usize {
|
||||
let (r, c) = self.to_2d(width);
|
||||
r * width + c
|
||||
}
|
||||
|
||||
fn to_2d(&self, width: usize) -> (usize, usize);
|
||||
|
||||
fn to_2d_offset(
|
||||
&self,
|
||||
width: usize,
|
||||
height: usize,
|
||||
r: usize,
|
||||
c: usize,
|
||||
) -> Option<(usize, usize)> {
|
||||
let (row, col) = self.to_2d(width);
|
||||
if row >= height || col >= width {
|
||||
return None;
|
||||
};
|
||||
Some((row + r, col + c))
|
||||
}
|
||||
}
|
||||
|
||||
impl Index2D for usize {
|
||||
fn to_2d(&self, width: usize) -> (usize, usize) {
|
||||
(*self / width, *self % width)
|
||||
}
|
||||
}
|
||||
|
||||
impl Index2D for (usize, usize) {
|
||||
fn to_2d(&self, _: usize) -> (usize, usize) {
|
||||
*self
|
||||
}
|
||||
}
|
39
src/containers/iter.rs
Normal file
39
src/containers/iter.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use super::Get2D;
|
||||
use std::iter::FusedIterator;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub(crate) struct ElementIter<'a, D>
|
||||
where
|
||||
D: Get2D,
|
||||
{
|
||||
data: &'a D,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl<'a, D: Get2D> ElementIter<'a, D> {
|
||||
pub(crate) fn new(data: &'a D) -> ElementIter<D> {
|
||||
ElementIter { data, index: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, D: Get2D> Iterator for ElementIter<'a, D> {
|
||||
type Item = &'a D::Scalar;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let result = self.data.get(self.index);
|
||||
self.index += 1;
|
||||
result
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let total = D::WIDTH * D::HEIGHT;
|
||||
(total - self.index, Some(total - self.index))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, D: Get2D> ExactSizeIterator for ElementIter<'a, D> {
|
||||
fn len(&self) -> usize {
|
||||
self.index - D::WIDTH * D::HEIGHT
|
||||
}
|
||||
}
|
||||
impl<'a, D: Get2D> FusedIterator for ElementIter<'a, D> {}
|
@ -1,2 +1,2 @@
|
||||
mod Container2D;
|
||||
mod Index2D;
|
||||
mod containers;
|
||||
mod matrix;
|
||||
|
90
src/matrix.rs
Normal file
90
src/matrix.rs
Normal file
@ -0,0 +1,90 @@
|
||||
use crate::containers::index::Index2D;
|
||||
use crate::containers::iter::ElementIter;
|
||||
use crate::containers::{Array2D, Get2D, Get2DMut, Get2DSized, Slice2D};
|
||||
use std::ops::{Add, Index, IndexMut};
|
||||
|
||||
type Matrix<T: Copy, const M: usize, const N: usize> = GenericMatrix<Array2D<T, M, N>, M, N>;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct GenericMatrix<D: Get2DSized<M, N>, const M: usize, const N: usize> {
|
||||
data: D,
|
||||
}
|
||||
|
||||
impl<D: Get2DSized<M, N>, const M: usize, const N: usize> GenericMatrix<D, M, N> {
|
||||
fn elements(&self) -> ElementIter<GenericMatrix<D, M, N>> {
|
||||
ElementIter::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Get2DSized<M, N> + Copy, const M: usize, const N: usize> Default for GenericMatrix<D, M, N>
|
||||
where
|
||||
D: Default,
|
||||
{
|
||||
fn default() -> Self {
|
||||
GenericMatrix { data: D::default() }
|
||||
}
|
||||
}
|
||||
// impl<D: Get2D + Copy, const M: usize, const N: usize> Matrix<D, M, N>
|
||||
// where
|
||||
// D::Scalar: Default,
|
||||
// {
|
||||
// fn new(data: &[&[D::Scalar]]) -> Result<Self, &'static str> {}
|
||||
// }
|
||||
|
||||
impl<D: Get2DSized<M, N>, const M: usize, const N: usize> Get2D for GenericMatrix<D, M, N> {
|
||||
type Scalar = D::Scalar;
|
||||
const HEIGHT: usize = D::HEIGHT;
|
||||
const WIDTH: usize = D::WIDTH;
|
||||
|
||||
fn get<I: Index2D>(&self, i: I) -> Option<&Self::Scalar> {
|
||||
self.data.get(i)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Get2DMut + Get2DSized<M, N>, const M: usize, const N: usize> Get2DMut
|
||||
for GenericMatrix<D, M, N>
|
||||
{
|
||||
fn get_mut<I: Index2D>(&mut self, i: I) -> Option<&mut Self::Scalar> {
|
||||
self.data.get_mut(i)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Get2DSized<M, N>, I: Index2D, const M: usize, const N: usize> Index<I>
|
||||
for GenericMatrix<D, M, N>
|
||||
{
|
||||
type Output = D::Scalar;
|
||||
|
||||
fn index(&self, index: I) -> &Self::Output {
|
||||
self.get(index).expect(&*format!(
|
||||
"Index {:?} out of range for {} x {} matrix",
|
||||
index.to_2d(D::WIDTH),
|
||||
D::HEIGHT,
|
||||
D::WIDTH
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Get2DMut + Get2DSized<M, N>, I: Index2D, const M: usize, const N: usize> IndexMut<I>
|
||||
for GenericMatrix<D, M, N>
|
||||
{
|
||||
fn index_mut(&mut self, index: I) -> &mut Self::Output {
|
||||
self.get_mut(index).expect(&*format!(
|
||||
"Index {:?} out of range for {} x {} matrix",
|
||||
index.to_2d(D::WIDTH),
|
||||
D::HEIGHT,
|
||||
D::WIDTH
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Get2DSized<M, N>, const M: usize, const N: usize> Get2DSized<M, N>
|
||||
for GenericMatrix<D, M, N>
|
||||
{
|
||||
}
|
||||
|
||||
fn foo() {
|
||||
let mut a: Matrix<i32, 5, 5> = Default::default();
|
||||
let c = Slice2D::<&Matrix<i32, 5, 5>, 3, 3>::new(&a, 2, 2);
|
||||
let b = Slice2D::<&mut Matrix<i32, 5, 5>, 3, 3>::new(&mut a, 1, 1);
|
||||
println!("{:?} {:?}", b, c)
|
||||
}
|
Loading…
Reference in New Issue
Block a user