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]
228macro_rules! impl_sum_prod_base_field {
229 ($alg_type:ty, $field_type:ty $(, ($type_param:ty, $param_name:ty))?) => {
230 paste::paste! {
231 impl$(<$param_name: $type_param>)? Sum<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
232 #[inline]
233 fn sum<I>(iter: I) -> Self
234 where
235 I: Iterator<Item = $field_type$(<$param_name>)?>,
236 {
237 iter.sum::<$field_type$(<$param_name>)?>().into()
238 }
239 }
240
241 impl$(<$param_name: $type_param>)? Product<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
242 #[inline]
243 fn product<I>(iter: I) -> Self
244 where
245 I: Iterator<Item = $field_type$(<$param_name>)?>,
246 {
247 iter.product::<$field_type$(<$param_name>)?>().into()
248 }
249 }
250 }
251 };
252}
253
254#[macro_export]
261macro_rules! impl_rng {
262 ($type:ty $(, ($type_param:ty, $param_name:ty))?) => {
263 paste::paste! {
264 impl$(<$param_name: $type_param>)? Distribution<$type$(<$param_name>)?> for StandardUniform {
265 #[inline]
266 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $type$(<$param_name>)? {
267 $type(rng.random())
268 }
269 }
270 }
271 };
272}
273
274#[macro_export]
281macro_rules! impl_packed_value {
282 ($alg_type:ty, $field_type:ty, $width:expr $(, ($type_param:ty, $param_name:ty))?) => {
283 paste::paste! {
284 unsafe impl$(<$param_name: $type_param>)? PackedValue for $alg_type$(<$param_name>)? {
285 type Value = $field_type$(<$param_name>)?;
286
287 const WIDTH: usize = $width;
288
289 #[inline]
290 fn from_slice(slice: &[Self::Value]) -> &Self {
291 assert_eq!(slice.len(), Self::WIDTH);
292 unsafe { &*slice.as_ptr().cast() }
293 }
294
295 #[inline]
296 fn from_slice_mut(slice: &mut [Self::Value]) -> &mut Self {
297 assert_eq!(slice.len(), Self::WIDTH);
298 unsafe { &mut *slice.as_mut_ptr().cast() }
299 }
300
301 #[inline]
302 fn as_slice(&self) -> &[Self::Value] {
303 &self.0
304 }
305
306 #[inline]
307 fn as_slice_mut(&mut self) -> &mut [Self::Value] {
308 &mut self.0
309 }
310
311 #[inline]
312 fn from_fn<F: FnMut(usize) -> Self::Value>(f: F) -> Self {
313 Self(core::array::from_fn(f))
314 }
315 }
316 }
317 };
318}
319
320pub use {
321 impl_add_assign, impl_add_base_field, impl_div_methods, impl_mul_base_field, impl_mul_methods,
322 impl_packed_value, impl_rng, impl_sub_assign, impl_sub_base_field, impl_sum_prod_base_field,
323 ring_sum,
324};