1use crate::consts::{ConstIndex, ConstIterator};
19use core::ops::*;
20
21pub struct VAdd<T, L, R, LT, RT, const N: usize>
22where
23 L: ConstIndex<LT, N> + Copy + Clone,
26 R: ConstIndex<RT, N> + Copy + Clone,
27 LT: Add<RT, Output = T>,
28{
29 l: L,
30 r: R,
31 m: core::marker::PhantomData<(T, LT, RT)>,
32}
33
34impl<T, L, R, LT, RT, const N: usize> Copy for VAdd<T, L, R, LT, RT, N>
35where
36 L: ConstIndex<LT, N> + Copy + Clone,
37 R: ConstIndex<RT, N> + Copy + Clone,
38 LT: Add<RT, Output = T>,
39{
40}
41
42impl<T, L, R, LT, RT, const N: usize> Clone for VAdd<T, L, R, LT, RT, N>
43where
44 L: ConstIndex<LT, N> + Copy + Clone,
45 R: ConstIndex<RT, N> + Copy + Clone,
46 LT: Add<RT, Output = T>,
47{
48 fn clone(&self) -> Self { *self }
49}
50
51unsafe impl<T, L, R, LT, RT, const N: usize> ConstIndex<T, N> for VAdd<T, L, R, LT, RT, N>
53where
54 L: ConstIndex<LT, N> + Copy + Clone,
55 R: ConstIndex<RT, N> + Copy + Clone,
56 LT: Add<RT, Output = T>,
57{
58 #[inline]
59 fn i(self, index: usize) -> T {
60 let l = self.l.i(index);
61 let r = self.r.i(index);
62 l + r
63 }
64}
65
66impl<T, L, R, LT, RT, O, NT, const N: usize> Add<O> for VAdd<T, L, R, LT, RT, N>
74where
75 L: ConstIndex<LT, N> + Copy + Clone,
76 R: ConstIndex<RT, N> + Copy + Clone,
77 LT: Add<RT, Output = T>,
78
79 O: ConstIndex<T, N> + Copy + Clone,
80 T: Add<T, Output = NT>,
81{
82 type Output = VAdd<NT, Self, O, T, T, N>;
83 fn add(self, other: O) -> Self::Output {
84 VAdd {
85 l: self,
86 r: other,
87 m: Default::default(),
88 }
89 }
90}
91
92impl<T, L, R, LT, RT, const N: usize> VAdd<T, L, R, LT, RT, N>
116where
117 L: ConstIndex<LT, N> + Copy + Clone,
118 R: ConstIndex<RT, N> + Copy + Clone,
119 LT: Add<RT, Output = T>,
120{
121 pub fn new(l: L, r: R) -> Self {
122 Self {
123 l,
124 r,
125 m: Default::default(),
126 }
127 }
128
129 pub fn realize(self) -> crate::Vector<T, N> { ConstIterator::from(self).collect() }
130}
131
132#[cfg(test)]
133pub(crate) const TESTLEN: usize = 777usize;
134
135#[test]
136fn calc_chain() {
137 use crate::Vector;
138 use rand::{thread_rng, Rng};
139 let mut rng = thread_rng();
140 let a: Vector<f32, TESTLEN> = rng.gen();
141 let b: Vector<f32, TESTLEN> = rng.gen();
142 let c: Vector<f32, TESTLEN> = rng.gen();
143 let d: Vector<f32, TESTLEN> = rng.gen();
144 let e: Vector<f32, TESTLEN> = rng.gen();
145
146 let ab = VAdd::new(a, b);
147 let abc = ab + c;
148 let abcd = abc + d;
149 let abcde = abcd + e;
150
151 let _res = abcde.realize();
152}