mod seal { pub trait Seal {} impl Seal for [T; N] {} } use seal::Seal; /// Turn a tuple into a array. Implemented for N≤32 pub trait Array: Sized + Seal { /// Turn a tuple into a array fn array(self) -> [T; N]; /// Turn a array into a tuple. /// Prefer postfix [`Tuple::tuple`]. fn tuple(x: [T; N]) -> Self; } /// Turn a array into a tuple. Implemented for N≤32 pub trait Tuple> { /// Turn a array into a tuple. fn tuple(self) -> O; } impl> Tuple for [T; N] { fn tuple(self) -> O { Array::tuple(self) } } // thanks yandros macro_rules! with_vars { ( [acc: $($acc:tt)*] [to_munch: T $($rest:tt)*] $($cb:tt)* ) => (with_vars! { [acc: $($acc)* x] [to_munch: $($rest)*] $($cb)* }); ( [acc: $($var:ident)*] [to_munch: /* nothing */] |$_:tt $metavar:ident| $body:tt ) => ({ macro_rules! __emit__ {( $_( $_ $metavar:ident)* ) => $body } __emit__! { $($var)* } }); } macro_rules! generate {( $($Hd:tt $($T:tt)*)? ) => ( $(generate! { $($T)* })? do_impl! { [$] $($Hd $($T)*)? } )} macro_rules! do_impl { ([$_:tt]) => {}; ( [$_:tt] // `$` sigil $($i:tt)+ ) => ( impl Seal for ($($i, )*) {} impl Array<{ 0 $(+ { stringify!($i); 1 } )* }, T> for ($($i, )*) { fn array(self) -> [T; 0 $(+ { stringify!($i); 1 } )*] { with_vars! { [acc: ] [to_munch: $($i)*] |$_ x| { let ($_($_ x, )*) = self; [$_($_ x, )*] } } } fn tuple(x: [T; 0 $(+ { stringify!($i); 1 } )*]) -> ($($i, )*) { with_vars! { [acc: ] [to_munch: $($i)*] |$_ x| { let [$_($x, )*] = x; ($_($x, )*) } } } } ); } generate! { T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T }