Skip to content

Commit 84ccc09

Browse files
committed
massively reduce repetition in ops macro
1 parent b568f31 commit 84ccc09

File tree

4 files changed

+105
-178
lines changed

4 files changed

+105
-178
lines changed

ff/src/fields/arithmetic.rs

Lines changed: 101 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -204,194 +204,123 @@ macro_rules! sqrt_impl {
204204
}};
205205
}
206206

207-
// Implements AddAssign on Self by deferring to an implementation on &Self
208-
#[macro_export]
209-
macro_rules! impl_additive_ops_from_ref {
210-
($type: ident, $([$type_params:ident, $bounds:ident$(, $keyword:ident)?$(, {$const:ident})?]),*) => {
211-
#[allow(unused_qualifications)]
212-
impl<$($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::Add<Self> for $type<$($type_params),*> {
213-
type Output = Self;
214-
215-
#[inline]
216-
fn add(self, other: Self) -> Self {
217-
let mut result = self;
218-
result.add_assign(&other);
219-
result
220-
}
221-
}
222-
223-
#[allow(unused_qualifications)]
224-
impl<'a, $($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::Add<&'a mut Self> for $type<$($type_params),*> {
225-
type Output = Self;
226-
227-
#[inline]
228-
fn add(self, other: &'a mut Self) -> Self {
229-
let mut result = self;
230-
result.add_assign(&*other);
231-
result
232-
}
233-
}
234-
235-
#[allow(unused_qualifications)]
236-
impl<$($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::Sub<Self> for $type<$($type_params),*> {
237-
type Output = Self;
238-
239-
#[inline]
240-
fn sub(self, other: Self) -> Self {
241-
let mut result = self;
242-
result.sub_assign(&other);
243-
result
244-
}
245-
}
246-
247-
#[allow(unused_qualifications)]
248-
impl<'a, $($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::Sub<&'a mut Self> for $type<$($type_params),*> {
249-
type Output = Self;
250-
251-
#[inline]
252-
fn sub(self, other: &'a mut Self) -> Self {
253-
let mut result = self;
254-
result.sub_assign(&*other);
255-
result
256-
}
257-
}
258-
259-
#[allow(unused_qualifications)]
260-
impl<$($($keyword)? $type_params: $bounds$(<$const>)?),*> core::iter::Sum<Self> for $type<$($type_params),*> {
261-
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
262-
iter.fold(Self::zero(), core::ops::Add::add)
263-
}
264-
}
265-
266-
#[allow(unused_qualifications)]
267-
impl<'a, $($($keyword)? $type_params: $bounds$(<$const>)?),*> core::iter::Sum<&'a Self> for $type<$($type_params),*> {
268-
fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
269-
iter.fold(Self::zero(), core::ops::Add::add)
270-
}
271-
}
272-
273-
#[allow(unused_qualifications)]
274-
impl<$($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::AddAssign<Self> for $type<$($type_params),*> {
275-
fn add_assign(&mut self, other: Self) {
276-
self.add_assign(&other)
277-
}
278-
}
279-
280-
#[allow(unused_qualifications)]
281-
impl<$($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::SubAssign<Self> for $type<$($type_params),*> {
282-
fn sub_assign(&mut self, other: Self) {
283-
self.sub_assign(&other)
284-
}
285-
}
286-
287-
#[allow(unused_qualifications)]
288-
impl<'a, $($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::AddAssign<&'a mut Self> for $type<$($type_params),*> {
289-
fn add_assign(&mut self, other: &'a mut Self) {
290-
self.add_assign(&*other)
291-
}
207+
macro_rules! result_body {
208+
($name:ident, $self:ident, $other:ident, $($deref:tt)?) => {
209+
paste::paste! {
210+
let mut result = $self;
211+
result.[<$name _assign>](&$($deref)?$other);
212+
result
292213
}
214+
}
215+
}
293216

294-
#[allow(unused_qualifications)]
295-
impl<'a, $($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::SubAssign<&'a mut Self> for $type<$($type_params),*> {
296-
fn sub_assign(&mut self, other: &'a mut Self) {
297-
self.sub_assign(&*other)
298-
}
217+
macro_rules! assign_body {
218+
($name:ident, $self:ident, $other:ident, $($deref:tt)?) => {
219+
paste::paste! {
220+
$self.[<$name _assign>](&$($deref)?$other);
299221
}
300-
};
222+
}
301223
}
302224

303-
// Implements AddAssign on Self by deferring to an implementation on &Self
304225
#[macro_export]
305-
macro_rules! impl_multiplicative_ops_from_ref {
306-
($type: ident, $([$type_params:ident, $bounds:ident$(, $keyword:ident)?$(, {$const:ident})?]),*) => {
307-
#[allow(unused_qualifications)]
308-
impl<$($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::Mul<Self> for $type<$($type_params),*> {
309-
type Output = Self;
310-
311-
#[inline]
312-
fn mul(self, other: Self) -> Self {
313-
let mut result = self;
314-
result.mul_assign(&other);
315-
result
316-
}
317-
}
318-
319-
#[allow(unused_qualifications)]
320-
impl<$($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::Div<Self> for $type<$($type_params),*> {
321-
type Output = Self;
322-
323-
#[inline]
324-
fn div(self, other: Self) -> Self {
325-
let mut result = self;
326-
result.div_assign(&other);
327-
result
328-
}
329-
}
330-
331-
#[allow(unused_qualifications)]
332-
impl<'a, $($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::Mul<&'a mut Self> for $type<$($type_params),*> {
333-
type Output = Self;
226+
macro_rules! impl_ops_from_ref {
227+
($type: ident,
228+
$([
229+
$type_params:ident,
230+
$bounds:ident
231+
$(, $keyword:ident)?
232+
$(, {$const:ident})?
233+
]),*
234+
) => {
235+
macro_rules! instantiate {
236+
($d:tt) => {
237+
macro_rules! ops {
238+
(
239+
$name:ident,
240+
$body:ident
241+
$d(, {$d output:ident})?
242+
$d(, <$d lifetime:tt>)?
243+
$d(, [$d mut:tt])?
244+
$d(, ($d deref:tt))?
245+
) => {
246+
paste::paste! {
247+
#[allow(unused_qualifications)]
248+
impl<
249+
$d($d lifetime, )?
250+
$(
251+
$($keyword)?
252+
$type_params:
253+
$bounds$(<$const>)?
254+
),*
255+
> [<$name:camel>]<$d(&$d lifetime )?$d($d mut )?Self> for $type<$($type_params),*>
256+
{
257+
$d(type $d output = Self;)?
258+
259+
#[inline]
260+
fn $name(self, other: Self) -> Self {
261+
$body!($name, self, other, $d($d deref)?);
262+
}
263+
}
264+
}
265+
}
266+
}
334267

335-
#[inline]
336-
fn mul(self, other: &'a mut Self) -> Self {
337-
let mut result = self;
338-
result.mul_assign(&*other);
339-
result
268+
macro_rules! iter {
269+
(
270+
$name:ident,
271+
$ident:ident,
272+
$op:ident
273+
$d(, <$d lifetime:tt>)?
274+
) => {
275+
paste::paste! {
276+
#[allow(unused_qualifications)]
277+
impl<
278+
$d($d lifetime, )?
279+
$(
280+
$($keyword)?
281+
$type_params:
282+
$bounds$(<$const>)?
283+
),*
284+
> [<$name:camel>]<$d(&$d lifetime )?Self> for $type<$($type_params),*>
285+
{
286+
fn $name<I: Iterator<Item = $d(&$d lifetime )?Self>>(iter: I) -> Self {
287+
iter.fold(Self::$ident(), [<$op:camel>]::$op)
288+
}
289+
}
290+
}
291+
}
292+
}
340293
}
341294
}
342295

343-
#[allow(unused_qualifications)]
344-
impl<'a, $($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::Div<&'a mut Self> for $type<$($type_params),*> {
345-
type Output = Self;
296+
instantiate!($);
346297

347-
#[inline]
348-
fn div(self, other: &'a mut Self) -> Self {
349-
let mut result = self;
350-
result.div_assign(&*other);
351-
result
352-
}
353-
}
298+
ops!(add, result_body, {Output});
299+
ops!(add, result_body, {Output}, <'a>, [mut], (*));
300+
ops!(sub, result_body, {Output});
301+
ops!(sub, result_body, {Output}, <'a>, [mut], (*));
354302

355-
#[allow(unused_qualifications)]
356-
impl<$($($keyword)? $type_params: $bounds$(<$const>)?),*> core::iter::Product<Self> for $type<$($type_params),*> {
357-
fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
358-
iter.fold(Self::one(), core::ops::Mul::mul)
359-
}
360-
}
303+
ops!(mul, result_body, {Output});
304+
ops!(mul, result_body, {Output}, <'a>, [mut], (*));
305+
ops!(div, result_body, {Output});
306+
ops!(div, result_body, {Output}, <'a>, [mut], (*));
361307

362-
#[allow(unused_qualifications)]
363-
impl<'a, $($($keyword)? $type_params: $bounds$(<$const>)?),*> core::iter::Product<&'a Self> for $type<$($type_params),*> {
364-
fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
365-
iter.fold(Self::one(), Mul::mul)
366-
}
367-
}
308+
ops!(add_assign, assign_body);
309+
ops!(add_assign, assign_body, <'a>, [mut], (*));
310+
ops!(sub_assign, assign_body);
311+
ops!(sub_assign, assign_body, <'a>, [mut], (*));
368312

369-
#[allow(unused_qualifications)]
370-
impl<$($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::MulAssign<Self> for $type<$($type_params),*> {
371-
fn mul_assign(&mut self, other: Self) {
372-
self.mul_assign(&other)
373-
}
374-
}
375313

376-
#[allow(unused_qualifications)]
377-
impl<'a, $($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::DivAssign<&'a mut Self> for $type<$($type_params),*> {
378-
fn div_assign(&mut self, other: &'a mut Self) {
379-
self.div_assign(&*other)
380-
}
381-
}
314+
ops!(mul_assign, assign_body);
315+
ops!(mul_assign, assign_body, <'a>, [mut], (*));
316+
ops!(div_assign, assign_body);
317+
ops!(div_assign, assign_body, <'a>, [mut], (*));
382318

383-
#[allow(unused_qualifications)]
384-
impl<'a, $($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::MulAssign<&'a mut Self> for $type<$($type_params),*> {
385-
fn mul_assign(&mut self, other: &'a mut Self) {
386-
self.mul_assign(&*other)
387-
}
388-
}
319+
use core::iter::{Sum, Product};
389320

390-
#[allow(unused_qualifications)]
391-
impl<$($($keyword)? $type_params: $bounds$(<$const>)?),*> core::ops::DivAssign<Self> for $type<$($type_params),*> {
392-
fn div_assign(&mut self, other: Self) {
393-
self.div_assign(&other)
394-
}
395-
}
321+
iter!(sum, zero, add);
322+
iter!(sum, zero, add, <'a>);
323+
iter!(product, one, mul);
324+
iter!(product, one, mul, <'a>);
396325
};
397326
}

ff/src/fields/models/cubic_extension.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,8 @@ impl<'a, P: CubicExtParameters> Div<&'a CubicExtField<P>> for CubicExtField<P> {
432432
}
433433
}
434434

435-
impl_additive_ops_from_ref!(CubicExtField, [P, CubicExtParameters]);
436-
impl_multiplicative_ops_from_ref!(CubicExtField, [P, CubicExtParameters]);
435+
impl_ops_from_ref!(CubicExtField, [P, CubicExtParameters]);
436+
437437
impl<'a, P: CubicExtParameters> AddAssign<&'a Self> for CubicExtField<P> {
438438
#[inline]
439439
fn add_assign(&mut self, other: &Self) {

ff/src/fields/models/fp.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -775,8 +775,7 @@ impl<'a, P: FpParams<N>, const N: usize> Div<&'a Fp<P, N>> for Fp<P, N> {
775775
result
776776
}
777777
}
778-
impl_additive_ops_from_ref!(Fp, [P, FpParams, {N}], [N, usize, const]);
779-
impl_multiplicative_ops_from_ref!(Fp, [P, FpParams, {N}], [N, usize, const]);
778+
impl_ops_from_ref!(Fp, [P, FpParams, {N}], [N, usize, const]);
780779

781780
impl<'a, P: FpParams<N>, const N: usize> AddAssign<&'a Self> for Fp<P, N> {
782781
#[inline]

ff/src/fields/models/quadratic_extension.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -492,8 +492,7 @@ impl<'a, P: QuadExtParameters> SubAssign<&'a Self> for QuadExtField<P> {
492492
}
493493
}
494494

495-
impl_additive_ops_from_ref!(QuadExtField, [P, QuadExtParameters]);
496-
impl_multiplicative_ops_from_ref!(QuadExtField, [P, QuadExtParameters]);
495+
impl_ops_from_ref!(QuadExtField, [P, QuadExtParameters]);
497496

498497
impl<'a, P: QuadExtParameters> MulAssign<&'a Self> for QuadExtField<P> {
499498
#[inline]

0 commit comments

Comments
 (0)