#[macro_export]
macro_rules! commutative_binop {
(
$( [ $($generic:tt)* ] )?
impl Add for $lhs:ty, $rhs:ty
$( where $($bound:tt)* )?
) => {
commutative_binop! {
$( [ $($generic)* ] )?
impl Add, add for $lhs, $rhs
$( where $($bound)* )?
}
};
(
$( [ $($generic:tt)* ] )?
impl Mul for $lhs:ty, $rhs:ty
$( where $($bound:tt)* )?
) => {
commutative_binop! {
$( [ $($generic)* ] )?
impl Mul, mul for $lhs, $rhs
$( where $($bound)* )?
}
};
(
$( [ $($generic:tt)* ] )?
impl $impl:ident, $meth:ident for $lhs:ty, $rhs:ty
$( where $($bound:tt)* )?
) => {
impl$(<$($generic)*>)? $impl<$lhs> for $rhs
$(where
$($bound)*)?
{
type Output = <$lhs as $impl<$rhs>>::Output;
fn $meth(self, rhs: $lhs) -> Self::Output {
<$lhs>::$meth(rhs, self)
}
}
};
}
#[macro_export]
macro_rules! forward_ref_binop {
(
$( [ $($generic:tt)* ] )?
impl Add for $lhs:ty $(, $rhs:ty )?
$( where $($bound:tt)* )?
) => {
forward_ref_binop! {
$( [ $($generic)* ] )?
impl Add, add for $lhs $(, $rhs )?
$( where $($bound)* )?
}
};
(
$( [ $($generic:tt)* ] )?
impl Sub for $lhs:ty $(, $rhs:ty )?
$( where $($bound:tt)* )?
) => {
forward_ref_binop! {
$( [ $($generic)* ] )?
impl Sub, sub for $lhs $(, $rhs )?
$( where $($bound)* )?
}
};
(
$( [ $($generic:tt)* ] )?
impl Mul for $lhs:ty $(, $rhs:ty )?
$( where $($bound:tt)* )?
) => {
forward_ref_binop! {
$( [ $($generic)* ] )?
impl Mul, mul for $lhs $(, $rhs )?
$( where $($bound)* )?
}
};
(
$( [ $($generic:tt)* ] )?
impl Div for $lhs:ty $(, $rhs:ty )?
$( where $($bound:tt)* )?
) => {
forward_ref_binop! {
$( [ $($generic)* ] )?
impl Div, div for $lhs $(, $rhs )?
$( where $($bound)* )?
}
};
(
$( [ $($generic:tt)* ] )?
impl $impl:ident, $meth:ident for $lhs:ty
$( where $($bound:tt)* )?
) => {
forward_ref_binop! {
$( [ $($generic)* ] )?
impl $impl, $meth for $lhs, $lhs
$( where $($bound)* )?
}
};
(
$( [ $($generic:tt)* ] )?
impl $impl:ident, $meth:ident for $lhs:ty, $rhs:ty
$( where $($bound:tt)* )?
) => {
impl$(<$($generic)*>)? $impl<$rhs> for &$lhs
$(where
$($bound)*)?
{
type Output = <$lhs as $impl<$rhs>>::Output;
fn $meth(self, rhs: $rhs) -> Self::Output {
<$lhs>::$meth(*self, rhs)
}
}
impl$(<$($generic)*>)? $impl<&$rhs> for $lhs
$(where
$($bound)*)?
{
type Output = <$lhs as $impl<$rhs>>::Output;
fn $meth(self, rhs: &$rhs) -> Self::Output {
<$lhs>::$meth(self, *rhs)
}
}
impl$(<$($generic)*>)? $impl<&$rhs> for &$lhs
$(where
$($bound)*)?
{
type Output = <$lhs as $impl<$rhs>>::Output;
fn $meth(self, rhs: &$rhs) -> Self::Output {
<$lhs>::$meth(*self, *rhs)
}
}
};
}
#[macro_export]
macro_rules! forward_ref_commutative_binop {
(
$( [ $($generic:tt)* ] )?
impl Add for $lhs:ty, $rhs:ty
$( where $($bound:tt)* )?
) => {
forward_ref_commutative_binop! {
$( [ $($generic)* ] )?
impl Add, add for $lhs, $rhs
$( where $($bound)* )?
}
};
(
$( [ $($generic:tt)* ] )?
impl Mul for $lhs:ty, $rhs:ty
$( where $($bound:tt)* )?
) => {
forward_ref_commutative_binop! {
$( [ $($generic)* ] )?
impl Mul, mul for $lhs, $rhs
$( where $($bound)* )?
}
};
(
$( [ $($generic:tt)* ] )?
impl $impl:ident, $meth:ident for $lhs:ty, $rhs:ty
$( where $($bound:tt)* )?
) => {
forward_ref_generic::forward_ref_binop! {
$( [ $($generic)* ] )?
impl $impl, $meth for $lhs, $rhs
$( where $($bound)* )?
}
forward_ref_generic::forward_ref_binop! {
$( [ $($generic)* ] )?
impl $impl, $meth for $rhs, $lhs
$( where $($bound)* )?
}
};
}