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