use crate::numeric::identity::{One, Zero};
use std::ops::{
Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
};
pub trait Num: PartialEq + Zero + One + NumOps {}
pub trait NumOps<Rhs = Self, Output = Self>:
Add<Rhs, Output = Output>
+ Sub<Rhs, Output = Output>
+ Mul<Rhs, Output = Output>
+ Div<Rhs, Output = Output>
+ Rem<Rhs, Output = Output>
{
}
pub trait NumAssignOps<Rhs = Self>:
AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
{
}
pub trait NumAssign: Num + NumAssignOps {}
pub trait NumRef: Num + for<'a> NumOps<&'a Self> {}
pub trait RefNum<Base>: NumOps<Base, Base> + for<'a> NumOps<&'a Base, Base> {}
impl<T> Num for T where T: PartialEq + Zero + One + NumOps {}
impl<T, Rhs, Output> NumOps<Rhs, Output> for T where
T: Add<Rhs, Output = Output>
+ Sub<Rhs, Output = Output>
+ Mul<Rhs, Output = Output>
+ Div<Rhs, Output = Output>
+ Rem<Rhs, Output = Output>
{
}
impl<T, Rhs> NumAssignOps<Rhs> for T where
T: AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
{
}
impl<T> NumAssign for T where T: Num + NumAssignOps {}
impl<T> NumRef for T where T: Num + for<'r> NumOps<&'r T> {}
impl<T, Base> RefNum<Base> for T where T: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}