1macro_rules! use_primes {
4 () => {
5 use crate::{
6 field::fp::{F2, F3, F5, F7},
7 prime::{P2, P3, P5, P7, ValidPrime},
8 };
9 };
10}
11
12macro_rules! dispatch_struct {
16 ($(#[derive $derives:tt])? $vis:vis $name:ident $(<$life:lifetime>)? from $fq_name:ident) => {
17 $(#[derive $derives])*
18 $vis enum $name $(<$life>)? {
19 _2($fq_name<$($life,)? Fp<P2>>),
20 _3($fq_name<$($life,)? Fp<P3>>),
21 _5($fq_name<$($life,)? Fp<P5>>),
22 _7($fq_name<$($life,)? Fp<P7>>),
23 Big($fq_name<$($life,)? Fp<ValidPrime>>),
24 }
25 };
26}
27
28macro_rules! dispatch_vector_inner {
29 ($vis:vis fn $method:ident $helper_method:ident(&self, other: &$other:tt $(, $arg:ident: $ty:ty )* ) $(-> $ret:ty)?) => {
32 $vis fn $method(&self, other: &$other, $($arg: $ty),* ) $(-> $ret)* {
33 match (self, other) {
34 (Self::_2(x), $other::_2(y)) => x.$helper_method(y, $($arg),*),
35 (Self::_3(x), $other::_3(y)) => x.$helper_method(y, $($arg),*),
36 (Self::_5(x), $other::_5(y)) => x.$helper_method(y, $($arg),*),
37 (Self::_7(x), $other::_7(y)) => x.$helper_method(y, $($arg),*),
38 (Self::Big(x), $other::Big(y)) if x.prime() == y.prime() => x.$helper_method(y, $($arg),*),
39 (l, r) => {
40 panic!("Applying {} to vectors over different primes ({} and {})", stringify!($method), l.prime(), r.prime());
41 }
42 }
43 }
44 };
45 ($vis:vis fn $method:ident $helper_method:ident(&mut self, other: &$other:tt $(, $arg:ident: $ty:ty )* ) $(-> $ret:ty)?) => {
46 #[allow(unused_parens)]
47 $vis fn $method(&mut self, other: &$other, $($arg: $ty),* ) $(-> $ret)* {
48 match (self, other) {
49 (Self::_2(x), $other::_2(y)) => x.$helper_method(y, $($arg),*),
50 (Self::_3(x), $other::_3(y)) => x.$helper_method(y, $($arg),*),
51 (Self::_5(x), $other::_5(y)) => x.$helper_method(y, $($arg),*),
52 (Self::_7(x), $other::_7(y)) => x.$helper_method(y, $($arg),*),
53 (Self::Big(x), $other::Big(y)) if x.prime() == y.prime() => x.$helper_method(y, $($arg),*),
54 (l, r) => {
55 panic!("Applying {} to vectors over different primes ({} and {})", stringify!($method), l.prime(), r.prime());
56 }
57 }
58 }
59 };
60 ($vis:vis fn $method:ident $helper_method:ident(&mut self, other: $other:tt $(, $arg:ident: $ty:ty )* ) $(-> $ret:ty)?) => {
61 $vis fn $method(&mut self, other: $other, $($arg: $ty),* ) $(-> $ret)* {
62 match (self, other) {
63 (Self::_2(x), $other::_2(y)) => x.$helper_method(y, $($arg),*),
64 (Self::_3(x), $other::_3(y)) => x.$helper_method(y, $($arg),*),
65 (Self::_5(x), $other::_5(y)) => x.$helper_method(y, $($arg),*),
66 (Self::_7(x), $other::_7(y)) => x.$helper_method(y, $($arg),*),
67 (Self::Big(x), $other::Big(y)) if x.prime() == y.prime() => x.$helper_method(y, $($arg),*),
68 (l, r) => {
69 panic!("Applying {} to vectors over different primes ({} and {})", stringify!($method), l.prime(), r.prime());
70 }
71 }
72 }
73 };
74 ($vis:vis fn $method:ident $helper_method:ident(&mut self $(, $arg:ident: $ty:ty )*, @left: $other1:tt, right: $other2:tt ) $(-> $ret:ty)?) => {
75 #[allow(unused_parens)]
76 $vis fn $method(&mut self, $($arg: $ty),* , left: $other1, right: $other2 ) $(-> $ret)* {
77 match (self, left, right) {
78 (Self::_2(x), $other1::_2(y), $other2::_2(z)) => x.$helper_method($($arg),*, y, z),
79 (Self::_3(x), $other1::_3(y), $other2::_3(z)) => x.$helper_method($($arg),*, y, z),
80 (Self::_5(x), $other1::_5(y), $other2::_5(z)) => x.$helper_method($($arg),*, y, z),
81 (Self::_7(x), $other1::_7(y), $other2::_7(z)) => x.$helper_method($($arg),*, y, z),
82 (Self::Big(x), $other1::Big(y), $other2::Big(z)) if x.prime() == y.prime() && y.prime() == z.prime() => x.$helper_method($($arg),*, y, z),
83 _ => {
84 panic!("Applying {} to vectors over different primes", stringify!($method));
85 }
86 }
87 }
88 };
89 ($vis:vis fn $method:ident $helper_method:ident(&mut self $(, $arg:ident: $ty:ty )* ) -> (dispatch $ret:path)) => {
90 #[must_use]
91 $vis fn $method(&mut self, $($arg: $ty),* ) -> $ret {
92 match self {
93 Self::_2(x) => <$ret>::_2(x.$helper_method($($arg),*)),
94 Self::_3(x) => <$ret>::_3(x.$helper_method($($arg),*)),
95 Self::_5(x) => <$ret>::_5(x.$helper_method($($arg),*)),
96 Self::_7(x) => <$ret>::_7(x.$helper_method($($arg),*)),
97 Self::Big(x) => <$ret>::Big(x.$helper_method($($arg),*)),
98 }
99 }
100 };
101 ($vis:vis fn $method:ident $helper_method:ident(&self $(, $arg:ident: $ty:ty )* ) -> (dispatch $ret:path)) => {
102 #[must_use]
103 $vis fn $method(&self, $($arg: $ty),* ) -> $ret {
104 match self {
105 Self::_2(x) => <$ret>::_2(x.$helper_method($($arg),*)),
106 Self::_3(x) => <$ret>::_3(x.$helper_method($($arg),*)),
107 Self::_5(x) => <$ret>::_5(x.$helper_method($($arg),*)),
108 Self::_7(x) => <$ret>::_7(x.$helper_method($($arg),*)),
109 Self::Big(x) => <$ret>::Big(x.$helper_method($($arg),*)),
110 }
111 }
112 };
113 ($vis:vis fn $method:ident $helper_method:ident(self $(, $arg:ident: $ty:ty )* ) -> (dispatch $ret:path)) => {
114 #[must_use]
115 $vis fn $method(self, $($arg: $ty),* ) -> $ret {
116 match self {
117 Self::_2(x) => <$ret>::_2(x.$helper_method($($arg),*)),
118 Self::_3(x) => <$ret>::_3(x.$helper_method($($arg),*)),
119 Self::_5(x) => <$ret>::_5(x.$helper_method($($arg),*)),
120 Self::_7(x) => <$ret>::_7(x.$helper_method($($arg),*)),
121 Self::Big(x) => <$ret>::Big(x.$helper_method($($arg),*)),
122 }
123 }
124 };
125 ($vis:vis fn $method:ident $helper_method:ident(&mut self $(, $arg:ident: $ty:ty )* ) $(-> $ret:ty)?) => {
126 #[allow(unused_parens)]
127 $vis fn $method(&mut self, $($arg: $ty),* ) $(-> $ret)* {
128 match self {
129 Self::_2(x) => x.$helper_method($($arg),*),
130 Self::_3(x) => x.$helper_method($($arg),*),
131 Self::_5(x) => x.$helper_method($($arg),*),
132 Self::_7(x) => x.$helper_method($($arg),*),
133 Self::Big(x) => x.$helper_method($($arg),*),
134 }
135 }
136 };
137 ($vis:vis fn $method:ident $helper_method:ident(&self $(, $arg:ident: $ty:ty )* ) $(-> $ret:ty)?) => {
138 #[allow(unused_parens)]
139 $vis fn $method(&self, $($arg: $ty),* ) $(-> $ret)* {
140 match self {
141 Self::_2(x) => x.$helper_method($($arg),*),
142 Self::_3(x) => x.$helper_method($($arg),*),
143 Self::_5(x) => x.$helper_method($($arg),*),
144 Self::_7(x) => x.$helper_method($($arg),*),
145 Self::Big(x) => x.$helper_method($($arg),*),
146 }
147 }
148 };
149 ($vis:vis fn $method:ident $helper_method:ident(self $(, $arg:ident: $ty:ty )* ) $(-> $ret:ty)?) => {
150 #[allow(unused_parens)]
151 $vis fn $method(self, $($arg: $ty),* ) $(-> $ret)* {
152 match self {
153 Self::_2(x) => x.$helper_method($($arg),*),
154 Self::_3(x) => x.$helper_method($($arg),*),
155 Self::_5(x) => x.$helper_method($($arg),*),
156 Self::_7(x) => x.$helper_method($($arg),*),
157 Self::Big(x) => x.$helper_method($($arg),*),
158 }
159 }
160 };
161}
162
163macro_rules! dispatch_vector {
164 () => {};
165 ($vis:vis fn $method:ident $tt:tt $(-> $ret:tt)?; $($tail:tt)*) => {
166 dispatch_vector_inner! {
167 $vis fn $method $method $tt $(-> $ret)*
168 }
169 dispatch_vector!{$($tail)*}
170 };
171 ($vis:vis fn @$method:ident $tt:tt $(-> $ret:tt)?; $($tail:tt)*) => {
172 paste::paste! {
173 dispatch_vector_inner! {
174 $vis fn $method [<$method _helper>] $tt $(-> $ret)*
175 }
176 }
177 dispatch_vector!{$($tail)*}
178 };
179 ($vis:vis fn $method:ident <P: Prime> (p: P $(, $arg:ident: $ty:ty )*) -> (from $fq_name:tt); $($tail:tt)*) => {
181 $vis fn $method<P: Prime>(p: P, $($arg: $ty),*) -> Self {
182 match p.as_u32() {
183 2 => Self::_2($fq_name::$method(F2, $($arg),*)),
184 3 => Self::_3($fq_name::$method(F3, $($arg),*)),
185 5 => Self::_5($fq_name::$method(F5, $($arg),*)),
186 7 => Self::_7($fq_name::$method(F7, $($arg),*)),
187 _ => Self::Big($fq_name::$method(Fp::new(p.to_dyn()), $($arg),*)),
188 }
189 }
190 dispatch_vector!{$($tail)*}
191 };
192 ($vis:vis fn $method:ident <P: Prime> (p: P $(, $arg:ident: $ty:ty )*) -> (from io $fq_name:tt); $($tail:tt)*) => {
194 $vis fn $method<P: Prime>(p: P, $($arg: $ty),*) -> std::io::Result<Self> {
195 Ok(match p.as_u32() {
196 2 => Self::_2($fq_name::$method(F2, $($arg),*)?),
197 3 => Self::_3($fq_name::$method(F3, $($arg),*)?),
198 5 => Self::_5($fq_name::$method(F5, $($arg),*)?),
199 7 => Self::_7($fq_name::$method(F7, $($arg),*)?),
200 _ => Self::Big($fq_name::$method(Fp::new(p.to_dyn()), $($arg),*)?),
201 })
202 }
203 dispatch_vector!{$($tail)*}
204 }
205}
206
207macro_rules! impl_from_inner {
208 ($var:tt, $p:ty) => {
209 impl<'a> From<FqVector<Fp<$p>>> for FpVector {
210 fn from(x: FqVector<Fp<$p>>) -> Self {
211 FpVector::$var(x)
212 }
213 }
214 };
215}
216
217macro_rules! impl_from {
218 () => {
219 impl_from_inner!(_2, P2);
220 impl_from_inner!(_3, P3);
221 impl_from_inner!(_5, P5);
222 impl_from_inner!(_7, P7);
223 impl_from_inner!(Big, ValidPrime);
224 };
225}
226
227macro_rules! impl_try_into_inner {
228 ($var:tt, $p:ty) => {
229 impl<'a> TryInto<&'a mut FqVector<Fp<$p>>> for &'a mut FpVector {
230 type Error = ();
231
232 fn try_into(self) -> Result<&'a mut FqVector<Fp<$p>>, Self::Error> {
233 match self {
234 FpVector::$var(x) => Ok(x),
235 _ => Err(()),
236 }
237 }
238 }
239 };
240}
241
242macro_rules! impl_try_into {
243 () => {
244 impl_try_into_inner!(_2, P2);
245 impl_try_into_inner!(_3, P3);
246 impl_try_into_inner!(_5, P5);
247 impl_try_into_inner!(_7, P7);
248 impl_try_into_inner!(Big, ValidPrime);
249 };
250}
251
252pub(super) use dispatch_struct;
253pub(super) use dispatch_vector;
254pub(super) use impl_try_into;
255pub(super) use use_primes;