primitives/utils/
arithmetic_ops.rs

1//! This code is borrowed from Renegade Finance's ark_mpc implementation.
2//! https://github.com/renegade-fi/ark-mpc
3
4/// Given an implementation of an arithmetic trait on two borrowed references,
5/// this macro implements the same arithmetic on the owned and partially-owned
6/// variants
7#[macro_export]
8macro_rules! impl_borrow_variants {
9    // Single type trait
10    ($target:ty, $trait:ident, $fn_name:ident, $op:tt, $($gen:ident: $gen_ty:ident),*) => {
11        // Single implementation, owned target type
12        impl<$($gen:$gen_ty),*> $trait for $target {
13            type Output = $target;
14
15            #[inline]
16            fn $fn_name(self) -> Self::Output {
17                $op &self
18            }
19        }
20    };
21
22    // Output type same as left hand side
23    ($lhs:ty, $trait:ident, $fn_name:ident, $op:tt, $rhs:ty, $($gen:ident: $gen_ty:ident),*) => {
24        impl_borrow_variants!($lhs, $trait, $fn_name, $op, $rhs, Output=$lhs, $($gen: $gen_ty),*);
25    };
26
27    // Output type specified
28    ($lhs:ty, $trait:ident, $fn_name:ident, $op:tt, $rhs:ty, Output=$out_type:ty, $($gen:ident: $gen_ty:ident),*) => {
29        /// lhs borrowed, rhs owned
30        impl<'a, $($gen: $gen_ty),*> $trait<$rhs> for &'a $lhs {
31            type Output = $out_type;
32
33            #[inline]
34            fn $fn_name(self, rhs: $rhs) -> Self::Output {
35                self $op &rhs
36            }
37        }
38
39        /// lhs owned, rhs borrowed
40        impl<'a, $($gen: $gen_ty),*> $trait<&'a $rhs> for $lhs {
41            type Output = $out_type;
42
43            #[inline]
44            fn $fn_name(self, rhs: &'a $rhs) -> Self::Output {
45                &self $op rhs
46            }
47        }
48
49        /// lhs owned, rhs owned
50        impl<$($gen: $gen_ty),*> $trait<$rhs> for $lhs {
51            type Output = $out_type;
52
53            #[inline]
54            fn $fn_name(self, rhs: $rhs) -> Self::Output {
55                &self $op &rhs
56            }
57        }
58    }
59}
60
61/// A macro to implement commutative variants of a binary operation
62#[macro_export]
63macro_rules! impl_commutative {
64    ($lhs:ty, $trait:ident, $fn_name:ident, $op:tt, $rhs:ty, $($gen:ident: $gen_ty:ident),*) => {
65        impl_commutative!($lhs, $trait, $fn_name, $op, $rhs, Output=$lhs, $($gen: $gen_ty),*);
66    };
67
68    ($lhs:ty, $trait:ident, $fn_name:ident, $op:tt, $rhs:ty, Output=$out_type:ty, $($gen:ident: $gen_ty:ident),*) => {
69        /// lhs borrowed, rhs borrowed
70        impl<'a, $($gen: $gen_ty),*> $trait<&'a $lhs> for &'a $rhs {
71            type Output = $out_type;
72
73            #[inline]
74            fn $fn_name(self, rhs: &'a $lhs) -> Self::Output {
75                rhs $op self
76            }
77        }
78
79        /// lhs borrowed, rhs owned
80        impl<'a, $($gen: $gen_ty),*> $trait<$lhs> for &'a $rhs
81        {
82            type Output = $out_type;
83
84            #[inline]
85            fn $fn_name(self, rhs: $lhs) -> Self::Output {
86                &rhs $op self
87            }
88        }
89
90        /// lhs owned, rhs borrowed
91        impl<'a, $($gen: $gen_ty),*> $trait<&'a $lhs> for $rhs
92        {
93            type Output = $out_type;
94
95            #[inline]
96            fn $fn_name(self, rhs: &'a $lhs) -> Self::Output {
97                rhs $op &self
98            }
99        }
100
101        /// lhs owned, rhs owned
102        impl<$($gen: $gen_ty),*> $trait<$lhs> for $rhs
103        {
104            type Output = $out_type;
105
106            #[inline]
107            fn $fn_name(self, rhs: $lhs) -> Self::Output {
108                &rhs $op &self
109            }
110        }
111    };
112}
113
114pub use impl_borrow_variants;
115pub use impl_commutative;