use building_blocks_core::{ConstZero, IntegerPoint, PointN};
use core::ops::{Add, AddAssign, Deref, Mul, Sub, SubAssign};
use num::Zero;
#[derive(Debug, Eq, PartialEq)]
pub struct Local<N>(pub PointN<N>);
pub type Local2i = Local<[i32; 2]>;
pub type Local3i = Local<[i32; 3]>;
impl<N> Clone for Local<N>
where
PointN<N>: Clone,
{
fn clone(&self) -> Self {
Local(self.0.clone())
}
}
impl<N> Copy for Local<N> where PointN<N>: Copy {}
impl<N> Local<N> {
#[inline]
pub fn localize_points_slice(points: &[PointN<N>]) -> Vec<Local<N>>
where
PointN<N>: Clone,
{
points.iter().cloned().map(Local).collect()
}
#[inline]
pub fn localize_points_array<const LEN: usize>(points: &[PointN<N>; LEN]) -> [Local<N>; LEN]
where
PointN<N>: ConstZero,
{
let mut locals = [Local(PointN::ZERO); LEN];
for (l, p) in locals.iter_mut().zip(points.iter()) {
*l = Local(*p);
}
locals
}
}
impl<N> Deref for Local<N> {
type Target = PointN<N>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct Stride(pub usize);
impl Zero for Stride {
#[inline]
fn zero() -> Self {
Stride(0)
}
#[inline]
fn is_zero(&self) -> bool {
self.0 == 0
}
}
impl Add for Stride {
type Output = Self;
#[inline]
fn add(self, rhs: Self) -> Self::Output {
Self(self.0.wrapping_add(rhs.0))
}
}
impl Sub for Stride {
type Output = Self;
#[inline]
fn sub(self, rhs: Self) -> Self::Output {
Self(self.0.wrapping_sub(rhs.0))
}
}
impl Mul<usize> for Stride {
type Output = Self;
#[inline]
fn mul(self, rhs: usize) -> Self::Output {
Self(self.0.wrapping_mul(rhs))
}
}
impl AddAssign for Stride {
#[inline]
fn add_assign(&mut self, rhs: Self) {
*self = *self + rhs;
}
}
impl SubAssign for Stride {
#[inline]
fn sub_assign(&mut self, rhs: Self) {
*self = *self - rhs;
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ChunkUnits<N>(pub PointN<N>);
pub type ChunkUnits2 = ChunkUnits<[i32; 2]>;
pub type ChunkUnits3 = ChunkUnits<[i32; 3]>;
impl<N> ChunkUnits<N>
where
PointN<N>: IntegerPoint<N>,
{
pub fn chunk_min(&self, chunk_shape: PointN<N>) -> PointN<N> {
chunk_shape * self.0
}
}