use crate::consts::{ConstIndex, ConstIterator};
use core::ops::*;
pub struct VAdd<T, L, R, LT, RT, const N: usize>
where
L: ConstIndex<LT, N> + Copy + Clone,
R: ConstIndex<RT, N> + Copy + Clone,
LT: Add<RT, Output = T>,
{
l: L,
r: R,
m: core::marker::PhantomData<(T, LT, RT)>,
}
impl<T, L, R, LT, RT, const N: usize> Copy for VAdd<T, L, R, LT, RT, N>
where
L: ConstIndex<LT, N> + Copy + Clone,
R: ConstIndex<RT, N> + Copy + Clone,
LT: Add<RT, Output = T>,
{
}
impl<T, L, R, LT, RT, const N: usize> Clone for VAdd<T, L, R, LT, RT, N>
where
L: ConstIndex<LT, N> + Copy + Clone,
R: ConstIndex<RT, N> + Copy + Clone,
LT: Add<RT, Output = T>,
{
fn clone(&self) -> Self { *self }
}
unsafe impl<T, L, R, LT, RT, const N: usize> ConstIndex<T, N> for VAdd<T, L, R, LT, RT, N>
where
L: ConstIndex<LT, N> + Copy + Clone,
R: ConstIndex<RT, N> + Copy + Clone,
LT: Add<RT, Output = T>,
{
#[inline]
fn i(self, index: usize) -> T {
let l = self.l.i(index);
let r = self.r.i(index);
l + r
}
}
impl<T, L, R, LT, RT, O, NT, const N: usize> Add<O> for VAdd<T, L, R, LT, RT, N>
where
L: ConstIndex<LT, N> + Copy + Clone,
R: ConstIndex<RT, N> + Copy + Clone,
LT: Add<RT, Output = T>,
O: ConstIndex<T, N> + Copy + Clone,
T: Add<T, Output = NT>,
{
type Output = VAdd<NT, Self, O, T, T, N>;
fn add(self, other: O) -> Self::Output {
VAdd {
l: self,
r: other,
m: Default::default(),
}
}
}
impl<T, L, R, LT, RT, const N: usize> VAdd<T, L, R, LT, RT, N>
where
L: ConstIndex<LT, N> + Copy + Clone,
R: ConstIndex<RT, N> + Copy + Clone,
LT: Add<RT, Output = T>,
{
pub fn new(l: L, r: R) -> Self {
Self {
l,
r,
m: Default::default(),
}
}
pub fn realize(self) -> crate::Vector<T, N> { ConstIterator::from(self).collect() }
}
#[cfg(test)]
pub(crate) const TESTLEN: usize = 777usize;
#[test]
fn calc_chain() {
use crate::Vector;
use rand::{thread_rng, Rng};
let mut rng = thread_rng();
let a: Vector<f32, TESTLEN> = rng.gen();
let b: Vector<f32, TESTLEN> = rng.gen();
let c: Vector<f32, TESTLEN> = rng.gen();
let d: Vector<f32, TESTLEN> = rng.gen();
let e: Vector<f32, TESTLEN> = rng.gen();
let ab = VAdd::new(a, b);
let abc = ab + c;
let abcd = abc + d;
let abcde = abcd + e;
let _res = abcde.realize();
}