#![allow(unused, non_camel_case_types)]
macro_rules! upcasted_op {
(
add_err($lhs:expr, $rhs:expr) $ba:ty => $up:ty) => {
if $crate::cif!(diff($ba, $up)) {
#[cfg(any(feature = "safe_num", not(feature = "unsafe_hint")))]
{
$lhs + $rhs
}
#[cfg(all(not(feature = "safe_num"), feature = "unsafe_hint"))]
unsafe {
$lhs.unchecked_add($rhs)
}
} else {
if let Some(sum) = $lhs.checked_add($rhs) {
sum
} else {
return Err($crate::NumError::Overflow(None));
}
}
};
(mul_err($lhs:expr, $rhs:expr) $ba:ty => $up:ty) => {
if $crate::cif!(diff($ba, $up)) {
#[cfg(any(feature = "safe_num", not(feature = "unsafe_hint")))]
{
$lhs * $rhs
}
#[cfg(all(not(feature = "safe_num"), feature = "unsafe_hint"))]
unsafe {
$lhs.unchecked_mul($rhs)
}
} else {
if let Some(product) = $lhs.checked_mul($rhs) {
product
} else {
return Err($crate::NumError::Overflow(None));
}
}
};
(
reduced_add_err($lhs:expr, $rhs:expr) % $modulus:expr; $ba:ty => $up:ty) => {
if $crate::cif!(diff($ba, $up)) {
#[cfg(any(feature = "safe_num", not(feature = "unsafe_hint")))]
{
$lhs + $rhs
}
#[cfg(all(not(feature = "safe_num"), feature = "unsafe_hint"))]
unsafe {
$lhs.unchecked_add($rhs)
}
} else {
if let Some(sum) = ($lhs % $modulus).checked_add($rhs % $modulus) {
sum
} else {
return Err($crate::NumError::Overflow(None));
}
}
};
(
reduced_add($lhs:expr, $rhs:expr) % $modulus:expr; $ba:ty => $up:ty) => {
if $crate::cif!(diff($ba, $up)) {
#[cfg(any(feature = "safe_num", not(feature = "unsafe_hint")))]
{
$lhs + $rhs
}
#[cfg(all(not(feature = "safe_num"), feature = "unsafe_hint"))]
unsafe {
$lhs.unchecked_add($rhs)
}
} else {
($lhs % $modulus) + ($rhs % $modulus)
}
};
(reduced_mul_err($lhs:expr, $rhs:expr) % $modulus:expr; $ba:ty => $up:ty) => {
if $crate::cif!(diff($ba, $up)) {
#[cfg(any(feature = "safe_num", not(feature = "unsafe_hint")))]
{
$lhs * $rhs
}
#[cfg(all(not(feature = "safe_num"), feature = "unsafe_hint"))]
unsafe {
$lhs.unchecked_mul($rhs)
}
} else {
if let Some(product) = ($lhs % $modulus).checked_mul($rhs % $modulus) {
product
} else {
return Err($crate::NumError::Overflow(None));
}
}
};
(reduced_mul($lhs:expr, $rhs:expr) % $modulus:expr; $ba:ty => $up:ty) => {
if $crate::cif!(diff($ba, $up)) {
#[cfg(any(feature = "safe_num", not(feature = "unsafe_hint")))]
{
$lhs * $rhs
}
#[cfg(all(not(feature = "safe_num"), feature = "unsafe_hint"))]
unsafe {
$lhs.unchecked_mul($rhs)
}
} else {
($lhs % $modulus) + ($rhs % $modulus)
}
};
}
pub(crate) use upcasted_op;
macro_rules! impl_ops {
($W:ident: $($T:ty : $cap:literal ),+) => { $(
$crate::num::impl_ops![@common $W($T:$cap)];
$crate::num::impl_ops![@neg $W($T:$cap)];
)+ };
($W:ident: (no_neg) $($T:ty : $cap:literal),+) => { $(
$crate::num::impl_ops![@common $W($T:$cap)];
)+ };
(@common $W:ident($T:ty : $cap:literal)) => {
$crate::num::impl_ops![@op $W($T:$cap), Add, add];
$crate::num::impl_ops![@op $W($T:$cap), Sub, sub];
$crate::num::impl_ops![@op $W($T:$cap), Mul, mul];
$crate::num::impl_ops![@op $W($T:$cap), Div, div];
$crate::num::impl_ops![@op $W($T:$cap), Rem, rem];
$crate::num::impl_ops![@op_assign $W($T:$cap), AddAssign, add_assign];
$crate::num::impl_ops![@op_assign $W($T:$cap), SubAssign, sub_assign];
$crate::num::impl_ops![@op_assign $W($T:$cap), MulAssign, mul_assign];
$crate::num::impl_ops![@op_assign $W($T:$cap), DivAssign, div_assign];
$crate::num::impl_ops![@op_assign $W($T:$cap), RemAssign, rem_assign];
};
(@neg $W:ident($T:ty : $cap:literal)) => {
#[cfg(feature = $cap )]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
impl core::ops::Neg for $W<$T> {
type Output = $W<$T>;
fn neg(self) -> $W<$T> { $W(self.0.neg()) }
}
};
(
@op $W:ident($T:ty : $cap:literal), $trait:ident, $fn:ident) => {
#[cfg(feature = $cap )]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
impl core::ops::$trait for $W<$T> {
$crate::num::impl_ops![@op_body $W($T), $fn, $W<$T>, 0];
}
#[cfg(feature = $cap )]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
impl<'s> core::ops::$trait<$W<$T>> for &'s $W<$T> {
$crate::num::impl_ops![@op_body $W($T), $fn, $W<$T>, 0];
}
#[cfg(feature = $cap )]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
impl<'o> core::ops::$trait<&'o $W<$T>> for $W<$T> {
$crate::num::impl_ops![@op_body $W($T), $fn, &'o $W<$T>, 0];
}
#[cfg(feature = $cap )]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
impl<'s, 'o> core::ops::$trait<&'o $W<$T>> for &'s $W<$T> {
$crate::num::impl_ops![@op_body $W($T), $fn, &'o $W<$T>, 0];
}
#[cfg(feature = $cap )]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
impl core::ops::$trait<$T> for $W<$T> {
$crate::num::impl_ops![@op_body $W($T), $fn, $T];
}
#[cfg(feature = $cap )]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
impl<'s> core::ops::$trait<$T> for &'s $W<$T> {
$crate::num::impl_ops![@op_body $W($T), $fn, $T];
}
#[cfg(feature = $cap )]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
impl<'o> core::ops::$trait<&'o $T> for $W<$T> {
$crate::num::impl_ops![@op_body $W($T), $fn, &'o $T];
}
#[cfg(feature = $cap )]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
impl<'s, 'o> core::ops::$trait<&'o $T> for &'s $W<$T> {
$crate::num::impl_ops![@op_body $W($T), $fn, &'o $T];
}
};
(@op_body $W:ident($T:ty), $fn:ident, $other:ty $(, $other_field:tt)?) => {
type Output = $W<$T>;
fn $fn(self, other: $other) -> $W<$T> { $W(self.0.$fn(other$(. $other_field)?)) }
};
(@op_assign $W:ident($T:ty : $cap:literal), $trait:ident, $fn:ident) => { $crate::paste! {
#[cfg(feature = $cap )]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
impl core::ops::$trait for $W<$T> {
fn $fn(&mut self, other: $W<$T>) { self.0.$fn(other.0); }
}
#[cfg(feature = $cap )]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
impl<'o> core::ops::$trait<&'o $W<$T>> for $W<$T> {
fn $fn(&mut self, other: &'o $W<$T>) { self.0.$fn(other.0); }
}
#[cfg(feature = $cap )]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
impl core::ops::$trait<$T> for $W<$T> {
fn $fn(&mut self, other: $T) { self.0.$fn(other); }
}
#[cfg(feature = $cap )]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
impl<'o> core::ops::$trait<&'o $T> for $W<$T> {
fn $fn(&mut self, other: &'o $T) { self.0.$fn(other); }
}
}};
}
pub(crate) use impl_ops;