#[macro_export]
macro_rules! impl_add_assign {
($type:ty $(, ($type_param:ty, $param_name:ty))?) => {
paste::paste! {
impl<$($param_name: $type_param,)? T: Into<Self>> AddAssign<T> for $type$(<$param_name>)? {
#[inline]
fn add_assign(&mut self, rhs: T) {
*self = *self + rhs.into();
}
}
}
};
}
#[macro_export]
macro_rules! ring_sum {
($type:ty $(, ($type_param:ty, $param_name:ty))?) => {
paste::paste! {
impl$(<$param_name: $type_param>)? Sum for $type$(<$param_name>)? {
#[inline]
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.reduce(|x, y| x + y).unwrap_or(Self::ZERO)
}
}
}
};
}
#[macro_export]
macro_rules! impl_sub_assign {
($type:ty $(, ($type_param:ty, $param_name:ty))?) => {
paste::paste! {
impl<$($param_name: $type_param,)? T: Into<Self>> SubAssign<T> for $type$(<$param_name>)? {
#[inline]
fn sub_assign(&mut self, rhs: T) {
*self = *self - rhs.into();
}
}
}
};
}
#[macro_export]
macro_rules! impl_mul_methods {
($type:ty $(, ($type_param:ty, $param_name:ty))?) => {
paste::paste! {
impl<$($param_name: $type_param,)? T: Into<Self>> MulAssign<T> for $type$(<$param_name>)? {
#[inline]
fn mul_assign(&mut self, rhs: T) {
*self = *self * rhs.into();
}
}
impl$(<$param_name: $type_param>)? Product for $type$(<$param_name>)? {
#[inline]
fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.reduce(|x, y| x * y).unwrap_or(Self::ONE)
}
}
}
};
}
#[macro_export]
macro_rules! impl_add_base_field {
($alg_type:ty, $field_type:ty $(, ($type_param:ty, $param_name:ty))?) => {
paste::paste! {
impl$(<$param_name: $type_param>)? Add<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
type Output = Self;
#[inline]
fn add(self, rhs: $field_type$(<$param_name>)?) -> Self {
self + Self::from(rhs)
}
}
impl$(<$param_name: $type_param>)? Add<$alg_type$(<$param_name>)?> for $field_type$(<$param_name>)? {
type Output = $alg_type$(<$param_name>)?;
#[inline]
fn add(self, rhs: $alg_type$(<$param_name>)?) -> Self::Output {
$alg_type::from(self) + rhs
}
}
}
};
}
#[macro_export]
macro_rules! impl_sub_base_field {
($alg_type:ty, $field_type:ty $(, ($type_param:ty, $param_name:ty))?) => {
paste::paste! {
impl$(<$param_name: $type_param>)? Sub<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
type Output = Self;
#[inline]
fn sub(self, rhs: $field_type$(<$param_name>)?) -> Self {
self - Self::from(rhs)
}
}
impl$(<$param_name: $type_param>)? Sub<$alg_type$(<$param_name>)?> for $field_type$(<$param_name>)? {
type Output = $alg_type$(<$param_name>)?;
#[inline]
fn sub(self, rhs: $alg_type$(<$param_name>)?) -> Self::Output {
$alg_type::from(self) - rhs
}
}
}
};
}
#[macro_export]
macro_rules! impl_mul_base_field {
($alg_type:ty, $field_type:ty $(, ($type_param:ty, $param_name:ty))?) => {
paste::paste! {
impl$(<$param_name: $type_param>)? Mul<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
type Output = Self;
#[inline]
fn mul(self, rhs: $field_type$(<$param_name>)?) -> Self {
self * Self::from(rhs)
}
}
impl$(<$param_name: $type_param>)? Mul<$alg_type$(<$param_name>)?> for $field_type$(<$param_name>)? {
type Output = $alg_type$(<$param_name>)?;
#[inline]
fn mul(self, rhs: $alg_type$(<$param_name>)?) -> Self::Output {
$alg_type::from(self) * rhs
}
}
}
};
}
#[macro_export]
macro_rules! impl_div_methods {
($alg_type:ty, $field_type:ty $(, ($type_param:ty, $param_name:ty))?) => {
paste::paste! {
impl$(<$param_name: $type_param>)? Div<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
type Output = Self;
#[inline]
#[allow(clippy::suspicious_arithmetic_impl)]
fn div(self, rhs: $field_type$(<$param_name>)?) -> Self {
self * Self::from(rhs.inverse())
}
}
impl$(<$param_name: $type_param>)? DivAssign<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
#[inline]
#[allow(clippy::suspicious_op_assign_impl)]
fn div_assign(&mut self, rhs: $field_type$(<$param_name>)?) {
*self *= Self::from(rhs.inverse());
}
}
}
};
}
#[macro_export]
macro_rules! impl_sum_prod_base_field {
($alg_type:ty, $field_type:ty $(, ($type_param:ty, $param_name:ty))?) => {
paste::paste! {
impl$(<$param_name: $type_param>)? Sum<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
#[inline]
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = $field_type$(<$param_name>)?>,
{
iter.sum::<$field_type$(<$param_name>)?>().into()
}
}
impl$(<$param_name: $type_param>)? Product<$field_type$(<$param_name>)?> for $alg_type$(<$param_name>)? {
#[inline]
fn product<I>(iter: I) -> Self
where
I: Iterator<Item = $field_type$(<$param_name>)?>,
{
iter.product::<$field_type$(<$param_name>)?>().into()
}
}
}
};
}
#[macro_export]
macro_rules! impl_rng {
($type:ty $(, ($type_param:ty, $param_name:ty))?) => {
paste::paste! {
impl$(<$param_name: $type_param>)? Distribution<$type$(<$param_name>)?> for StandardUniform {
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $type$(<$param_name>)? {
$type(rng.random())
}
}
}
};
}
#[macro_export]
macro_rules! impl_packed_value {
($alg_type:ty, $field_type:ty, $width:expr $(, ($type_param:ty, $param_name:ty))?) => {
paste::paste! {
unsafe impl$(<$param_name: $type_param>)? PackedValue for $alg_type$(<$param_name>)? {
type Value = $field_type$(<$param_name>)?;
const WIDTH: usize = $width;
#[inline]
fn from_slice(slice: &[Self::Value]) -> &Self {
assert_eq!(slice.len(), Self::WIDTH);
unsafe { &*slice.as_ptr().cast() }
}
#[inline]
fn from_slice_mut(slice: &mut [Self::Value]) -> &mut Self {
assert_eq!(slice.len(), Self::WIDTH);
unsafe { &mut *slice.as_mut_ptr().cast() }
}
#[inline]
fn as_slice(&self) -> &[Self::Value] {
&self.0
}
#[inline]
fn as_slice_mut(&mut self) -> &mut [Self::Value] {
&mut self.0
}
#[inline]
fn from_fn<F: FnMut(usize) -> Self::Value>(f: F) -> Self {
Self(core::array::from_fn(f))
}
}
}
};
}
pub use impl_add_assign;
pub use impl_add_base_field;
pub use impl_div_methods;
pub use impl_mul_base_field;
pub use impl_mul_methods;
pub use impl_packed_value;
pub use impl_rng;
pub use impl_sub_assign;
pub use impl_sub_base_field;
pub use impl_sum_prod_base_field;
pub use ring_sum;