use core::iter::IntoIterator;
use core::ops::{Add, Index, IndexMut, Mul, Sub};
use core::slice;
use super::Point;
use num_traits::Float;
#[derive(Debug, Copy, Clone)]
pub struct PointN<T, const N: usize>([T; N]);
impl<T, const N: usize> PointN<T, N> {
pub fn new(array: [T; N]) -> Self {
PointN(array)
}
}
impl<T: Default + Copy, const N: usize> Default for PointN<T, N> {
fn default() -> Self {
PointN([T::default(); N])
}
}
impl<T, const N: usize> PartialEq for PointN<T, N>
where
T: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
for i in 0..N {
if self.0[i] != other.0[i] {
return false;
}
}
true
}
}
impl<T, const N: usize> Add for PointN<T, N>
where
T: Add<Output = T> + Copy,
{
type Output = Self;
fn add(self, other: PointN<T, N>) -> PointN<T, N> {
let mut res = self;
for i in 0..N {
res.0[i] = self.0[i] + other.0[i];
}
res
}
}
impl<T, const N: usize> Add<T> for PointN<T, N>
where
T: Add<Output = T> + Copy,
{
type Output = Self;
fn add(self, _rhs: T) -> PointN<T, N> {
let mut res = self;
for i in 0..N {
res.0[i] = self.0[i] + _rhs;
}
res
}
}
impl<T, const N: usize> Sub for PointN<T, N>
where
T: Sub<Output = T> + Copy,
{
type Output = Self;
fn sub(self, other: PointN<T, N>) -> PointN<T, N> {
let mut res = self;
for i in 0..N {
res.0[i] = self.0[i] - other.0[i];
}
res
}
}
impl<T, const N: usize> Sub<T> for PointN<T, N>
where
T: Sub<Output = T> + Copy,
{
type Output = Self;
fn sub(self, _rhs: T) -> PointN<T, N> {
let mut res = self;
for i in 0..N {
res.0[i] = self.0[i] - _rhs;
}
res
}
}
impl<T, const N: usize, U> Mul<U> for PointN<T, N>
where
T: Mul<U, Output = T> + Copy, U: Clone + Copy,
{
type Output = PointN<T, N>;
fn mul(self, _rhs: U) -> PointN<T, N> {
let mut res = self;
for i in 0..res.0.len() {
res.0[i] = res.0[i] * _rhs;
}
res
}
}
impl<T, const N: usize> IntoIterator for PointN<T, N> {
type Item = T;
type IntoIter = core::array::IntoIter<Self::Item, N>;
fn into_iter(self) -> Self::IntoIter {
IntoIterator::into_iter(self.0)
}
}
impl<'a, T, const N: usize> IntoIterator for &'a mut PointN<T, N> {
type Item = &'a mut T;
type IntoIter = slice::IterMut<'a, T>;
fn into_iter(self) -> slice::IterMut<'a, T> {
self.0.iter_mut()
}
}
impl<T, const N: usize> Index<usize> for PointN<T, N> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.0[index]
}
}
impl<T, const N: usize> IndexMut<usize> for PointN<T, N> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.0[index]
}
}
impl<T, const N: usize> Point for PointN<T, N>
where
T: Float,
{
type Scalar = T;
const DIM: usize = N;
}