use core::ops::{Neg, Div};
use super::basic::{Z0, B0, B1, P1, N1};
use crate::constant::{Integer, NonZero};
use crate::variable::{Var, Numeric};
impl<I: NonZero> Div<I> for Z0 {
type Output = Self;
#[inline(always)]
fn div(self, _rhs: I) -> Self::Output {
self }
}
impl Div<P1> for P1 {
type Output = Self;
#[inline(always)]
fn div(self, _rhs: Self) -> Self::Output {
P1
}
}
impl Div<N1> for P1 {
type Output = N1;
#[inline(always)]
fn div(self, _rhs: N1) -> Self::Output {
N1
}
}
impl<H:NonZero> Div<B0<H>> for P1 {
type Output = f64;
fn div(self, _: B0<H>) -> f64 {
f64::from(1) / f64::from(B0::<H>::to_i32())
}
}
impl<H:NonZero> Div<B1<H>> for P1 {
type Output = f64;
fn div(self, _: B1<H>) -> f64 {
f64::from(1) / f64::from(B1::<H>::to_i32())
}
}
impl Div<P1> for N1 {
type Output = Self;
#[inline(always)]
fn div(self, _rhs: P1) -> Self::Output {
N1
}
}
impl Div<N1> for N1 {
type Output = P1;
#[inline(always)]
fn div(self, _rhs: N1) -> Self::Output {
P1
}
}
impl<H:NonZero> Div<B0<H>> for N1 {
type Output = f64;
fn div(self, _: B0<H>) -> f64 {
f64::from(-1) / f64::from(B0::<H>::to_i32())
}
}
impl<H:NonZero> Div<B1<H>> for N1 {
type Output = f64;
fn div(self, _: B1<H>) -> f64 {
f64::from(-1) / f64::from(B1::<H>::to_i32())
}
}
impl<H: NonZero> Div<P1> for B0<H> {
type Output = Self;
#[inline(always)]
fn div(self, _rhs: P1) -> Self::Output {
self
}
}
impl<H: NonZero> Div<N1> for B0<H>
where
B0<H>: Neg,
{
type Output = <B0<H> as Neg>::Output;
#[inline(always)]
fn div(self, _rhs: N1) -> Self::Output {
-self
}
}
impl<H1:NonZero, H2:NonZero> Div<B0<H2>> for B0<H1> {
type Output = f64;
fn div(self, _: B0<H2>) -> f64 {
f64::from(B0::<H1>::to_i32()) / f64::from(B0::<H2>::to_i32())
}
}
impl<H1:NonZero, H2:NonZero> Div<B1<H2>> for B0<H1> {
type Output = f64;
fn div(self, _: B1<H2>) -> f64 {
f64::from(B0::<H1>::to_i32()) / f64::from(B1::<H2>::to_i32())
}
}
impl<H: NonZero> Div<P1> for B1<H> {
type Output = Self;
#[inline(always)]
fn div(self, _rhs: P1) -> Self::Output {
self
}
}
impl<H: NonZero> Div<N1> for B1<H>
where
B1<H>: Neg,
{
type Output = <B1<H> as Neg>::Output;
#[inline(always)]
fn div(self, _rhs: N1) -> Self::Output {
-self
}
}
impl<H1:NonZero, H2:NonZero> Div<B0<H2>> for B1<H1> {
type Output = f64;
fn div(self, _: B0<H2>) -> f64 {
f64::from(B1::<H1>::to_i32()) / f64::from(B0::<H2>::to_i32())
}
}
impl<H1:NonZero, H2:NonZero> Div<B1<H2>> for B1<H1> {
type Output = f64;
fn div(self, _: B1<H2>) -> f64 {
f64::from(B1::<H1>::to_i32()) / f64::from(B1::<H2>::to_i32())
}
}
pub type Quot<A, B> = <A as Div<B>>::Output;
impl<T: Numeric + PartialEq> Div<Var<T>> for Z0 {
type Output = Self;
fn div(self, rhs: Var<T>) -> Self::Output {
assert!(rhs.0 != T::from(0), "division by zero");
self
}
}
impl<T: Numeric> Div<Var<T>> for P1 {
type Output = Var<T>;
#[inline(always)]
fn div(self, rhs: Var<T>) -> Self::Output {
Var(T::from(1) / rhs.0)
}
}
impl<T: Numeric> Div<Var<T>> for N1{
type Output = <Var<T> as Neg>::Output;
#[inline(always)]
fn div(self, rhs: Var<T>) -> Self::Output {
Var(T::from(-1) / rhs.0)
}
}
impl<H: NonZero, T:Numeric> Div<Var<T>> for B0<H>
where
B0<H>: Integer,
Var<T>: Div<Var<T>>,
{
type Output = Var<T>;
#[inline(always)]
fn div(self, rhs: Var<T>) -> Self::Output {
Var(T::from(B0::<H>::to_i32()) / rhs.0)
}
}
impl<H: NonZero, T:Numeric> Div<Var<T>> for B1<H>
where
B1<H>: Integer,
Var<T>: Div<Var<T>>,
{
type Output = Var<T>;
#[inline(always)]
fn div(self, rhs: Var<T>) -> Self::Output {
Var(T::from(B1::<H>::to_i32()) / rhs.0)
}
}