pub mod prelude {
#[doc(inline)]
pub use super::{first, second, third, uncons};
}
pub trait Empty {}
pub trait Singleton: First {}
pub trait Pair: First + Second {}
pub trait Triple: First + Second + Third {}
pub trait First {
type First;
fn first(self) -> Self::First;
}
pub trait Second {
type Second;
fn second(self) -> Self::Second;
}
pub trait Third {
type Third;
fn third(self) -> Self::Third;
}
pub trait Cons {
type Head;
type Tail;
fn uncons(self) -> (Self::Head, Self::Tail);
}
pub fn first<P: First>(seq: P) -> P::First {
seq.first()
}
pub fn second<P: Second>(seq: P) -> P::Second {
seq.second()
}
pub fn third<P: Third>(seq: P) -> P::Third {
seq.third()
}
pub fn uncons<L: Cons>(list: L) -> (L::Head, L::Tail) {
list.uncons()
}
impl<'a, A> Cons for &'a [A] {
type Head = Option<&'a A>;
type Tail = &'a [A];
fn uncons(self) -> (Self::Head, Self::Tail) {
if self.len() > 0 {
let (a, b) = self.split_at(1);
(Some(&a[0]), b)
} else {
(None, &[])
}
}
}
impl<'a, A> Cons for &'a mut [A] {
type Head = Option<&'a mut A>;
type Tail = &'a mut [A];
fn uncons(self) -> (Self::Head, Self::Tail) {
if self.len() > 0 {
let (a, b) = self.split_at_mut(1);
(Some(&mut a[0]), b)
} else {
(None, &mut [])
}
}
}
macro_rules! one {
($($t:tt)*) => {1}
}
macro_rules! expr {
($e:expr) => {$e}
}
macro_rules! count {
($($t:ident),*) => {
$(one!($t) +)* 0
}
}
macro_rules! impl_list {
() => {};
($Fi:tt $Ft:ident, $($Ai:tt $At:ident,)*) => {
impl<$Ft, $($At),*> Cons for ($Ft, $($At),*) {
type Head = $Ft;
type Tail = ($($At,)*);
fn uncons(self) -> (Self::Head, Self::Tail) {
expr!((self.$Fi, ($(self.$Ai,)*)))
}
}
impl<'a, $Ft, $($At),*> Cons for &'a ($Ft, $($At),*) {
type Head = &'a $Ft;
type Tail = ($(&'a $At,)*);
fn uncons(self) -> (Self::Head, Self::Tail) {
expr!((&self.$Fi, ($(&self.$Ai,)*)))
}
}
impl<'a, $Ft, $($At),*> Cons for &'a mut ($Ft, $($At),*) {
type Head = &'a mut $Ft;
type Tail = ($(&'a mut $At,)*);
fn uncons(self) -> (Self::Head, Self::Tail) {
expr!((&mut self.$Fi, ($(&mut self.$Ai,)*)))
}
}
impl<'a, 'b, $Ft, $($At),*> Cons for &'a &'b ($Ft, $($At),*) {
type Head = &'b $Ft;
type Tail = ($(&'b $At,)*);
fn uncons(self) -> (Self::Head, Self::Tail) {
(*self).uncons()
}
}
impl<'a, 'b, $Ft, $($At),*> Cons for &'a mut &'b ($Ft, $($At),*) {
type Head = &'b $Ft;
type Tail = ($(&'b $At,)*);
fn uncons(self) -> (Self::Head, Self::Tail) {
(*self).uncons()
}
}
impl<'b, 'a: 'b, $Ft, $($At),*> Cons for &'a mut &'b mut ($Ft, $($At),*) {
type Head = &'b mut $Ft;
type Tail = ($(&'b mut $At,)*);
fn uncons(self) -> (Self::Head, Self::Tail) {
(*self).uncons()
}
}
impl<$Ft> Cons for [$Ft; count!($Ft $(,$At)*)] {
type Head = $Ft;
type Tail = [$Ft; count!($($At),*)];
fn uncons(self) -> (Self::Head, Self::Tail) {
use std::{ptr, mem};
unsafe {
let ptr = self.as_ptr();
let a = ptr::read(ptr);
let b = ptr::read(ptr.offset(1) as *const [$Ft; count!($($At),*)]);
mem::forget(self);
(a, b)
}
}
}
impl<'a, $Ft> Cons for &'a [$Ft; count!($Ft $(,$At)*)] {
type Head = &'a $Ft;
type Tail = &'a [$Ft; count!($($At),*)];
fn uncons(self) -> (Self::Head, Self::Tail) {
unsafe {
let ptr = self.as_ptr();
let a = &*ptr;
let b = &*(ptr.offset(1) as *const [$Ft; count!($($At),*)]);
(a, b)
}
}
}
impl<'a, $Ft> Cons for &'a mut [$Ft; count!($Ft $(,$At)*)] {
type Head = &'a mut $Ft;
type Tail = &'a mut [$Ft; count!($($At),*)];
fn uncons(self) -> (Self::Head, Self::Tail) {
unsafe {
let ptr = self.as_mut_ptr();
let a = &mut *ptr;
let b = &mut *(ptr.offset(1) as *mut [$Ft; count!($($At),*)]);
(a, b)
}
}
}
impl<'a, 'b, $Ft> Cons for &'a &'b [$Ft; count!($Ft $(,$At)*)] {
type Head = &'b $Ft;
type Tail = &'b [$Ft; count!($($At),*)];
fn uncons(self) -> (Self::Head, Self::Tail) {
(*self).uncons()
}
}
impl<'a, 'b, $Ft> Cons for &'a mut &'b [$Ft; count!($Ft $(,$At)*)] {
type Head = &'b $Ft;
type Tail = &'b [$Ft; count!($($At),*)];
fn uncons(self) -> (Self::Head, Self::Tail) {
(*self).uncons()
}
}
impl<'b, 'a: 'b, $Ft> Cons for &'a mut &'b mut [$Ft; count!($Ft $(,$At)*)] {
type Head = &'b mut $Ft;
type Tail = &'b mut [$Ft; count!($($At),*)];
fn uncons(self) -> (Self::Head, Self::Tail) {
(*self).uncons()
}
}
}
}
impl_list!{0 A, 1 B, 2 C, 3 D, 4 E, 5 F, 6 G, 7 H, 8 I, 9 J,}
impl_list!{0 A, 1 B, 2 C, 3 D, 4 E, 5 F, 6 G, 7 H, 8 I,}
impl_list!{0 A, 1 B, 2 C, 3 D, 4 E, 5 F, 6 G, 7 H,}
impl_list!{0 A, 1 B, 2 C, 3 D, 4 E, 5 F, 6 G,}
impl_list!{0 A, 1 B, 2 C, 3 D, 4 E, 5 F,}
impl_list!{0 A, 1 B, 2 C, 3 D, 4 E,}
impl_list!{0 A, 1 B, 2 C, 3 D,}
impl_list!{0 A, 1 B, 2 C,}
impl_list!{0 A, 1 B,}
impl_list!{0 A,}
impl<T> First for T where T: Cons {
type First = T::Head;
fn first(self) -> Self::First {
self.uncons().0
}
}
impl<T> Second for T
where T: Cons,
T::Tail: Cons
{
type Second = <T::Tail as Cons>::Head;
fn second(self) -> Self::Second {
self.uncons().1.uncons().0
}
}
impl<T> Third for T
where T: Cons,
T::Tail: Cons,
<T::Tail as Cons>::Tail: Cons,
{
type Third = <<T::Tail as Cons>::Tail as Cons>::Head;
fn third(self) -> Self::Third {
self.uncons().1.uncons().1.uncons().0
}
}
impl Empty for () {}
impl<'a> Empty for &'a () {}
impl<'a> Empty for &'a mut () {}
impl<'a, T> Empty for &'a [T; 0] {}
impl<'a, T> Empty for &'a mut [T; 0] {}
impl<A> Singleton for (A,) {}
impl<'a, A> Singleton for &'a (A,) {}
impl<'a, A> Singleton for &'a mut (A,) {}
impl<'a, A> Singleton for &'a [A; 1] {}
impl<'a, A> Singleton for &'a mut [A; 1] {}
impl<A, B> Pair for (A, B) {}
impl<'a, A, B> Pair for &'a (A, B) {}
impl<'a, A, B> Pair for &'a mut (A, B) {}
impl<'a, A> Pair for &'a [A; 2] {}
impl<'a, A> Pair for &'a mut [A; 2] {}
impl<A, B, C> Triple for (A, B, C) {}
impl<'a, A, B, C> Triple for &'a (A, B, C) {}
impl<'a, A, B, C> Triple for &'a mut (A, B, C) {}
impl<'a, A> Triple for &'a [A; 3] {}
impl<'a, A> Triple for &'a mut [A; 3] {}