1use super::PrimitiveTraits;
2
3pub trait TupleTy<T> {
4    const __DATA: T;
5    const VALUE: T = Self::__DATA;
6}
7
8impl TupleTy<()> for () {
9    const __DATA: () = ();
10}
11
12macro_rules! TupleTyByNum {
13    ($($generics:ident),*) => {
14        impl<T: PrimitiveTraits<DATATYPE = ($($generics),*, )>, $($generics),*> TupleTy<($($generics),*, )> for T {
15            const __DATA: ($($generics),*, ) = <T as PrimitiveTraits>::__DATA;
16        }
17
18        impl<$($generics: PrimitiveTraits),*> PrimitiveTraits for ($($generics),*, ) {
19            type DATATYPE = ($($generics::DATATYPE),*, );
20            const __DATA: Self::DATATYPE = ($($generics::__DATA),*, );
21        }
22    };
23}
24
25TupleTyByNum!(A);
26TupleTyByNum!(A, B);
27TupleTyByNum!(A, B, C);
28TupleTyByNum!(A, B, C, D);
29TupleTyByNum!(A, B, C, D, E);
30TupleTyByNum!(A, B, C, D, E, F);
31TupleTyByNum!(A, B, C, D, E, F, G);
32TupleTyByNum!(A, B, C, D, E, F, G, H);
33TupleTyByNum!(A, B, C, D, E, F, G, H, I);
34TupleTyByNum!(A, B, C, D, E, F, G, H, I, J);
35
36#[cfg(test)]
37mod tests {
38    use crate::primitive::{F32, F64, U32};
39    use core::mem;
40
41    use super::TupleTy;
42
43    pub const fn tester_inner0<T: TupleTy<()>>() {
44        T::VALUE
45    }
46
47    pub const fn tester_inner1<T: TupleTy<(f32,)>>() -> (f32,) {
48        T::VALUE
49    }
50
51    pub const fn tester_inner2<T: TupleTy<(f32, f64)>>() -> (f32, f64) {
52        T::VALUE
53    }
54
55    pub const fn tester_inner3<T: TupleTy<(f32, (f64, u32))>>() -> (f32, (f64, u32)) {
56        T::VALUE
57    }
58
59    pub const fn tester_inner4<T: TupleTy<(f32, f32, f32, f32)>>() -> (f32, f32, f32, f32) {
60        T::VALUE
61    }
62
63    #[test]
64    fn call_tester() {
65        let s: (F32!(0.4), F64!(0.3)) = unsafe { mem::zeroed() };
66        assert_eq!(core::mem::size_of_val(&s), 0);
67        assert_eq!(tester_inner0::<()>(), ());
68        assert_eq!(tester_inner1::<(F32!(0.4),)>(), (0.4,));
69        assert_eq!(tester_inner2::<(F32!(0.4), F64!(0.3))>(), (0.4, 0.3));
70        assert_eq!(
71            tester_inner3::<(F32!(0.4), (F64!(0.3), U32!(5)))>(),
72            (0.4, (0.3, 5))
73        );
74        assert_eq!(
75            tester_inner4::<(F32!(0.4), F32!(0.3), F32!(0.2), F32!(0.1))>(),
76            (0.4, 0.3, 0.2, 0.1)
77        );
78    }
79}