binius_field/
arithmetic_traits.rs1use std::{
5 iter::Sum,
6 ops::{Add, AddAssign, Sub, SubAssign},
7};
8
9pub trait Square {
11 fn square(self) -> Self;
13}
14
15pub trait WideMul: Sized {
30 type Output: Default
31 + Clone
32 + Sum
33 + Add<Output = Self::Output>
34 + AddAssign
35 + Sub<Output = Self::Output>
36 + SubAssign;
37
38 fn wide_mul(a: Self, b: Self) -> Self::Output;
39 fn reduce(wide: Self::Output) -> Self;
40}
41
42macro_rules! impl_trivial_wide_mul {
43 ($name:ty) => {
44 impl $crate::arithmetic_traits::WideMul for $name {
45 type Output = Self;
46
47 #[inline]
48 fn wide_mul(a: Self, b: Self) -> Self {
49 a * b
50 }
51
52 #[inline]
53 fn reduce(wide: Self) -> Self {
54 wide
55 }
56 }
57 };
58}
59
60pub(crate) use impl_trivial_wide_mul;
61
62pub trait InvertOrZero {
64 fn invert_or_zero(self) -> Self;
66}
67
68pub trait TaggedMul<Strategy> {
70 fn mul(self, rhs: Self) -> Self;
71}
72
73macro_rules! impl_mul_with {
74 ($name:ident @ $strategy:ty) => {
75 impl std::ops::Mul for $name {
76 type Output = Self;
77
78 #[inline]
79 fn mul(self, rhs: Self) -> Self {
80 $crate::tracing::trace_multiplication!($name);
81
82 $crate::arithmetic_traits::TaggedMul::<$strategy>::mul(self, rhs)
83 }
84 }
85 };
86 ($name:ty => $bigger:ty) => {
87 impl std::ops::Mul for $name {
88 type Output = Self;
89
90 #[inline]
91 fn mul(self, rhs: Self) -> Self {
92 $crate::arch::portable::packed::mul_as_bigger_type::<_, $bigger>(self, rhs)
93 }
94 }
95 };
96}
97
98pub(crate) use impl_mul_with;
99
100pub trait TaggedSquare<Strategy> {
102 fn square(self) -> Self;
103}
104
105macro_rules! impl_square_with {
106 ($name:ident @ $strategy:ty) => {
107 impl $crate::arithmetic_traits::Square for $name {
108 #[inline]
109 fn square(self) -> Self {
110 $crate::arithmetic_traits::TaggedSquare::<$strategy>::square(self)
111 }
112 }
113 };
114 ($name:ty => $bigger:ty) => {
115 impl $crate::arithmetic_traits::Square for $name {
116 #[inline]
117 fn square(self) -> Self {
118 $crate::arch::portable::packed::square_as_bigger_type::<_, $bigger>(self)
119 }
120 }
121 };
122}
123
124pub(crate) use impl_square_with;
125
126pub trait TaggedInvertOrZero<Strategy> {
128 fn invert_or_zero(self) -> Self;
129}
130
131macro_rules! impl_invert_with {
132 ($name:ident @ $strategy:ty) => {
133 impl $crate::arithmetic_traits::InvertOrZero for $name {
134 #[inline]
135 fn invert_or_zero(self) -> Self {
136 $crate::arithmetic_traits::TaggedInvertOrZero::<$strategy>::invert_or_zero(self)
137 }
138 }
139 };
140 ($name:ty => $bigger:ty) => {
141 impl $crate::arithmetic_traits::InvertOrZero for $name {
142 #[inline]
143 fn invert_or_zero(self) -> Self {
144 $crate::arch::portable::packed::invert_as_bigger_type::<_, $bigger>(self)
145 }
146 }
147 };
148}
149
150pub(crate) use impl_invert_with;