#![allow(non_snake_case)] use super::*; include!(concat!(env!("OUT_DIR"), "/impl_td.rs")); include!(concat!(env!("OUT_DIR"), "/impl_rv.rs")); include!(concat!(env!("OUT_DIR"), "/impl_pk.rs")); macro_rules! generate {( $($Hd:tt $($T:tt)*)? ) => ( $(generate! { $($T)* })? do_impl! { [$] $($($T)* [$] $Hd)? } )} // impl Reverse for () { // type Reversed = (); // fn reverse(self) -> Self::Reversed { // () // } // } impl Tupl for () { const LEN: usize = 0; type Head = !; type Last = !; type Tail = (); type Init = (); type Inner = (); fn uncons(self) -> (Self::Head, Self::Tail) { todo!() } fn unsnoc(self) -> (Self::Init, Self::Last) { todo!() } fn fcons(head: Self::Head, _: Self::Inner, _: Self::Last) -> Self { match head {} } fn cons(head: Self::Head, _: Self::Tail) -> Self { match head {} } fn snoc(_: Self::Init, last: Self::Last) -> Self { match last {} } } impl Tupl for (T,) { const LEN: usize = 1; type Head = T; type Last = T; type Tail = (); type Init = (); type Inner = (); fn uncons(self) -> (Self::Head, Self::Tail) { unimplemented!("dont call base case.") } fn unsnoc(self) -> (Self::Init, Self::Last) { unimplemented!("dont call base case.") } fn cons(_: Self::Head, _: Self::Tail) -> Self { unimplemented!("dont call base case.") } fn snoc(_: Self::Init, _: Self::Last) -> Self { unimplemented!("dont call base case.") } fn fcons(_: Self::Head, _: Self::Inner, _: Self::Last) -> Self { unimplemented!("dont call base case.") } } macro_rules! do_impl { ([$_:tt]) => {}; ([$_:tt] [$] $i:tt) => {}; // ([$_:tt] $i:ident [$] $x:tt) => {}; ( [$_:tt] // `$` sigil $hd:tt $($i:ident)* [$] $tl:tt ) => ( // impl Seal for ($($i, )*) {} impl<$($i,)* Α> Cons<Α> for ($($i,)*) { type Cons = (Α, $($i,)*); type Snoc = ($($i,)* Α,); } #[allow(non_snake_case)] impl<$hd, $($i,)* $tl> Tupl for ($hd, $($i,)* $tl) { const LEN: usize = 0 $(+ { stringify!($i); 1 } )*; type Head = $hd; type Last = $tl; type Tail = ($($i,)* $tl,); type Init = ($hd, $($i,)*); type Inner = ($($i,)*); fn cons(head: Self::Head, ($($i,)* $tl,): Self::Tail) -> Self { (head, $($i,)* $tl,) } fn snoc(($hd, $($i,)*): Self::Init, last: Self::Last) -> Self { ($hd, $($i,)* last) } fn fcons(head: Self::Head, ($($i,)*): Self::Inner, last: Self::Last) -> Self { (head, $($i,)* last) } fn uncons(self) -> (Self::Head, Self::Tail) { let ($hd, $($i,)* $tl) = self; ($hd, ($($i,)* $tl,)) } fn unsnoc(self) -> (Self::Init, Self::Last) { let ($hd, $($i,)* $tl) = self; (($hd, $($i,)*), $tl) } // 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!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z); impl> Push for U { type Result = U::Snoc; fn push(self, other: T) -> Self::Result { crate::snoc(self, other) } } impl> With for T { type Result = U::Cons; fn with(self, other: U) -> Self::Result { crate::cons(self, other) } }