const_struct 0.6.4

macro that allows const structures to be passed as const generics
Documentation
use super::PrimitiveTraits;

pub trait TupleTy<T> {
    const __DATA: T;
    const VALUE: T = Self::__DATA;
}

impl TupleTy<()> for () {
    const __DATA: () = ();
}

macro_rules! TupleTyByNum {
    ($($generics:ident),*) => {
        impl<T: PrimitiveTraits<DATATYPE = ($($generics),*, )>, $($generics),*> TupleTy<($($generics),*, )> for T {
            const __DATA: ($($generics),*, ) = <T as PrimitiveTraits>::__DATA;
        }

        impl<$($generics: PrimitiveTraits),*> PrimitiveTraits for ($($generics),*, ) {
            type DATATYPE = ($($generics::DATATYPE),*, );
            const __DATA: Self::DATATYPE = ($($generics::__DATA),*, );
        }
    };
}

TupleTyByNum!(A);
TupleTyByNum!(A, B);
TupleTyByNum!(A, B, C);
TupleTyByNum!(A, B, C, D);
TupleTyByNum!(A, B, C, D, E);
TupleTyByNum!(A, B, C, D, E, F);
TupleTyByNum!(A, B, C, D, E, F, G);
TupleTyByNum!(A, B, C, D, E, F, G, H);
TupleTyByNum!(A, B, C, D, E, F, G, H, I);
TupleTyByNum!(A, B, C, D, E, F, G, H, I, J);

#[cfg(test)]
mod tests {
    use crate::primitive::{F32, F64, U32};
    use core::mem;

    use super::TupleTy;

    pub const fn tester_inner0<T: TupleTy<()>>() {
        T::VALUE
    }

    pub const fn tester_inner1<T: TupleTy<(f32,)>>() -> (f32,) {
        T::VALUE
    }

    pub const fn tester_inner2<T: TupleTy<(f32, f64)>>() -> (f32, f64) {
        T::VALUE
    }

    pub const fn tester_inner3<T: TupleTy<(f32, (f64, u32))>>() -> (f32, (f64, u32)) {
        T::VALUE
    }

    pub const fn tester_inner4<T: TupleTy<(f32, f32, f32, f32)>>() -> (f32, f32, f32, f32) {
        T::VALUE
    }

    #[test]
    fn call_tester() {
        let s: (F32!(0.4), F64!(0.3)) = unsafe { mem::zeroed() };
        assert_eq!(core::mem::size_of_val(&s), 0);
        assert_eq!(tester_inner0::<()>(), ());
        assert_eq!(tester_inner1::<(F32!(0.4),)>(), (0.4,));
        assert_eq!(tester_inner2::<(F32!(0.4), F64!(0.3))>(), (0.4, 0.3));
        assert_eq!(
            tester_inner3::<(F32!(0.4), (F64!(0.3), U32!(5)))>(),
            (0.4, (0.3, 5))
        );
        assert_eq!(
            tester_inner4::<(F32!(0.4), F32!(0.3), F32!(0.2), F32!(0.1))>(),
            (0.4, 0.3, 0.2, 0.1)
        );
    }
}