core_simd/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
6use super::*;
7
8macro_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        {
17            type Output = Simd<T, N>;
18
19            #[inline]
20            fn $call(self, rhs: $simd) -> Self::Output {
21                (*self).$call(rhs)
22            }
23        }
24    };
25}
26
27macro_rules! deref_rhs {
28    (impl<T, const N: usize> $trait:ident for $simd:ty {
29            fn $call:ident
30        }) => {
31        impl<T, const N: usize> $trait<&$simd> for $simd
32        where
33            T: SimdElement,
34            $simd: $trait<$simd, Output = $simd>,
35        {
36            type Output = Simd<T, N>;
37
38            #[inline]
39            fn $call(self, rhs: &$simd) -> Self::Output {
40                self.$call(*rhs)
41            }
42        }
43    };
44}
45
46macro_rules! deref_ops {
47    ($(impl<T, const N: usize> $trait:ident for $simd:ty {
48            fn $call:ident
49        })*) => {
50        $(
51            deref_rhs! {
52                impl<T, const N: usize> $trait for $simd {
53                    fn $call
54                }
55            }
56            deref_lhs! {
57                impl<T, const N: usize> $trait for $simd {
58                    fn $call
59                }
60            }
61            impl<'lhs, 'rhs, T, const N: usize> $trait<&'rhs $simd> for &'lhs $simd
62            where
63                T: SimdElement,
64                $simd: $trait<$simd, Output = $simd>,
65            {
66                type Output = $simd;
67
68                #[inline]
69                fn $call(self, rhs: &'rhs $simd) -> Self::Output {
70                    (*self).$call(*rhs)
71                }
72            }
73        )*
74    }
75}
76
77deref_ops! {
78    // Arithmetic
79    impl<T, const N: usize> Add for Simd<T, N> {
80        fn add
81    }
82
83    impl<T, const N: usize> Mul for Simd<T, N> {
84        fn mul
85    }
86
87    impl<T, const N: usize> Sub for Simd<T, N> {
88        fn sub
89    }
90
91    impl<T, const N: usize> Div for Simd<T, N> {
92        fn div
93    }
94
95    impl<T, const N: usize> Rem for Simd<T, N> {
96        fn rem
97    }
98
99    // Bitops
100    impl<T, const N: usize> BitAnd for Simd<T, N> {
101        fn bitand
102    }
103
104    impl<T, const N: usize> BitOr for Simd<T, N> {
105        fn bitor
106    }
107
108    impl<T, const N: usize> BitXor for Simd<T, N> {
109        fn bitxor
110    }
111
112    impl<T, const N: usize> Shl for Simd<T, N> {
113        fn shl
114    }
115
116    impl<T, const N: usize> Shr for Simd<T, N> {
117        fn shr
118    }
119}