Skip to main content

ark_ff/fields/
arithmetic.rs

1// Implements AddAssign on Self by deferring to an implementation on &Self
2#[macro_export]
3macro_rules! impl_additive_ops_from_ref {
4    ($type: ident, $params: ident) => {
5        impl<P: $params> core::ops::Add<Self> for $type<P> {
6            type Output = Self;
7
8            #[inline]
9            fn add(self, other: Self) -> Self {
10                let mut result = self;
11                result += &other;
12                result
13            }
14        }
15
16        impl<'a, P: $params> core::ops::Add<&'a mut Self> for $type<P> {
17            type Output = Self;
18
19            #[inline]
20            fn add(self, other: &'a mut Self) -> Self {
21                let mut result = self;
22                result += &*other;
23                result
24            }
25        }
26
27        impl<'b, P: $params> core::ops::Add<$type<P>> for &'b $type<P> {
28            type Output = $type<P>;
29
30            #[inline]
31            fn add(self, mut other: $type<P>) -> $type<P> {
32                other += self;
33                other
34            }
35        }
36
37        impl<'a, 'b, P: $params> core::ops::Add<&'a $type<P>> for &'b $type<P> {
38            type Output = $type<P>;
39
40            #[inline]
41            fn add(self, other: &'a $type<P>) -> $type<P> {
42                let mut result = *self;
43                result += &*other;
44                result
45            }
46        }
47
48        impl<'a, 'b, P: $params> core::ops::Add<&'a mut $type<P>> for &'b $type<P> {
49            type Output = $type<P>;
50
51            #[inline]
52            fn add(self, other: &'a mut $type<P>) -> $type<P> {
53                let mut result = *self;
54                result += &*other;
55                result
56            }
57        }
58
59        impl<'b, P: $params> core::ops::Sub<$type<P>> for &'b $type<P> {
60            type Output = $type<P>;
61
62            #[inline]
63            fn sub(self, other: $type<P>) -> $type<P> {
64                let mut result = *self;
65                result -= &other;
66                result
67            }
68        }
69
70        impl<'a, 'b, P: $params> core::ops::Sub<&'a $type<P>> for &'b $type<P> {
71            type Output = $type<P>;
72
73            #[inline]
74            fn sub(self, other: &'a $type<P>) -> $type<P> {
75                let mut result = *self;
76                result -= &*other;
77                result
78            }
79        }
80
81        impl<'a, 'b, P: $params> core::ops::Sub<&'a mut $type<P>> for &'b $type<P> {
82            type Output = $type<P>;
83
84            #[inline]
85            fn sub(self, other: &'a mut $type<P>) -> $type<P> {
86                let mut result = *self;
87                result -= &*other;
88                result
89            }
90        }
91
92        impl<P: $params> core::ops::Sub<Self> for $type<P> {
93            type Output = Self;
94
95            #[inline]
96            fn sub(self, other: Self) -> Self {
97                let mut result = self;
98                result -= &other;
99                result
100            }
101        }
102
103        impl<'a, P: $params> core::ops::Sub<&'a mut Self> for $type<P> {
104            type Output = Self;
105
106            #[inline]
107            fn sub(self, other: &'a mut Self) -> Self {
108                let mut result = self;
109                result -= &*other;
110                result
111            }
112        }
113
114        impl<P: $params> core::iter::Sum<Self> for $type<P> {
115            fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
116                iter.fold(Self::zero(), core::ops::Add::add)
117            }
118        }
119
120        impl<'a, P: $params> core::iter::Sum<&'a Self> for $type<P> {
121            fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
122                iter.fold(Self::zero(), core::ops::Add::add)
123            }
124        }
125
126        impl<P: $params> core::ops::AddAssign<Self> for $type<P> {
127            fn add_assign(&mut self, other: Self) {
128                *self += &other
129            }
130        }
131
132        impl<P: $params> core::ops::SubAssign<Self> for $type<P> {
133            fn sub_assign(&mut self, other: Self) {
134                *self -= &other
135            }
136        }
137
138        impl<'a, P: $params> core::ops::AddAssign<&'a mut Self> for $type<P> {
139            fn add_assign(&mut self, other: &'a mut Self) {
140                *self += &*other
141            }
142        }
143
144        impl<'a, P: $params> core::ops::SubAssign<&'a mut Self> for $type<P> {
145            fn sub_assign(&mut self, other: &'a mut Self) {
146                *self -= &*other
147            }
148        }
149    };
150}
151
152// Implements `MulAssign` and `DivAssign` by deferring to an implementation on &Self
153#[macro_export]
154macro_rules! impl_multiplicative_ops_from_ref {
155    ($type: ident, $params: ident) => {
156        impl<P: $params> core::ops::Mul<Self> for $type<P> {
157            type Output = Self;
158
159            #[inline]
160            fn mul(self, other: Self) -> Self {
161                let mut result = self;
162                result *= &other;
163                result
164            }
165        }
166
167        impl<P: $params> core::ops::Div<Self> for $type<P> {
168            type Output = Self;
169
170            #[inline]
171            fn div(self, other: Self) -> Self {
172                let mut result = self;
173                result.div_assign(&other);
174                result
175            }
176        }
177
178        impl<'a, P: $params> core::ops::Mul<&'a mut Self> for $type<P> {
179            type Output = Self;
180
181            #[inline]
182            fn mul(self, other: &'a mut Self) -> Self {
183                let mut result = self;
184                result *= &*other;
185                result
186            }
187        }
188
189        impl<'a, P: $params> core::ops::Div<&'a mut Self> for $type<P> {
190            type Output = Self;
191
192            #[inline]
193            fn div(self, other: &'a mut Self) -> Self {
194                let mut result = self;
195                result.div_assign(&*other);
196                result
197            }
198        }
199
200        impl<'b, P: $params> core::ops::Mul<$type<P>> for &'b $type<P> {
201            type Output = $type<P>;
202
203            #[inline]
204            fn mul(self, mut other: $type<P>) -> $type<P> {
205                other *= self;
206                other
207            }
208        }
209
210        impl<'a, 'b, P: $params> core::ops::Mul<&'a $type<P>> for &'b $type<P> {
211            type Output = $type<P>;
212
213            #[inline]
214            fn mul(self, other: &'a $type<P>) -> $type<P> {
215                let mut result = *self;
216                result *= &*other;
217                result
218            }
219        }
220
221        impl<'a, 'b, P: $params> core::ops::Mul<&'a mut $type<P>> for &'b $type<P> {
222            type Output = $type<P>;
223
224            #[inline]
225            fn mul(self, other: &'a mut $type<P>) -> $type<P> {
226                let mut result = *self;
227                result *= &*other;
228                result
229            }
230        }
231
232        impl<'b, P: $params> core::ops::Div<$type<P>> for &'b $type<P> {
233            type Output = $type<P>;
234
235            #[inline]
236            fn div(self, other: $type<P>) -> $type<P> {
237                let mut result = *self;
238                result.div_assign(&other);
239                result
240            }
241        }
242
243        impl<'a, 'b, P: $params> core::ops::Div<&'a $type<P>> for &'b $type<P> {
244            type Output = $type<P>;
245
246            #[inline]
247            fn div(self, other: &'a $type<P>) -> $type<P> {
248                let mut result = *self;
249                result.div_assign(&*other);
250                result
251            }
252        }
253
254        impl<'a, 'b, P: $params> core::ops::Div<&'a mut $type<P>> for &'b $type<P> {
255            type Output = $type<P>;
256
257            #[inline]
258            fn div(self, other: &'a mut $type<P>) -> $type<P> {
259                let mut result = *self;
260                result.div_assign(&*other);
261                result
262            }
263        }
264
265        impl<P: $params> core::iter::Product<Self> for $type<P> {
266            fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
267                iter.fold(Self::one(), core::ops::Mul::mul)
268            }
269        }
270
271        impl<'a, P: $params> core::iter::Product<&'a Self> for $type<P> {
272            fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
273                iter.fold(Self::one(), Mul::mul)
274            }
275        }
276
277        impl<P: $params> core::ops::MulAssign<Self> for $type<P> {
278            fn mul_assign(&mut self, other: Self) {
279                *self *= &other
280            }
281        }
282
283        impl<'a, P: $params> core::ops::DivAssign<&'a mut Self> for $type<P> {
284            fn div_assign(&mut self, other: &'a mut Self) {
285                self.div_assign(&*other)
286            }
287        }
288
289        impl<'a, P: $params> core::ops::MulAssign<&'a mut Self> for $type<P> {
290            fn mul_assign(&mut self, other: &'a mut Self) {
291                *self *= &*other
292            }
293        }
294
295        impl<P: $params> core::ops::DivAssign<Self> for $type<P> {
296            fn div_assign(&mut self, other: Self) {
297                self.div_assign(&other)
298            }
299        }
300    };
301}