p3_field/
op_assign_macros.rs1#[macro_export]
23macro_rules! impl_add_assign {
24 ($type:ty $(, ($type_param:ty, $param_name:ty))?) => {
25 paste::paste! {
26 impl<$($param_name: $type_param,)? T: Into<Self>> AddAssign<T> for $type$(<$param_name>)? {
27 #[inline]
28 fn add_assign(&mut self, rhs: T) {
29 *self = *self + rhs.into();
30 }
31 }
32 }
33 };
34}
35
36#[macro_export]
40macro_rules! ring_sum {
41 ($type:ty $(, ($type_param:ty, $param_name:ty))?) => {
42 paste::paste! {
43 impl$(<$param_name: $type_param>)? Sum for $type$(<$param_name>)? {
44 #[inline]
45 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
46 iter.reduce(|x, y| x + y).unwrap_or(Self::ZERO)
47 }
48 }
49 }
50 };
51}
52
53#[macro_export]
59macro_rules! impl_sub_assign {
60 ($type:ty $(, ($type_param:ty, $param_name:ty))?) => {
61 paste::paste! {
62 impl<$($param_name: $type_param,)? T: Into<Self>> SubAssign<T> for $type$(<$param_name>)? {
63 #[inline]
64 fn sub_assign(&mut self, rhs: T) {
65 *self = *self - rhs.into();
66 }
67 }
68 }
69 };
70}
71
72#[macro_export]
79macro_rules! impl_mul_methods {
80 ($type:ty $(, ($type_param:ty, $param_name:ty))?) => {
81 paste::paste! {
82 impl<$($param_name: $type_param,)? T: Into<Self>> MulAssign<T> for $type$(<$param_name>)? {
83 #[inline]
84 fn mul_assign(&mut self, rhs: T) {
85 *self = *self * rhs.into();
86 }
87 }
88
89 impl$(<$param_name: $type_param>)? Product for $type$(<$param_name>)? {
90 #[inline]
91 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
92 iter.reduce(|x, y| x * y).unwrap_or(Self::ONE)
93 }
94 }
95 }
96 };
97}
98
99#[macro_export]
105macro_rules! impl_add_base_field {
106 ($alg_type:ty, $field_type:ty $(, ($type_param:ty, $param_name:ty))?) => {
107 paste::paste! {
108 impl$(<$param_name: $type_param>)? Add<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
109 type Output = Self;
110
111 #[inline]
112 fn add(self, rhs: $field_type$(<$param_name>)?) -> Self {
113 self + Self::from(rhs)
114 }
115 }
116
117 impl$(<$param_name: $type_param>)? Add<$alg_type$(<$param_name>)?> for $field_type$(<$param_name>)? {
118 type Output = $alg_type$(<$param_name>)?;
119
120 #[inline]
121 fn add(self, rhs: $alg_type$(<$param_name>)?) -> Self::Output {
122 $alg_type::from(self) + rhs
123 }
124 }
125 }
126 };
127}
128
129#[macro_export]
135macro_rules! impl_sub_base_field {
136 ($alg_type:ty, $field_type:ty $(, ($type_param:ty, $param_name:ty))?) => {
137 paste::paste! {
138 impl$(<$param_name: $type_param>)? Sub<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
139 type Output = Self;
140
141 #[inline]
142 fn sub(self, rhs: $field_type$(<$param_name>)?) -> Self {
143 self - Self::from(rhs)
144 }
145 }
146
147 impl$(<$param_name: $type_param>)? Sub<$alg_type$(<$param_name>)?> for $field_type$(<$param_name>)? {
148 type Output = $alg_type$(<$param_name>)?;
149
150 #[inline]
151 fn sub(self, rhs: $alg_type$(<$param_name>)?) -> Self::Output {
152 $alg_type::from(self) - rhs
153 }
154 }
155 }
156 };
157}
158
159#[macro_export]
165macro_rules! impl_mul_base_field {
166 ($alg_type:ty, $field_type:ty $(, ($type_param:ty, $param_name:ty))?) => {
167 paste::paste! {
168 impl$(<$param_name: $type_param>)? Mul<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
169 type Output = Self;
170
171 #[inline]
172 fn mul(self, rhs: $field_type$(<$param_name>)?) -> Self {
173 self * Self::from(rhs)
174 }
175 }
176
177 impl$(<$param_name: $type_param>)? Mul<$alg_type$(<$param_name>)?> for $field_type$(<$param_name>)? {
178 type Output = $alg_type$(<$param_name>)?;
179
180 #[inline]
181 fn mul(self, rhs: $alg_type$(<$param_name>)?) -> Self::Output {
182 $alg_type::from(self) * rhs
183 }
184 }
185 }
186 };
187}
188
189#[macro_export]
198macro_rules! impl_div_methods {
199 ($alg_type:ty, $field_type:ty $(, ($type_param:ty, $param_name:ty))?) => {
200 paste::paste! {
201 impl$(<$param_name: $type_param>)? Div<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
202 type Output = Self;
203
204 #[inline]
205 #[allow(clippy::suspicious_arithmetic_impl)]
206 fn div(self, rhs: $field_type$(<$param_name>)?) -> Self {
207 self * Self::from(rhs.inverse())
208 }
209 }
210
211 impl$(<$param_name: $type_param>)? DivAssign<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
212 #[inline]
213 #[allow(clippy::suspicious_op_assign_impl)]
214 fn div_assign(&mut self, rhs: $field_type$(<$param_name>)?) {
215 *self *= Self::from(rhs.inverse());
216 }
217 }
218 }
219 };
220}
221
222#[macro_export]
229macro_rules! impl_packed_field_div {
230 ($type:ty $(, ($type_param:ty, $param_name:ty))?) => {
231 paste::paste! {
232 impl$(<$param_name: $type_param>)? Div for $type$(<$param_name>)? {
233 type Output = Self;
234
235 #[inline]
236 #[allow(clippy::suspicious_arithmetic_impl)]
237 fn div(self, rhs: Self) -> Self {
238 use p3_field::{Field, PackedValue, PrimeCharacteristicRing};
239
240 let mut result = Self::broadcast(<Self as PackedValue>::Value::ZERO);
241 p3_field::batch_multiplicative_inverse_general(
242 rhs.as_slice(),
243 result.as_slice_mut(),
244 |x| x.inverse(),
245 );
246 self * result
247 }
248 }
249
250 impl$(<$param_name: $type_param>)? DivAssign for $type$(<$param_name>)? {
251 #[inline]
252 fn div_assign(&mut self, rhs: Self) {
253 *self = *self / rhs;
254 }
255 }
256 }
257 };
258}
259
260#[macro_export]
266macro_rules! impl_sum_prod_base_field {
267 ($alg_type:ty, $field_type:ty $(, ($type_param:ty, $param_name:ty))?) => {
268 paste::paste! {
269 impl$(<$param_name: $type_param>)? Sum<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
270 #[inline]
271 fn sum<I>(iter: I) -> Self
272 where
273 I: Iterator<Item = $field_type$(<$param_name>)?>,
274 {
275 iter.sum::<$field_type$(<$param_name>)?>().into()
276 }
277 }
278
279 impl$(<$param_name: $type_param>)? Product<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
280 #[inline]
281 fn product<I>(iter: I) -> Self
282 where
283 I: Iterator<Item = $field_type$(<$param_name>)?>,
284 {
285 iter.product::<$field_type$(<$param_name>)?>().into()
286 }
287 }
288 }
289 };
290}
291
292#[macro_export]
299macro_rules! impl_rng {
300 ($type:ty $(, ($type_param:ty, $param_name:ty))?) => {
301 paste::paste! {
302 impl$(<$param_name: $type_param>)? Distribution<$type$(<$param_name>)?> for StandardUniform {
303 #[inline]
304 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $type$(<$param_name>)? {
305 $type(rng.random())
306 }
307 }
308 }
309 };
310}
311
312#[macro_export]
319macro_rules! impl_packed_value {
320 ($alg_type:ty, $field_type:ty, $width:expr $(, ($type_param:ty, $param_name:ty))?) => {
321 paste::paste! {
322 unsafe impl$(<$param_name: $type_param>)? PackedValue for $alg_type$(<$param_name>)? {
323 type Value = $field_type$(<$param_name>)?;
324
325 const WIDTH: usize = $width;
326
327 #[inline]
328 fn from_slice(slice: &[Self::Value]) -> &Self {
329 assert_eq!(slice.len(), Self::WIDTH);
330 unsafe { &*slice.as_ptr().cast() }
331 }
332
333 #[inline]
334 fn from_slice_mut(slice: &mut [Self::Value]) -> &mut Self {
335 assert_eq!(slice.len(), Self::WIDTH);
336 unsafe { &mut *slice.as_mut_ptr().cast() }
337 }
338
339 #[inline]
340 fn as_slice(&self) -> &[Self::Value] {
341 &self.0
342 }
343
344 #[inline]
345 fn as_slice_mut(&mut self) -> &mut [Self::Value] {
346 &mut self.0
347 }
348
349 #[inline]
350 fn from_fn<F: FnMut(usize) -> Self::Value>(f: F) -> Self {
351 Self(core::array::from_fn(f))
352 }
353 }
354 }
355 };
356}
357
358pub use impl_add_assign;
359pub use impl_add_base_field;
360pub use impl_div_methods;
361pub use impl_mul_base_field;
362pub use impl_mul_methods;
363pub use impl_packed_field_div;
364pub use impl_packed_value;
365pub use impl_rng;
366pub use impl_sub_assign;
367pub use impl_sub_base_field;
368pub use impl_sum_prod_base_field;
369pub use ring_sum;