pub trait Tuple2CTuple { type CTuple; } // We place each tuple inside its own module so that it rustrover hints simply show it as C<...> macro_rules! define_tuple { ($struct_name:ident, $module_name:ident, $($T:ident),*) => { pub mod $module_name { #[repr(C)] pub struct $struct_name<$($T),*>($(pub $T),*); impl<$($T),*> super::Tuple2CTuple for ($($T,)*) { type CTuple = $struct_name<$($T,)*>; } } }; } // @formatter:off define_tuple!(C, t0 , ); define_tuple!(C, t1 , T0); define_tuple!(C, t2 , T0, T1); define_tuple!(C, t3 , T0, T1, T2); define_tuple!(C, t4 , T0, T1, T2, T3); define_tuple!(C, t5 , T0, T1, T2, T3, T4); define_tuple!(C, t6 , T0, T1, T2, T3, T4, T5); define_tuple!(C, t7 , T0, T1, T2, T3, T4, T5, T6); define_tuple!(C, t8 , T0, T1, T2, T3, T4, T5, T6, T7); define_tuple!(C, t9 , T0, T1, T2, T3, T4, T5, T6, T7, T8); define_tuple!(C, t10, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9); define_tuple!(C, t11, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10); define_tuple!(C, t12, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11); define_tuple!(C, t13, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12); define_tuple!(C, t14, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13); define_tuple!(C, t15, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14); define_tuple!(C, t16, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T16); // @formatter:on /// Helper macro to get the correct Tuple based on the number of arguments... pub macro find_type { // @formatter:off () => { $crate::ctuple::t0::C }, ($T0:tt) => { $crate::ctuple::t1::C }, ($T0:tt, $T1:tt) => { $crate::ctuple::t2::C }, ($T0:tt, $T1:tt, $T2:tt) => { $crate::ctuple::t3::C }, ($T0:tt, $T1:tt, $T2:tt, $T3:tt) => { $crate::ctuple::t4::C }, ($T0:tt, $T1:tt, $T2:tt, $T3:tt, $T4:tt) => { $crate::ctuple::t5::C }, ($T0:tt, $T1:tt, $T2:tt, $T3:tt, $T4:tt, $T5:tt) => { $crate::ctuple::t6::C }, ($T0:tt, $T1:tt, $T2:tt, $T3:tt, $T4:tt, $T5:tt, $T6:tt) => { $crate::ctuple::t7::C }, ($T0:tt, $T1:tt, $T2:tt, $T3:tt, $T4:tt, $T5:tt, $T6:tt, $T7:tt) => { $crate::ctuple::t8::C }, ($T0:tt, $T1:tt, $T2:tt, $T3:tt, $T4:tt, $T5:tt, $T6:tt, $T7:tt, $T8:tt) => { $crate::ctuple::t9::C }, ($T0:tt, $T1:tt, $T2:tt, $T3:tt, $T4:tt, $T5:tt, $T6:tt, $T7:tt, $T8:tt, $T9:tt) => { $crate::ctuple::t10::C }, ($T0:tt, $T1:tt, $T2:tt, $T3:tt, $T4:tt, $T5:tt, $T6:tt, $T7:tt, $T8:tt, $T9:tt, $T10:tt) => { $crate::ctuple::t11::C }, ($T0:tt, $T1:tt, $T2:tt, $T3:tt, $T4:tt, $T5:tt, $T6:tt, $T7:tt, $T8:tt, $T9:tt, $T10:tt, $T11:tt) => { $crate::ctuple::t12::C }, ($T0:tt, $T1:tt, $T2:tt, $T3:tt, $T4:tt, $T5:tt, $T6:tt, $T7:tt, $T8:tt, $T9:tt, $T10:tt, $T11:tt, $T12:tt) => { $crate::ctuple::t13::C }, ($T0:tt, $T1:tt, $T2:tt, $T3:tt, $T4:tt, $T5:tt, $T6:tt, $T7:tt, $T8:tt, $T9:tt, $T10:tt, $T11:tt, $T12:tt, $T13:tt) => { $crate::ctuple::t14::C }, ($T0:tt, $T1:tt, $T2:tt, $T3:tt, $T4:tt, $T5:tt, $T6:tt, $T7:tt, $T8:tt, $T9:tt, $T10:tt, $T11:tt, $T12:tt, $T13:tt, $T14:tt) => { $crate::ctuple::t15::C }, ($T0:tt, $T1:tt, $T2:tt, $T3:tt, $T4:tt, $T5:tt, $T6:tt, $T7:tt, $T8:tt, $T9:tt, $T10:tt, $T11:tt, $T12:tt, $T13:tt, $T14:tt, $T15:tt) => { $crate::ctuple::t16::C }, // @formatter:on } #[allow(non_snake_case)] pub macro C { // Simply use the Tuple2CTuple trait to convert the regular tuple to our ReprC variant ($($types:ty),*) => { <($($types,)*) as Tuple2CTuple>::CTuple }, // use the auxiliary macro to find the correct tuple type and construct it ($($values:expr),*) => { $crate::ctuple::find_type!($($values),*)($($values),*) }, }