use crate::{
num_vals::{U0, U1},
op_types::SubExp,
val_types::{NumberVal, B, _0, _1},
NumExpr, NumRet,
};
use core::ops::Sub as StSub;
impl<L, R> NumExpr for SubExp<L, R>
where
L: NumExpr,
R: NumExpr,
L::Ret: StSub<R::Ret>,
SubOut<L::Ret, R::Ret>: NumExpr,
NumRet<SubOut<L::Ret, R::Ret>>: NumberVal,
{
type Ret = NumRet<SubOut<L::Ret, R::Ret>>;
}
type SubOut<L, R> = <L as StSub<R>>::Output;
impl StSub<U0> for U0 {
type Output = U0;
fn sub(self, _rhs: U0) -> Self::Output {
unimplemented!("type eval only")
}
}
impl StSub<U0> for U1 {
type Output = U1;
fn sub(self, _rhs: U0) -> Self::Output {
unimplemented!("type eval only")
}
}
impl StSub<U1> for U1 {
type Output = U0;
fn sub(self, _rhs: U1) -> Self::Output {
unimplemented!("type eval only")
}
}
impl<LBs, LB> StSub<U0> for B<LBs, LB> {
type Output = B<LBs, LB>;
fn sub(self, _rhs: U0) -> Self::Output {
unimplemented!("type eval only")
}
}
impl<Bs> StSub<_1> for B<Bs, _1> {
type Output = B<Bs, _0>;
fn sub(self, _rhs: U1) -> Self::Output {
unimplemented!("type eval only")
}
}
impl<Bs> StSub<_1> for B<Bs, _0>
where
Bs: StSub<_1>,
B<SubOut<Bs, _1>, _1>: NumExpr,
{
type Output = NumRet<B<SubOut<Bs, _1>, _1>>;
fn sub(self, _rhs: U1) -> Self::Output {
unimplemented!("type eval only")
}
}
impl<LB, RB> StSub<B<RB, _0>> for B<LB, _0>
where
LB: StSub<RB>,
B<SubOut<LB, RB>, _0>: NumExpr,
{
type Output = NumRet<B<SubOut<LB, RB>, _0>>;
fn sub(self, _rhs: B<RB, _0>) -> Self::Output {
unimplemented!("type eval only")
}
}
impl<LB, RB> StSub<B<RB, _1>> for B<LB, _0>
where
LB: StSub<RB>,
SubOut<LB, RB>: StSub<_1>,
B<SubOut<SubOut<LB, RB>, _1>, _1>: NumExpr,
{
type Output = NumRet<B<SubOut<SubOut<LB, RB>, _1>, _1>>;
fn sub(self, _rhs: B<RB, _1>) -> Self::Output {
unimplemented!("type eval only")
}
}
impl<LB, RB> StSub<B<RB, _0>> for B<LB, _1>
where
LB: StSub<RB>,
B<SubOut<LB, RB>, _1>: NumExpr,
{
type Output = NumRet<B<SubOut<LB, RB>, _1>>;
fn sub(self, _rhs: B<RB, _0>) -> Self::Output {
unimplemented!("type eval only")
}
}
impl<LB, RB> StSub<B<RB, _1>> for B<LB, _1>
where
LB: StSub<RB>,
B<SubOut<LB, RB>, _0>: NumExpr,
{
type Output = NumRet<B<SubOut<LB, RB>, _0>>;
fn sub(self, _rhs: B<RB, _1>) -> Self::Output {
unimplemented!("type eval only")
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::{
num_vals::{U0, U1, U2, U3},
test_res::*,
};
#[test]
#[allow(clippy::used_underscore_items)]
fn eval_sub() {
const _0_SUB_0: () = _b0::<SubExp<U0, U0>>();
const _1_SUB_0: () = _b1::<SubExp<U1, U0>>();
const _1_SUB_1: () = _b0::<SubExp<U1, U1>>();
const _2_SUB_1: () = _b1::<SubExp<U2, U1>>();
const _2_SUB_0: () = _b2::<SubExp<U2, U0>>();
const _3_SUB_1: () = _b2::<SubExp<U3, _1>>();
const _4_SUB_1: () = _b3::<SubExp<B<B<_1, _0>, _0>, _1>>();
const _2_SUB_2: () = _b0::<SubExp<U2, U2>>();
const _3_SUB_2: () = _b1::<SubExp<U3, U2>>();
const _3_SUB_3: () = _b0::<SubExp<U3, U3>>();
}
}