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 | use super::*; |
6 | |
7 | macro_rules! deref_lhs { |
8 | (impl<T, const N: usize> $trait:ident for $simd:ty { |
9 | fn $call:ident |
10 | }) => { |
11 | impl<T, const N: usize> $trait<$simd> for &$simd |
12 | where |
13 | T: SimdElement, |
14 | $simd: $trait<$simd, Output = $simd>, |
15 | LaneCount<N>: SupportedLaneCount, |
16 | { |
17 | type Output = Simd<T, N>; |
18 | |
19 | #[inline] |
20 | #[must_use = "operator returns a new vector without mutating the inputs" ] |
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 | #[must_use = "operator returns a new vector without mutating the inputs" ] |
42 | fn $call(self, rhs: &$simd) -> Self::Output { |
43 | self.$call(*rhs) |
44 | } |
45 | } |
46 | }; |
47 | } |
48 | |
49 | macro_rules! deref_ops { |
50 | ($(impl<T, const N: usize> $trait:ident for $simd:ty { |
51 | fn $call:ident |
52 | })*) => { |
53 | $( |
54 | deref_rhs! { |
55 | impl<T, const N: usize> $trait for $simd { |
56 | fn $call |
57 | } |
58 | } |
59 | deref_lhs! { |
60 | impl<T, const N: usize> $trait for $simd { |
61 | fn $call |
62 | } |
63 | } |
64 | impl<'lhs, 'rhs, T, const N: usize> $trait<&'rhs $simd> for &'lhs $simd |
65 | where |
66 | T: SimdElement, |
67 | $simd: $trait<$simd, Output = $simd>, |
68 | LaneCount<N>: SupportedLaneCount, |
69 | { |
70 | type Output = $simd; |
71 | |
72 | #[inline] |
73 | #[must_use = "operator returns a new vector without mutating the inputs" ] |
74 | fn $call(self, rhs: &'rhs $simd) -> Self::Output { |
75 | (*self).$call(*rhs) |
76 | } |
77 | } |
78 | )* |
79 | } |
80 | } |
81 | |
82 | deref_ops! { |
83 | // Arithmetic |
84 | impl<T, const N: usize> Add for Simd<T, N> { |
85 | fn add |
86 | } |
87 | |
88 | impl<T, const N: usize> Mul for Simd<T, N> { |
89 | fn mul |
90 | } |
91 | |
92 | impl<T, const N: usize> Sub for Simd<T, N> { |
93 | fn sub |
94 | } |
95 | |
96 | impl<T, const N: usize> Div for Simd<T, N> { |
97 | fn div |
98 | } |
99 | |
100 | impl<T, const N: usize> Rem for Simd<T, N> { |
101 | fn rem |
102 | } |
103 | |
104 | // Bitops |
105 | impl<T, const N: usize> BitAnd for Simd<T, N> { |
106 | fn bitand |
107 | } |
108 | |
109 | impl<T, const N: usize> BitOr for Simd<T, N> { |
110 | fn bitor |
111 | } |
112 | |
113 | impl<T, const N: usize> BitXor for Simd<T, N> { |
114 | fn bitxor |
115 | } |
116 | |
117 | impl<T, const N: usize> Shl for Simd<T, N> { |
118 | fn shl |
119 | } |
120 | |
121 | impl<T, const N: usize> Shr for Simd<T, N> { |
122 | fn shr |
123 | } |
124 | } |
125 | |