#![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<T> 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<T> 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<T, U: Cons<T>> Push<T> for U {
type Result = U::Snoc;
fn push(self, other: T) -> Self::Result {
crate::snoc(self, other)
}
}
impl<T, U: Cons<T>> With<U> for T {
type Result = U::Cons;
fn with(self, other: U) -> Self::Result {
crate::cons(self, other)
}
}