1#![macro_use]
19
20#[cfg(feature = "simd")]
21macro_rules! default_fn {
22 { $($tt:tt)* } => { default fn $( $tt )* };
23}
24
25#[cfg(not(feature = "simd"))]
26macro_rules! default_fn {
27 { $($tt:tt)* } => { fn $( $tt )* };
28}
29
30macro_rules! impl_operator {
32 (<$S:ident: $Constraint:ident> $Op:ident for $Lhs:ty {
34 fn $op:ident($x:ident) -> $Output:ty { $body:expr }
35 }) => {
36 impl<$S: $Constraint> $Op for $Lhs {
37 type Output = $Output;
38 #[inline]
39 default_fn!($op(self) -> $Output {
40 let $x = self; $body
41 });
42 }
43
44 impl<'a, $S: $Constraint> $Op for &'a $Lhs {
45 type Output = $Output;
46 #[inline]
47 default_fn!($op(self) -> $Output {
48 let $x = self; $body
49 });
50 }
51 };
52 (<$S:ident: $Constraint:ident> $Op:ident<$Rhs:ident> for $Lhs:ty {
54 fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
55 }) => {
56 impl<$S: $Constraint> $Op<$Rhs> for $Lhs {
57 type Output = $Output;
58 #[inline]
59 default_fn!($op(self, other: $Rhs) -> $Output {
60 let ($lhs, $rhs) = (self, other); $body
61 });
62 }
63
64 impl<'a, $S: $Constraint> $Op<$Rhs> for &'a $Lhs {
65 type Output = $Output;
66 #[inline]
67 default_fn!($op(self, other: $Rhs) -> $Output {
68 let ($lhs, $rhs) = (self, other); $body
69 });
70 }
71 };
72 (<$S:ident: $Constraint:ident> $Op:ident<$Rhs:ty> for $Lhs:ty {
74 fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
75 }) => {
76 impl<$S: $Constraint> $Op<$Rhs> for $Lhs {
77 type Output = $Output;
78 #[inline]
79 default_fn!( $op(self, other: $Rhs) -> $Output {
80 let ($lhs, $rhs) = (self, other); $body
81 });
82 }
83
84 impl<'a, $S: $Constraint> $Op<&'a $Rhs> for $Lhs {
85 type Output = $Output;
86 #[inline]
87 default_fn!( $op(self, other: &'a $Rhs) -> $Output {
88 let ($lhs, $rhs) = (self, other); $body
89 });
90 }
91
92 impl<'a, $S: $Constraint> $Op<$Rhs> for &'a $Lhs {
93 type Output = $Output;
94 #[inline]
95 default_fn!( $op(self, other: $Rhs) -> $Output {
96 let ($lhs, $rhs) = (self, other); $body
97 });
98 }
99
100 impl<'a, 'b, $S: $Constraint> $Op<&'a $Rhs> for &'b $Lhs {
101 type Output = $Output;
102 #[inline]
103 default_fn!( $op(self, other: &'a $Rhs) -> $Output {
104 let ($lhs, $rhs) = (self, other); $body
105 });
106 }
107 };
108 ($Op:ident<$Rhs:ident<$S:ident>> for $Lhs:ty {
110 fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
111 }) => {
112 impl $Op<$Rhs<$S>> for $Lhs {
113 type Output = $Output;
114 #[inline]
115 default_fn!( $op(self, other: $Rhs<$S>) -> $Output {
116 let ($lhs, $rhs) = (self, other); $body
117 });
118 }
119
120 impl<'a> $Op<&'a $Rhs<$S>> for $Lhs {
121 type Output = $Output;
122 #[inline]
123 default_fn!( $op(self, other: &'a $Rhs<$S>) -> $Output {
124 let ($lhs, $rhs) = (self, other); $body
125 });
126 }
127 };
128}
129
130macro_rules! impl_assignment_operator {
131 (<$S:ident: $Constraint:ident> $Op:ident<$Rhs:ty> for $Lhs:ty {
132 fn $op:ident(&mut $lhs:ident, $rhs:ident) $body:block
133 }) => {
134 impl<$S: $Constraint + $Op<$S>> $Op<$Rhs> for $Lhs {
135 #[inline]
136 default_fn!( $op(&mut $lhs, $rhs: $Rhs) $body );
137 }
138 };
139}
140
141macro_rules! fold_array {
142 (&$method:ident, { $x:expr }) => {
143 *$x
144 };
145 (&$method:ident, { $x:expr, $y:expr }) => {
146 $x.$method(&$y)
147 };
148 (&$method:ident, { $x:expr, $y:expr, $z:expr }) => {
149 $x.$method(&$y).$method(&$z)
150 };
151 (&$method:ident, { $x:expr, $y:expr, $z:expr, $w:expr }) => {
152 $x.$method(&$y).$method(&$z).$method(&$w)
153 };
154 ($method:ident, { $x:expr }) => {
155 $x
156 };
157 ($method:ident, { $x:expr, $y:expr }) => {
158 $x.$method($y)
159 };
160 ($method:ident, { $x:expr, $y:expr, $z:expr }) => {
161 $x.$method($y).$method($z)
162 };
163 ($method:ident, { $x:expr, $y:expr, $z:expr, $w:expr }) => {
164 $x.$method($y).$method($z).$method($w)
165 };
166}
167
168macro_rules! impl_fixed_array_conversions {
170 ($ArrayN:ident <$S:ident> { $($field:ident : $index:expr),+ }, $n:expr) => {
171 impl<$S> Into<[$S; $n]> for $ArrayN<$S> {
172 #[inline]
173 fn into(self) -> [$S; $n] {
174 match self { $ArrayN { $($field),+ } => [$($field),+] }
175 }
176 }
177
178 impl<$S> AsRef<[$S; $n]> for $ArrayN<$S> {
179 #[inline]
180 fn as_ref(&self) -> &[$S; $n] {
181 unsafe { mem::transmute(self) }
182 }
183 }
184
185 impl<$S> AsMut<[$S; $n]> for $ArrayN<$S> {
186 #[inline]
187 fn as_mut(&mut self) -> &mut [$S; $n] {
188 unsafe { mem::transmute(self) }
189 }
190 }
191
192 impl<$S: Clone> From<[$S; $n]> for $ArrayN<$S> {
193 #[inline]
194 fn from(v: [$S; $n]) -> $ArrayN<$S> {
195 $ArrayN { $($field: v[$index].clone()),+ }
197 }
198 }
199
200 impl<'a, $S> From<&'a [$S; $n]> for &'a $ArrayN<$S> {
201 #[inline]
202 fn from(v: &'a [$S; $n]) -> &'a $ArrayN<$S> {
203 unsafe { mem::transmute(v) }
204 }
205 }
206
207 impl<'a, $S> From<&'a mut [$S; $n]> for &'a mut $ArrayN<$S> {
208 #[inline]
209 fn from(v: &'a mut [$S; $n]) -> &'a mut $ArrayN<$S> {
210 unsafe { mem::transmute(v) }
211 }
212 }
213 }
214}
215
216macro_rules! impl_tuple_conversions {
218 ($ArrayN:ident <$S:ident> { $($field:ident),+ }, $Tuple:ty) => {
219 impl<$S> Into<$Tuple> for $ArrayN<$S> {
220 #[inline]
221 fn into(self) -> $Tuple {
222 match self { $ArrayN { $($field),+ } => ($($field),+,) }
223 }
224 }
225
226 impl<$S> AsRef<$Tuple> for $ArrayN<$S> {
227 #[inline]
228 fn as_ref(&self) -> &$Tuple {
229 unsafe { mem::transmute(self) }
230 }
231 }
232
233 impl<$S> AsMut<$Tuple> for $ArrayN<$S> {
234 #[inline]
235 fn as_mut(&mut self) -> &mut $Tuple {
236 unsafe { mem::transmute(self) }
237 }
238 }
239
240 impl<$S> From<$Tuple> for $ArrayN<$S> {
241 #[inline]
242 fn from(v: $Tuple) -> $ArrayN<$S> {
243 match v { ($($field),+,) => $ArrayN { $($field: $field),+ } }
244 }
245 }
246
247 impl<'a, $S> From<&'a $Tuple> for &'a $ArrayN<$S> {
248 #[inline]
249 fn from(v: &'a $Tuple) -> &'a $ArrayN<$S> {
250 unsafe { mem::transmute(v) }
251 }
252 }
253
254 impl<'a, $S> From<&'a mut $Tuple> for &'a mut $ArrayN<$S> {
255 #[inline]
256 fn from(v: &'a mut $Tuple) -> &'a mut $ArrayN<$S> {
257 unsafe { mem::transmute(v) }
258 }
259 }
260 }
261}
262
263macro_rules! impl_index_operators {
265 ($VectorN:ident<$S:ident>, $n:expr, $Output:ty, $I:ty) => {
266 impl<$S> Index<$I> for $VectorN<$S> {
267 type Output = $Output;
268
269 #[inline]
270 fn index<'a>(&'a self, i: $I) -> &'a $Output {
271 let v: &[$S; $n] = self.as_ref();
272 &v[i]
273 }
274 }
275
276 impl<$S> IndexMut<$I> for $VectorN<$S> {
277 #[inline]
278 fn index_mut<'a>(&'a mut self, i: $I) -> &'a mut $Output {
279 let v: &mut [$S; $n] = self.as_mut();
280 &mut v[i]
281 }
282 }
283 };
284}
285
286#[cfg(feature = "simd")]
288macro_rules! impl_operator_simd {
289 ([$Simd:ident]; $Op:ident for $Lhs:ty {
291 fn $op:ident($x:ident) -> $Output:ty { $body:expr }
292 }) => {
293 impl $Op for $Lhs {
294 #[inline]
295 fn $op(self) -> $Output {
296 let $x: $Simd = self.into();
297 $body
298 }
299 }
300 };
301 (@rs [$Simd:ident]; $Op:ident<$Rhs:ty> for $Lhs:ty {
303 fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
304 }) => {
305 impl $Op<$Rhs> for $Lhs {
306 #[inline]
307 fn $op(self, other: $Rhs) -> $Output {
308 let ($lhs, $rhs): ($Simd, $Simd) = (self.into(), $Simd::splat(other));
309 $body
310 }
311 }
312
313 impl<'a> $Op<$Rhs> for &'a $Lhs {
314 #[inline]
315 fn $op(self, other: $Rhs) -> $Output {
316 let ($lhs, $rhs): ($Simd, $Simd) = ((*self).into(), $Simd::splat(other));
317 $body
318 }
319 }
320 };
321
322 ([$Simd:ident]; $Op:ident<$Rhs:ty> for $Lhs:ty {
324 fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
325 }) => {
326 impl $Op<$Rhs> for $Lhs {
327 #[inline]
328 fn $op(self, other: $Rhs) -> $Output {
329 let ($lhs, $rhs): ($Simd, $Simd) = (self.into(), other.into());
330 $body
331 }
332 }
333
334 impl<'a> $Op<&'a $Rhs> for $Lhs {
335 #[inline]
336 fn $op(self, other: &'a $Rhs) -> $Output {
337 let ($lhs, $rhs): ($Simd, $Simd) = (self.into(), (*other).into());
338 $body
339 }
340 }
341
342 impl<'a> $Op<$Rhs> for &'a $Lhs {
343 #[inline]
344 fn $op(self, other: $Rhs) -> $Output {
345 let ($lhs, $rhs): ($Simd, $Simd) = ((*self).into(), other.into());
346 $body
347 }
348 }
349
350 impl<'a, 'b> $Op<&'a $Rhs> for &'b $Lhs {
351 #[inline]
352 fn $op(self, other: &'a $Rhs) -> $Output {
353 let ($lhs, $rhs): ($Simd, $Simd) = ((*self).into(), (*other).into());
354 $body
355 }
356 }
357 };
358
359 (@ls [$Simd:ident]; $Op:ident<$Rhs:ty> for $Lhs:ident {
361 fn $op:ident($lhs:ident, $rhs:ident) -> $Output:ty { $body:expr }
362 }) => {
363 impl $Op<$Rhs> for $Lhs {
364 #[inline]
365 fn $op(self, other: $Rhs) -> $Output {
366 let ($lhs, $rhs): ($Simd, $Simd) = ($Simd::splat(self), other.into());
367 $body
368 }
369 }
370
371 impl<'a> $Op<&'a $Rhs> for $Lhs {
372 #[inline]
373 fn $op(self, other: &'a $Rhs) -> $Output {
374 let ($lhs, $rhs): ($Simd, $Simd) = ($Simd::splat(self), (*other).into());
375 $body
376 }
377 }
378 };
379}
380
381#[cfg(feature = "mint")]
383macro_rules! impl_mint_conversions {
384 ($ArrayN:ident { $($field:ident),+ }, $Mint:ident) => {
385 impl<S: Clone> Into<mint::$Mint<S>> for $ArrayN<S> {
386 #[inline]
387 fn into(self) -> mint::$Mint<S> {
388 mint::$Mint::from([$(self.$field),+])
389 }
390 }
391
392 impl<S> From<mint::$Mint<S>> for $ArrayN<S> {
393 #[inline]
394 fn from(v: mint::$Mint<S>) -> Self {
395 $ArrayN { $( $field: v.$field, )+ }
396 }
397 }
398 }
399}
400
401include!(concat!(env!("OUT_DIR"), "/swizzle_operator_macro.rs"));