generic_simd/
implementation.rs

1macro_rules! arithmetic_ops {
2    {
3        @new $type:ty, $feature:expr, $trait:ident, $func:ident, ()
4    } => {
5        impl core::ops::$trait<$type> for $type {
6            type Output = Self;
7            #[allow(unused_unsafe)]
8            #[inline]
9            fn $func(mut self, rhs: Self) -> Self {
10                for (a, b) in self.iter_mut().zip(rhs.iter()) {
11                    *a = core::ops::$trait::$func(*a, b);
12                }
13                self
14            }
15        }
16
17        impl core::ops::$trait<<$type as $crate::vector::Vector>::Scalar> for $type {
18            type Output = Self;
19            #[inline]
20            fn $func(mut self, rhs: <$type as $crate::vector::Vector>::Scalar) -> Self {
21                for a in self.iter_mut() {
22                    *a = core::ops::$trait::$func(*a, rhs);
23                }
24                self
25            }
26        }
27    };
28    {
29        @assign $type:ty, $feature:expr, $trait:ident, $func:ident, ()
30    } => {
31        impl core::ops::$trait<$type> for $type {
32            #[allow(unused_unsafe)]
33            #[inline]
34            fn $func(&mut self, rhs: Self) {
35                for (a, b) in self.iter_mut().zip(rhs.iter()) {
36                    core::ops::$trait::$func(a, b);
37                }
38            }
39        }
40
41        impl core::ops::$trait<<$type as $crate::vector::Vector>::Scalar> for $type {
42            #[inline]
43            fn $func(&mut self, rhs: <$type as $crate::vector::Vector>::Scalar) {
44                for a in self.iter_mut() {
45                    core::ops::$trait::$func(a, rhs);
46                }
47            }
48        }
49    };
50    {
51        @new $type:ty, $feature:expr, $trait:ident, $func:ident, ($op:path)
52    } => {
53        impl core::ops::$trait<$type> for $type {
54            type Output = Self;
55            #[allow(unused_unsafe)]
56            #[inline]
57            fn $func(self, rhs: Self) -> Self {
58                Self(unsafe { $op(self.0, rhs.0) })
59            }
60        }
61
62        impl core::ops::$trait<<$type as $crate::vector::Vector>::Scalar> for $type {
63            type Output = Self;
64            #[inline]
65            fn $func(self, rhs: <$type as $crate::vector::Vector>::Scalar) -> Self {
66                self.$func(<$type>::splat(unsafe { $feature }, rhs))
67            }
68        }
69    };
70    {
71        @assign $type:ty, $feature:expr, $trait:ident, $func:ident, ($op:path)
72    } => {
73        impl core::ops::$trait<$type> for $type {
74            #[allow(unused_unsafe)]
75            #[inline]
76            fn $func(&mut self, rhs: Self) {
77                self.0 = unsafe { $op(self.0, rhs.0) };
78            }
79        }
80
81        impl core::ops::$trait<<$type as $crate::vector::Vector>::Scalar> for $type {
82            #[inline]
83            fn $func(&mut self, rhs: <$type as $crate::vector::Vector>::Scalar) {
84                self.$func(<$type>::splat(unsafe { $feature }, rhs))
85            }
86        }
87    };
88    {
89        feature: $feature:expr,
90        for $type:ty:
91            add -> $add_expr:tt,
92            sub -> $sub_expr:tt,
93            mul -> $mul_expr:tt,
94            div -> $div_expr:tt
95    } => {
96        impl core::iter::Sum<$type> for Option<$type> {
97            #[inline]
98            fn sum<I>(mut iter: I) -> Self
99            where
100                I: Iterator<Item = $type>,
101            {
102                if let Some(mut sum) = iter.next() {
103                    while let Some(v) = iter.next() {
104                        sum += v;
105                    }
106                    Some(sum)
107                } else {
108                    None
109                }
110            }
111        }
112
113        impl core::iter::Sum<$type> for <$type as $crate::vector::Vector>::Scalar {
114            #[inline]
115            fn sum<I>(iter: I) -> Self
116            where
117                I: Iterator<Item = $type>,
118            {
119                if let Some(sums) = iter.sum::<Option<$type>>() {
120                    sums.iter().sum()
121                } else {
122                    Default::default()
123                }
124            }
125        }
126
127        impl core::iter::Product<$type> for Option<$type> {
128            #[inline]
129            fn product<I>(mut iter: I) -> Self
130            where
131                I: Iterator<Item = $type>,
132            {
133                if let Some(mut sum) = iter.next() {
134                    while let Some(v) = iter.next() {
135                        sum *= v;
136                    }
137                    Some(sum)
138                } else {
139                    None
140                }
141            }
142        }
143
144        impl core::iter::Product<$type> for <$type as $crate::vector::Vector>::Scalar {
145            #[inline]
146            fn product<I>(iter: I) -> Self
147            where
148                I: Iterator<Item = $type>,
149            {
150                if let Some(sums) = iter.sum::<Option<$type>>() {
151                    sums.iter().product()
152                } else {
153                    Default::default()
154                }
155            }
156        }
157
158        arithmetic_ops!{@new $type, $feature, Add, add, $add_expr}
159        arithmetic_ops!{@new $type, $feature, Sub, sub, $sub_expr}
160        arithmetic_ops!{@new $type, $feature, Mul, mul, $mul_expr}
161        arithmetic_ops!{@new $type, $feature, Div, div, $div_expr}
162        arithmetic_ops!{@assign $type, $feature, AddAssign, add_assign, $add_expr}
163        arithmetic_ops!{@assign $type, $feature, SubAssign, sub_assign, $sub_expr}
164        arithmetic_ops!{@assign $type, $feature, MulAssign, mul_assign, $mul_expr}
165        arithmetic_ops!{@assign $type, $feature, DivAssign, div_assign, $div_expr}
166    };
167}
168
169macro_rules! as_slice {
170    {
171        $type:ty
172    } => {
173        impl AsRef<[<$type as crate::vector::Vector>::Scalar]> for $type {
174            #[inline]
175            fn as_ref(&self) -> &[<$type as crate::vector::Vector>::Scalar] {
176                use crate::vector::Vector;
177                self.as_slice()
178            }
179        }
180
181        impl AsMut<[<$type as crate::vector::Vector>::Scalar]> for $type {
182            #[inline]
183            fn as_mut(&mut self) -> &mut [<$type as crate::vector::Vector>::Scalar] {
184                use crate::vector::Vector;
185                self.as_slice_mut()
186            }
187        }
188
189        impl core::ops::Deref for $type {
190            type Target = [<Self as crate::vector::Vector>::Scalar];
191            #[inline]
192            fn deref(&self) -> &Self::Target {
193                self.as_slice()
194            }
195        }
196
197        impl core::ops::DerefMut for $type {
198            #[inline]
199            fn deref_mut(&mut self) -> &mut <Self as core::ops::Deref>::Target {
200                self.as_slice_mut()
201            }
202        }
203    }
204}