1 | //! This module hacks in "implicit deref" for Simd's operators. |
2 | //! Ideally, Rust would take care of this itself, |
3 | //! and method calls usually handle the LHS implicitly. |
4 | //! But this is not the case with arithmetic ops. |
5 | |
6 | use super::*; |
7 | |
8 | macro_rules! deref_lhs { |
9 | (impl<T, const N: usize> $trait:ident for $simd:ty { |
10 | fn $call:ident |
11 | }) => { |
12 | impl<T, const N: usize> $trait<$simd> for &$simd |
13 | where |
14 | T: SimdElement, |
15 | $simd: $trait<$simd, Output = $simd>, |
16 | LaneCount<N>: SupportedLaneCount, |
17 | { |
18 | type Output = Simd<T, N>; |
19 | |
20 | #[inline] |
21 | fn $call(self, rhs: $simd) -> Self::Output { |
22 | (*self).$call(rhs) |
23 | } |
24 | } |
25 | }; |
26 | } |
27 | |
28 | macro_rules! deref_rhs { |
29 | (impl<T, const N: usize> $trait:ident for $simd:ty { |
30 | fn $call:ident |
31 | }) => { |
32 | impl<T, const N: usize> $trait<&$simd> for $simd |
33 | where |
34 | T: SimdElement, |
35 | $simd: $trait<$simd, Output = $simd>, |
36 | LaneCount<N>: SupportedLaneCount, |
37 | { |
38 | type Output = Simd<T, N>; |
39 | |
40 | #[inline] |
41 | fn $call(self, rhs: &$simd) -> Self::Output { |
42 | self.$call(*rhs) |
43 | } |
44 | } |
45 | }; |
46 | } |
47 | |
48 | macro_rules! deref_ops { |
49 | ($(impl<T, const N: usize> $trait:ident for $simd:ty { |
50 | fn $call:ident |
51 | })*) => { |
52 | $( |
53 | deref_rhs! { |
54 | impl<T, const N: usize> $trait for $simd { |
55 | fn $call |
56 | } |
57 | } |
58 | deref_lhs! { |
59 | impl<T, const N: usize> $trait for $simd { |
60 | fn $call |
61 | } |
62 | } |
63 | impl<'lhs, 'rhs, T, const N: usize> $trait<&'rhs $simd> for &'lhs $simd |
64 | where |
65 | T: SimdElement, |
66 | $simd: $trait<$simd, Output = $simd>, |
67 | LaneCount<N>: SupportedLaneCount, |
68 | { |
69 | type Output = $simd; |
70 | |
71 | #[inline] |
72 | fn $call(self, rhs: &'rhs $simd) -> Self::Output { |
73 | (*self).$call(*rhs) |
74 | } |
75 | } |
76 | )* |
77 | } |
78 | } |
79 | |
80 | deref_ops! { |
81 | // Arithmetic |
82 | impl<T, const N: usize> Add for Simd<T, N> { |
83 | fn add |
84 | } |
85 | |
86 | impl<T, const N: usize> Mul for Simd<T, N> { |
87 | fn mul |
88 | } |
89 | |
90 | impl<T, const N: usize> Sub for Simd<T, N> { |
91 | fn sub |
92 | } |
93 | |
94 | impl<T, const N: usize> Div for Simd<T, N> { |
95 | fn div |
96 | } |
97 | |
98 | impl<T, const N: usize> Rem for Simd<T, N> { |
99 | fn rem |
100 | } |
101 | |
102 | // Bitops |
103 | impl<T, const N: usize> BitAnd for Simd<T, N> { |
104 | fn bitand |
105 | } |
106 | |
107 | impl<T, const N: usize> BitOr for Simd<T, N> { |
108 | fn bitor |
109 | } |
110 | |
111 | impl<T, const N: usize> BitXor for Simd<T, N> { |
112 | fn bitxor |
113 | } |
114 | |
115 | impl<T, const N: usize> Shl for Simd<T, N> { |
116 | fn shl |
117 | } |
118 | |
119 | impl<T, const N: usize> Shr for Simd<T, N> { |
120 | fn shr |
121 | } |
122 | } |
123 | |