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;
}