macro_rules! impl_binop_with_macro {
(impl $trait:ident, $method:ident, $impl:ident) => {
crate::helper_macros::impl_binop_with_macro!(impl $trait for crate::rbig::RBig, $method, $impl);
};
(impl $trait:ident for $t:ty, $method:ident, $impl:ident) => {
crate::helper_macros::impl_binop_with_macro!(impl $trait for $t, $method -> $t, $impl);
};
(impl $trait:ident, $method:ident -> $omethod:ty, $impl:ident) => {
crate::helper_macros::impl_binop_with_macro!(impl $trait for crate::rbig::RBig, $method -> $omethod, $impl);
};
(impl $trait:ident for $t:ty, $method:ident -> $omethod:ty, $impl:ident) => {
impl $trait for $t {
type Output = $omethod;
fn $method(self, rhs: $t) -> $omethod {
let (a, b) = self.into_parts();
let (c, d) = rhs.into_parts();
let (ra, rb, rc, rd) = (&a, &b, &c, &d);
$impl!(a, b, c, d, ra, rb, rc, rd, $method)
}
}
impl<'r> $trait<&'r $t> for $t {
type Output = $omethod;
fn $method(self, rhs: &$t) -> $omethod {
let (a, b) = self.into_parts();
let (c, d) = (rhs.numerator(), rhs.denominator());
let (ra, rb, rc, rd) = (&a, &b, c, d);
$impl!(a, b, c, d, ra, rb, rc, rd, $method)
}
}
impl<'l> $trait<$t> for &'l $t {
type Output = $omethod;
fn $method(self, rhs: $t) -> $omethod {
let (a, b) = (self.numerator(), self.denominator());
let (c, d) = rhs.into_parts();
let (ra, rb, rc, rd) = (a, b, &c, &d);
$impl!(a, b, c, d, ra, rb, rc, rd, $method)
}
}
impl<'l, 'r> $trait<&'r $t> for &'l $t {
type Output = $omethod;
fn $method(self, rhs: &$t) -> $omethod {
let (a, b) = (self.numerator(), self.denominator());
let (c, d) = (rhs.numerator(), rhs.denominator());
let (ra, rb, rc, rd) = (a, b, c, d);
$impl!(a, b, c, d, ra, rb, rc, rd, $method)
}
}
};
(impl $trait:ident for $t:ty, $method:ident, $o1:ident = $ty_o1:ty, $o2:ident = $ty_o2:ty, $impl:ident) => {
impl $trait for $t {
type $o1 = $ty_o1;
type $o2 = $ty_o2;
fn $method(self, rhs: $t) -> ($ty_o1, $ty_o2) {
let (a, b) = self.into_parts();
let (c, d) = rhs.into_parts();
let (ra, rb, rc, rd) = (&a, &b, &c, &d);
$impl!(a, b, c, d, ra, rb, rc, rd, $method)
}
}
impl<'r> $trait<&'r $t> for $t {
type $o1 = $ty_o1;
type $o2 = $ty_o2;
fn $method(self, rhs: &$t) -> ($ty_o1, $ty_o2) {
let (a, b) = self.into_parts();
let (c, d) = (rhs.numerator(), rhs.denominator());
let (ra, rb, rc, rd) = (&a, &b, c, d);
$impl!(a, b, c, d, ra, rb, rc, rd, $method)
}
}
impl<'l> $trait<$t> for &'l $t {
type $o1 = $ty_o1;
type $o2 = $ty_o2;
fn $method(self, rhs: $t) -> ($ty_o1, $ty_o2) {
let (a, b) = (self.numerator(), self.denominator());
let (c, d) = rhs.into_parts();
let (ra, rb, rc, rd) = (a, b, &c, &d);
$impl!(a, b, c, d, ra, rb, rc, rd, $method)
}
}
impl<'l, 'r> $trait<&'r $t> for &'l $t {
type $o1 = $ty_o1;
type $o2 = $ty_o2;
fn $method(self, rhs: &$t) -> ($ty_o1, $ty_o2) {
let (a, b) = (self.numerator(), self.denominator());
let (c, d) = (rhs.numerator(), rhs.denominator());
let (ra, rb, rc, rd) = (a, b, c, d);
$impl!(a, b, c, d, ra, rb, rc, rd, $method)
}
}
};
}
macro_rules! impl_binop_with_int {
(impl $trait:ident<$int:ty>, $method:ident, $impl:ident) => {
crate::helper_macros::impl_binop_with_int!(impl $trait<$int>, $method, crate::rbig::RBig, $impl);
};
(impl $trait:ident<$int:ty>, $method:ident, $t:ty, $impl:ident) => {
impl $trait<$int> for $t {
type Output = $t;
fn $method(self, rhs: $int) -> $t {
let (a, b) = self.into_parts();
let (ra, rb, ri) = (&a, &b, &rhs);
$impl!(a, b, rhs, ra, rb, ri, $method)
}
}
impl<'r> $trait<&'r $int> for $t {
type Output = $t;
fn $method(self, rhs: &$int) -> $t {
let (a, b) = self.into_parts();
let (ra, rb, ri) = (&a, &b, rhs);
$impl!(a, b, rhs, ra, rb, ri, $method)
}
}
impl<'l> $trait<$int> for &'l $t {
type Output = $t;
fn $method(self, rhs: $int) -> $t {
let (ra, rb, ri) = (self.numerator(), self.denominator(), &rhs);
let (a, b) = (ra.clone(), rb.clone());
$impl!(a, b, rhs, ra, rb, ri, $method)
}
}
impl<'l, 'r> $trait<&'r $int> for &'l $t {
type Output = $t;
fn $method(self, rhs: &$int) -> $t {
let (ra, rb, ri) = (self.numerator(), self.denominator(), rhs);
let (a, b) = (ra.clone(), rb.clone());
$impl!(a, b, rhs, ra, rb, ri, $method)
}
}
};
(impl $trait:ident for $int:ty, $method:ident, $impl:ident) => {
crate::helper_macros::impl_binop_with_int!(impl $trait for $int, $method, crate::rbig::RBig, $impl);
};
(impl $trait:ident for $int:ty, $method:ident, $t:ty, $impl:ident) => {
impl $trait<$t> for $int {
type Output = $t;
fn $method(self, rhs: $t) -> $t {
let (a, b) = rhs.into_parts();
let (ra, rb, ri) = (&a, &b, &self);
$impl!(a, b, self, ra, rb, ri, $method)
}
}
impl<'r> $trait<&'r $t> for $int {
type Output = $t;
fn $method(self, rhs: &$t) -> $t {
let (ra, rb, ri) = (rhs.numerator(), rhs.denominator(), &self);
let (a, b) = (ra.clone(), rb.clone());
$impl!(a, b, self, ra, rb, ri, $method)
}
}
impl<'l> $trait<$t> for &'l $int {
type Output = $t;
fn $method(self, rhs: $t) -> $t {
let (a, b) = rhs.into_parts();
let (ra, rb, ri) = (&a, &b, self);
$impl!(a, b, self, ra, rb, ri, $method)
}
}
impl<'l, 'r> $trait<&'r $t> for &'l $int {
type Output = $t;
fn $method(self, rhs: &$t) -> $t {
let (ra, rb, ri) = (rhs.numerator(), rhs.denominator(), self);
let (a, b) = (ra.clone(), rb.clone());
$impl!(a, b, self, ra, rb, ri, $method)
}
}
}
}
macro_rules! impl_binop_assign_by_taking {
(impl $trait:ident for $t1:ty, $methodassign:ident, $method:ident) => {
crate::helper_macros::impl_binop_assign_by_taking!(impl $trait<$t1> for $t1, $methodassign, $method);
};
(impl $trait:ident<$t2:ty> for $t1:ty, $methodassign:ident, $method:ident) => {
impl $trait<$t2> for $t1 {
#[inline]
fn $methodassign(&mut self, rhs: $t2) {
*self = core::mem::take(self).$method(rhs);
}
}
impl $trait<&$t2> for $t1 {
#[inline]
fn $methodassign(&mut self, rhs: &$t2) {
*self = core::mem::take(self).$method(rhs);
}
}
};
}
pub(crate) use impl_binop_assign_by_taking;
pub(crate) use impl_binop_with_int;
pub(crate) use impl_binop_with_macro;