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