]> git.lizzy.rs Git - rust.git/blob - library/portable-simd/crates/core_simd/src/ops/deref.rs
Merge commit 'a8385522ade6f67853edac730b5bf164ddb298fd' into simd-remove-autosplats
[rust.git] / library / portable-simd / crates / core_simd / src / ops / deref.rs
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 LANES: usize> $trait:ident for $simd:ty {
9             fn $call:ident
10         }) => {
11         impl<T, const LANES: usize> $trait<$simd> for &$simd
12         where
13             T: SimdElement,
14             $simd: $trait<$simd, Output = $simd>,
15             LaneCount<LANES>: SupportedLaneCount,
16         {
17             type Output = Simd<T, LANES>;
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 LANES: usize> $trait:ident for $simd:ty {
30             fn $call:ident
31         }) => {
32         impl<T, const LANES: usize> $trait<&$simd> for $simd
33         where
34             T: SimdElement,
35             $simd: $trait<$simd, Output = $simd>,
36             LaneCount<LANES>: SupportedLaneCount,
37         {
38             type Output = Simd<T, LANES>;
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 LANES: usize> $trait:ident for $simd:ty {
51             fn $call:ident
52         })*) => {
53         $(
54             deref_rhs! {
55                 impl<T, const LANES: usize> $trait for $simd {
56                     fn $call
57                 }
58             }
59             deref_lhs! {
60                 impl<T, const LANES: usize> $trait for $simd {
61                     fn $call
62                 }
63             }
64             impl<'lhs, 'rhs, T, const LANES: usize> $trait<&'rhs $simd> for &'lhs $simd
65             where
66                 T: SimdElement,
67                 $simd: $trait<$simd, Output = $simd>,
68                 LaneCount<LANES>: 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: &$simd) -> Self::Output {
75                     (*self).$call(*rhs)
76                 }
77             }
78         )*
79     }
80 }
81
82 deref_ops! {
83     // Arithmetic
84     impl<T, const LANES: usize> Add for Simd<T, LANES> {
85         fn add
86     }
87
88     impl<T, const LANES: usize> Mul for Simd<T, LANES> {
89         fn mul
90     }
91
92     impl<T, const LANES: usize> Sub for Simd<T, LANES> {
93         fn sub
94     }
95
96     impl<T, const LANES: usize> Div for Simd<T, LANES> {
97         fn div
98     }
99
100     impl<T, const LANES: usize> Rem for Simd<T, LANES> {
101         fn rem
102     }
103
104     // Bitops
105     impl<T, const LANES: usize> BitAnd for Simd<T, LANES> {
106         fn bitand
107     }
108
109     impl<T, const LANES: usize> BitOr for Simd<T, LANES> {
110         fn bitor
111     }
112
113     impl<T, const LANES: usize> BitXor for Simd<T, LANES> {
114         fn bitxor
115     }
116
117     impl<T, const LANES: usize> Shl for Simd<T, LANES> {
118         fn shl
119     }
120
121     impl<T, const LANES: usize> Shr for Simd<T, LANES> {
122         fn shr
123     }
124 }