generic_array_storage/conv.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
use generic_array::{ArrayLength, IntoArrayLength};
use nalgebra::{Const, DimName, DimNameAdd, DimNameMul, DimNameProd, DimNameSum, U0, U1, U2};
use typenum::{UInt, UTerm, B0, B1};
/// Convenience trait, used to define type **conv**ersions
///
/// Also, this is the only bound to [`GenericMatrix`](super::GenericMatrix) type alias, meaning that all of the following are valid [`GenericMatrix`](super::GenericMatrix)es:
/// ```rust
/// # use generic_array_storage::GenericMatrix;
/// type NalgebraMatrix = GenericMatrix<i32, nalgebra::U3, nalgebra::U4>;
/// type TypenumMatrix = GenericMatrix<i32, typenum::U3, typenum::U4>;
/// type TypenumConstMatrix = GenericMatrix<i32, typenum::Const<3>, typenum::Const<3>>;
/// // (nalgebra::Const are actually aliased by nalgebra::{U1, U2, ...})
/// ```
pub trait Conv {
/// [`typenum`]-faced type (unsigned int)
type TNum: ArrayLength;
/// [`nalgebra`]-faced type (matrix dimension)
type Nalg: DimName;
/// Constructor method used in [`nalgebra`] implementations
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
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
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;
}