use generic_array::{ArrayLength, IntoArrayLength};
use nalgebra::{Const, DimName, DimNameAdd, DimNameMul, DimNameProd, DimNameSum, U0, U1, U2};
use typenum::{B0, B1, UInt, UTerm};
pub trait Conv {
type TNum: ArrayLength;
type Nalg: DimName;
fn new_nalg() -> Self::Nalg {
Self::Nalg::name()
}
}
impl Conv for UTerm {
type Nalg = U0;
type TNum = Self;
}
impl<U: Conv> Conv for UInt<U, B1>
where
Self: ArrayLength,
U: ArrayLength,
UInt<U, B0>: Conv,
<UInt<U, B0> as Conv>::Nalg: DimNameAdd<U1>,
{
type TNum = Self;
type Nalg = DimNameSum<<UInt<U, B0> as Conv>::Nalg, U1>;
}
impl<U: Conv> Conv for UInt<U, B0>
where
Self: ArrayLength,
U: ArrayLength,
U::Nalg: DimNameMul<U2>,
{
type TNum = Self;
type Nalg = DimNameProd<U::Nalg, U2>;
}
type TNum<const N: usize> = typenum::Const<N>;
impl<const N: usize> Conv for TNum<N>
where
Self: IntoArrayLength,
{
type TNum = <Self as IntoArrayLength>::ArrayLength;
type Nalg = Const<N>;
}
impl<const N: usize> Conv for Const<N>
where
TNum<N>: IntoArrayLength,
{
type TNum = <TNum<N> as IntoArrayLength>::ArrayLength;
type Nalg = Self;
}