1use crate::vector::{width, Vector};
2use core::marker::PhantomData;
3
4#[cfg(feature = "complex")]
5use crate::vector::Complex;
6
7pub trait Double {
9 type Doubled: width::Width;
10}
11
12impl Double for width::W1 {
13 type Doubled = width::W2;
14}
15
16impl Double for width::W2 {
17 type Doubled = width::W4;
18}
19
20impl Double for width::W4 {
21 type Doubled = width::W8;
22}
23
24#[derive(Copy, Clone, Debug)]
26#[repr(transparent)]
27pub struct Shim2<Underlying, Scalar>([Underlying; 2], PhantomData<Scalar>);
28
29pub type Shim4<Underlying, Scalar> = Shim2<Shim2<Underlying, Scalar>, Scalar>;
31
32pub type Shim8<Underlying, Scalar> = Shim4<Shim2<Underlying, Scalar>, Scalar>;
34
35unsafe impl<Underlying, Scalar> Vector for Shim2<Underlying, Scalar>
36where
37 Underlying: Vector<Scalar = Scalar>,
38 Underlying::Width: Double,
39 Scalar: Copy,
40{
41 type Scalar = Scalar;
42 type Token = <Underlying as Vector>::Token;
43 type Width = <Underlying::Width as Double>::Doubled;
44 type Underlying = [<Underlying as Vector>::Underlying; 2];
45
46 #[inline]
47 fn zeroed(token: Self::Token) -> Self {
48 Self([Underlying::zeroed(token); 2], PhantomData)
49 }
50
51 #[inline]
52 fn splat(token: Self::Token, from: Self::Scalar) -> Self {
53 Self([Underlying::splat(token, from); 2], PhantomData)
54 }
55}
56
57impl<Underlying, Scalar> AsRef<[Scalar]> for Shim2<Underlying, Scalar>
58where
59 Underlying: Vector<Scalar = Scalar>,
60 Underlying::Width: Double,
61 Scalar: Copy,
62{
63 #[inline]
64 fn as_ref(&self) -> &[Scalar] {
65 self.as_slice()
66 }
67}
68
69impl<Underlying, Scalar> AsMut<[Scalar]> for Shim2<Underlying, Scalar>
70where
71 Underlying: Vector<Scalar = Scalar>,
72 Underlying::Width: Double,
73 Scalar: Copy,
74{
75 #[inline]
76 fn as_mut(&mut self) -> &mut [Scalar] {
77 self.as_slice_mut()
78 }
79}
80
81impl<Underlying, Scalar> core::ops::Deref for Shim2<Underlying, Scalar>
82where
83 Underlying: Vector<Scalar = Scalar>,
84 Underlying::Width: Double,
85 Scalar: Copy,
86{
87 type Target = [Scalar];
88
89 #[inline]
90 fn deref(&self) -> &Self::Target {
91 self.as_slice()
92 }
93}
94
95impl<Underlying, Scalar> core::ops::DerefMut for Shim2<Underlying, Scalar>
96where
97 Underlying: Vector<Scalar = Scalar>,
98 Underlying::Width: Double,
99 Scalar: Copy,
100{
101 #[inline]
102 fn deref_mut(&mut self) -> &mut <Self as core::ops::Deref>::Target {
103 self.as_slice_mut()
104 }
105}
106
107macro_rules! implement {
108 {
109 @op $trait:ident :: $func:ident
110 } => {
111 impl<Underlying, Scalar> core::ops::$trait<Self> for Shim2<Underlying, Scalar>
112 where
113 Underlying: Copy + core::ops::$trait<Underlying, Output=Underlying>,
114 {
115 type Output = Self;
116
117 #[inline]
118 fn $func(self, rhs: Self) -> Self {
119 Self([self.0[0].$func(rhs.0[0]), self.0[1].$func(rhs.0[1])], PhantomData)
120 }
121 }
122
123 impl<Underlying, Scalar> core::ops::$trait<Scalar> for Shim2<Underlying, Scalar>
124 where
125 Underlying: Copy + core::ops::$trait<Scalar, Output=Underlying>,
126 Scalar: Copy,
127 {
128 type Output = Self;
129
130 #[inline]
131 fn $func(self, rhs: Scalar) -> Self {
132 Self([self.0[0].$func(rhs), self.0[1].$func(rhs)], PhantomData)
133 }
134 }
135 };
136
137 {
138 @op_assign $trait:ident :: $func:ident
139 } => {
140 impl<Underlying, Scalar> core::ops::$trait<Self> for Shim2<Underlying, Scalar>
141 where
142 Underlying: Copy + core::ops::$trait<Underlying>,
143 Scalar: Copy,
144 {
145 #[inline]
146 fn $func(&mut self, rhs: Self) {
147 self.0[0].$func(rhs.0[0]);
148 self.0[1].$func(rhs.0[1]);
149 }
150 }
151
152 impl<Underlying, Scalar> core::ops::$trait<Scalar> for Shim2<Underlying, Scalar>
153 where
154 Underlying: Copy + core::ops::$trait<Scalar>,
155 Scalar: Copy,
156 {
157 #[inline]
158 fn $func(&mut self, rhs: Scalar) {
159 self.0[0].$func(rhs);
160 self.0[1].$func(rhs);
161 }
162 }
163 };
164}
165
166implement! { @op Add::add }
167implement! { @op Sub::sub }
168implement! { @op Mul::mul }
169implement! { @op Div::div }
170implement! { @op_assign AddAssign::add_assign }
171implement! { @op_assign SubAssign::sub_assign }
172implement! { @op_assign MulAssign::mul_assign }
173implement! { @op_assign DivAssign::div_assign }
174
175impl<Underlying, Scalar> core::ops::Neg for Shim2<Underlying, Scalar>
176where
177 Underlying: Copy + core::ops::Neg<Output = Underlying>,
178{
179 type Output = Self;
180
181 #[inline]
182 fn neg(self) -> Self {
183 Self([-self.0[0], -self.0[1]], PhantomData)
184 }
185}
186
187impl<Underlying, Scalar> core::iter::Sum<Shim2<Underlying, Scalar>>
188 for Option<Shim2<Underlying, Scalar>>
189where
190 Shim2<Underlying, Scalar>: core::ops::AddAssign,
191 Underlying: Copy,
192{
193 #[inline]
194 fn sum<I>(mut iter: I) -> Self
195 where
196 I: Iterator<Item = Shim2<Underlying, Scalar>>,
197 {
198 if let Some(mut sum) = iter.next() {
199 for v in iter {
200 sum += v;
201 }
202 Some(sum)
203 } else {
204 None
205 }
206 }
207}
208
209impl<Underlying, Scalar> core::iter::Sum<Shim2<Underlying, Scalar>>
210 for <Shim2<Underlying, Scalar> as Vector>::Scalar
211where
212 Option<Shim2<Underlying, Scalar>>: core::iter::Sum<Shim2<Underlying, Scalar>>,
213 Underlying: Vector<Scalar = Scalar>,
214 Underlying::Width: Double,
215 Scalar: Copy + core::ops::Add<Self, Output = Self> + Default,
216{
217 #[inline]
218 fn sum<I>(iter: I) -> Self
219 where
220 I: Iterator<Item = Shim2<Underlying, Scalar>>,
221 {
222 let mut value = Self::default();
223 if let Some(sums) = iter.sum::<Option<Shim2<Underlying, Scalar>>>() {
224 for sum in sums.as_slice() {
225 value = value + *sum;
226 }
227 }
228 value
229 }
230}
231
232impl<Underlying, Scalar> core::iter::Product<Shim2<Underlying, Scalar>>
233 for Option<Shim2<Underlying, Scalar>>
234where
235 Shim2<Underlying, Scalar>: core::ops::MulAssign,
236 Underlying: Copy,
237{
238 #[inline]
239 fn product<I>(mut iter: I) -> Self
240 where
241 I: Iterator<Item = Shim2<Underlying, Scalar>>,
242 {
243 if let Some(mut sum) = iter.next() {
244 for v in iter {
245 sum *= v;
246 }
247 Some(sum)
248 } else {
249 None
250 }
251 }
252}
253
254impl<Underlying, Scalar> core::iter::Product<Shim2<Underlying, Scalar>>
255 for <Shim2<Underlying, Scalar> as Vector>::Scalar
256where
257 Option<Shim2<Underlying, Scalar>>: core::iter::Product<Shim2<Underlying, Scalar>>,
258 Underlying: Vector<Scalar = Scalar>,
259 Underlying::Width: Double,
260 Scalar: Copy + core::ops::Mul<Self, Output = Self> + Default,
261{
262 #[inline]
263 fn product<I>(iter: I) -> Self
264 where
265 I: Iterator<Item = Shim2<Underlying, Scalar>>,
266 {
267 let mut value = Self::default();
268 if let Some(products) = iter.product::<Option<Shim2<Underlying, Scalar>>>() {
269 for product in products.as_slice() {
270 value = value * *product;
271 }
272 }
273 value
274 }
275}
276
277#[cfg(feature = "complex")]
278impl<Underlying, Real> Complex for Shim2<Underlying, num_complex::Complex<Real>>
279where
280 Underlying: Vector<Scalar = num_complex::Complex<Real>> + Complex<RealScalar = Real>,
281 Underlying::Width: Double,
282 Real: Copy,
283{
284 type RealScalar = Real;
285
286 #[inline]
287 fn conj(self) -> Self {
288 Self([self.0[0].conj(), self.0[1].conj()], PhantomData)
289 }
290
291 #[inline]
292 fn mul_i(self) -> Self {
293 Self([self.0[0].mul_i(), self.0[1].mul_i()], PhantomData)
294 }
295
296 #[inline]
297 fn mul_neg_i(self) -> Self {
298 Self([self.0[0].mul_neg_i(), self.0[1].mul_neg_i()], PhantomData)
299 }
300}