pub mod combinate;
pub mod backends;
use crate::{
range::{
Range0To,
RangeBoundsTimes,
RangeBoundsPlus,
BoundRange,
},
};
use mint::Vector3;
use std::{
ops::RangeBounds,
fmt::Debug,
};
pub fn alloc<I, T>(x_len: i32, y_len: i32, z_len: i32, startval: T) -> backends::heap::ArrayGrid3<T>
where
T: Clone
{
backends::heap::ArrayGrid3::broadcast(x_len, y_len, z_len, startval)
}
pub fn alloc_gen<I, T, F>(x_len: i32, y_len: i32, z_len: i32, generator: F) -> backends::heap::ArrayGrid3<T>
where
I: From<Vector3<i32>>,
F: FnMut(I) -> T,
{
backends::heap::ArrayGrid3::new(x_len, y_len, z_len, generator)
}
pub fn array3x3x3<I, T>(startval: T) -> backends::inline3x3x3::Inline3x3x3Grid<T>
where
T: Clone
{
backends::inline3x3x3::Inline3x3x3Grid::broadcast(startval)
}
pub fn array3x3x3_gen<I, T, F>(generator: F) -> backends::inline3x3x3::Inline3x3x3Grid<T>
where
I: From<Vector3<i32>>,
F: FnMut(I) -> T,
{
backends::inline3x3x3::Inline3x3x3Grid::new(generator)
}
pub fn value_fn<I, T, F>(f: F) -> backends::kolmo::KolmoGrid3<F, I, T>
where
I: From<Vector3<i32>>,
F: Fn(I) -> T,
{
backends::kolmo::KolmoGrid3::new(f)
}
pub fn ref_fn<'a, I, T, F>(f: F) -> backends::kolmoref::KolmoRefGrid3<'a, F, I, T>
where
I: From<Vector3<i32>>,
T: 'a,
F: Fn(I) -> &'a T,
{
backends::kolmoref::KolmoRefGrid3::new(f)
}
pub fn mut_fn<'a, I, T, F>(f: F) -> backends::kolmomut::KolmoMutGrid3<'a, F, I, T>
where
I: From<Vector3<i32>>,
T: 'a,
F: Fn(I) -> &'a mut T,
{
backends::kolmomut::KolmoMutGrid3::new(f)
}
pub fn reader_writer<I, R, T, Fr, Fw>(referent: R, reader: Fr, writer: Fw) -> backends::kolmorw::KolmoRwGrid3<I, R, T, Fr, Fw>
where
I: From<Vector3<i32>>,
Fr: Fn(I, &R) -> &T,
Fw: Fn(I, &mut R) -> &mut T,
{
backends::kolmorw::KolmoRwGrid3::new(referent, reader, writer)
}
pub trait Grid3 {
type Item;
type XBound: RangeBounds<i32>;
type YBound: RangeBounds<i32>;
type ZBound: RangeBounds<i32>;
fn x_bound(&self) -> Self::XBound;
fn y_bound(&self) -> Self::YBound;
fn z_bound(&self) -> Self::ZBound;
fn in_bounds<I>(&self, coord: I) -> bool
where
I: Into<Vector3<i32>>
{
let Vector3 { x, y, z } = coord.into();
self.x_bound().contains(&x)
&& self.y_bound().contains(&y)
&& self.z_bound().contains(&z)
}
fn map<F, T>(self, func: F) -> combinate::map::Grid3Map<Self, F, T>
where
Self: Sized,
F: Fn(Self::Item) -> T,
{
combinate::map::Grid3Map::new(self, func)
}
fn enumap<I, F, T>(self, func: F) -> combinate::enumap::Grid3EnuMap<Self, F, T, I>
where
Self: Sized,
I: From<Vector3<i32>>,
F: Fn(I, Self::Item) -> T,
{
combinate::enumap::Grid3EnuMap::new(self, func)
}
fn flatten<I>(self, stride: I) -> combinate::flatten::Grid3Flat<Self>
where
Self: Sized,
Self::Item: Grid3,
Self::XBound: Clone + RangeBoundsTimes,
Self::YBound: Clone + RangeBoundsTimes,
Self::ZBound: Clone + RangeBoundsTimes,
I: Into<Vector3<i32>>,
{
combinate::flatten::Grid3Flat::new(self, stride)
}
fn new_origin<I>(self, new_origin: I) -> combinate::neworigin::Grid3NewOrigin<Self>
where
Self: Sized,
Self::XBound: RangeBoundsPlus,
Self::YBound: RangeBoundsPlus,
Self::ZBound: RangeBoundsPlus,
I: Into<Vector3<i32>>,
{
combinate::neworigin::Grid3NewOrigin::new(self, new_origin)
}
fn oob_handler<I, F>(self, handler: F) -> combinate::oobhandler::Grid3OobHandler<Self, I, F>
where
Self: Sized,
I: From<Vector3<i32>>,
F: Fn(I) -> Self::Item,
{
combinate::oobhandler::Grid3OobHandler::new(self, handler)
}
fn subview<X, Y, Z>(self, new_x: X, new_y: Y, new_z: Z) -> combinate::slice::Grid3Slice<Self, X, Y, Z>
where
Self: Sized,
Self::XBound: Debug,
Self::YBound: Debug,
Self::ZBound: Debug,
X: RangeBounds<i32> + Clone + Debug,
Y: RangeBounds<i32> + Clone + Debug,
Z: RangeBounds<i32> + Clone + Debug,
{
combinate::slice::Grid3Slice::new(self, new_x, new_y, new_z)
}
fn try_subview<X, Y, Z>(self, new_x: X, new_y: Y, new_z: Z) -> Result<combinate::slice::Grid3Slice<Self, X, Y, Z>, Self>
where
Self: Sized,
Self::XBound: Debug,
Self::YBound: Debug,
X: RangeBounds<i32> + Clone + Debug,
Y: RangeBounds<i32> + Clone + Debug,
Z: RangeBounds<i32> + Clone + Debug,
{
combinate::slice::Grid3Slice::try_new(self, new_x, new_y, new_z)
}
fn subview_0to(self, new_x_len: i32, new_y_len: i32, new_z_len: i32) -> combinate::slice::Grid3Slice<Self, Range0To, Range0To, Range0To>
where
Self: Sized,
Self::XBound: Debug,
Self::YBound: Debug,
Self::ZBound: Debug,
{
combinate::slice::Grid3Slice::new(
self,
Range0To { end: new_x_len },
Range0To { end: new_y_len },
Range0To { end: new_z_len })
}
fn try_subview_0to(self, new_x_len: i32, new_y_len: i32, new_z_len: i32) -> Result<combinate::slice::Grid3Slice<Self, Range0To, Range0To, Range0To>, Self>
where
Self: Sized,
Self::XBound: Debug,
Self::YBound: Debug,
Self::ZBound: Debug,
{
combinate::slice::Grid3Slice::try_new(
self,
Range0To { end: new_x_len },
Range0To { end: new_y_len },
Range0To { end: new_z_len },)
}
fn wrapping(self) -> combinate::wrapping::Grid3Wrapping<Self>
where
Self: Sized,
Self::XBound: BoundRange,
Self::YBound: BoundRange,
Self::ZBound: BoundRange,
{
combinate::wrapping::Grid3Wrapping::new(self)
}
fn collect(&self) -> backends::heap::ArrayGrid3<Self::Item>
where
Self: Grid3Get,
Self::XBound: Into<Range0To>,
Self::YBound: Into<Range0To>,
Self::ZBound: Into<Range0To>,
{
let x_len = self.x_bound().into().end;
let y_len = self.y_bound().into().end;
let z_len = self.y_bound().into().end;
backends::heap::ArrayGrid3::new(
x_len, y_len, z_len,
|coord: Vector3<i32>| self.get(coord))
}
}
pub trait Grid3Len: Grid3<XBound=Range0To, YBound=Range0To, ZBound=Range0To> {
fn x_len(&self) -> i32 {
self.x_bound().end
}
fn y_len(&self) -> i32 {
self.y_bound().end
}
fn z_len(&self) -> i32 {
self.z_bound().end
}
}
pub trait Grid3Get: Grid3 {
fn get<I>(&self, coord: I) -> Self::Item
where
I: Into<Vector3<i32>>;
fn try_get<I>(&self, coord: I) -> Option<Self::Item>
where
I: Into<Vector3<i32>>
{
let coord = coord.into();
if self.in_bounds(coord) {
Some(self.get(coord))
} else {
None
}
}
}
pub trait Grid3Set: Grid3 {
fn set<I>(&mut self, coord: I, elem: Self::Item)
where
I: Into<Vector3<i32>>;
fn try_set<I>(&mut self, coord: I, elem: Self::Item) -> Result<(), Self::Item>
where
I: Into<Vector3<i32>>
{
let coord = coord.into();
if self.in_bounds(coord) {
self.set(coord, elem);
Ok({})
} else {
Err(elem)
}
}
}
pub trait Grid3Ref: Grid3 {
fn idx<I>(&self, coord: I) -> &Self::Item
where
I: Into<Vector3<i32>>;
fn try_idx<I>(&self, coord: I) -> Option<&Self::Item>
where
I: Into<Vector3<i32>>
{
let coord = coord.into();
if self.in_bounds(coord) {
Some(self.idx(coord))
} else {
None
}
}
}
pub trait Grid3Mut: Grid3 {
fn midx<I>(&mut self, coord: I) -> &mut Self::Item
where
I: Into<Vector3<i32>>;
fn try_midx<I>(&mut self, coord: I) -> Option<&mut Self::Item>
where
I: Into<Vector3<i32>>
{
let coord = coord.into();
if self.in_bounds(coord) {
Some(self.midx(coord))
} else {
None
}
}
}