generic_simd/
implementation.rs1macro_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}