1use crate::engine::Eval;
4use ::typenum as tn;
5
6pub trait Pass: Eval<Result=tn::True> {}
8impl<T> Pass for T where T:Eval<Result=tn::True> {}
9
10
11pub trait Fail: Eval<Result=tn::False> {}
13impl<T> Fail for T where T:Eval<Result=tn::False> {}
14
15pub trait List: internal::List {
16 type Head;
17 type Tail: internal::List;
18 type IsEOL;
19 const LEN: usize;
20
21 fn split(self)->(<Self as List>::Head, <Self as List>::Tail);
22
23 fn head(&self)->&Self::Head;
24 fn tail(&self)->&Self::Tail;
25
26 fn into_iter_as<X>(self)->Self::ListIter where Self:ListOf<X> {
27 self.list_of_iter()
28 }
29}
30
31pub trait ListOf<X>: List + Sized {
32 type ListIter: Iterator<Item=X>;
33 fn list_of_iter(self)->Self::ListIter;
34}
35
36impl<X> ListOf<X> for crate::HNil {
37 type ListIter = std::iter::Empty<X>;
38 fn list_of_iter(self)->Self::ListIter {
39 std::iter::empty()
40 }
41}
42
43impl<H,T,X> ListOf<X> for crate::HCons<H,T>
44where T: ListOf<X>, H:Into<X> {
45 type ListIter = std::iter::Chain<std::iter::Once<X>, T::ListIter>;
46 fn list_of_iter(self)->Self::ListIter {
47 std::iter::once(self.head.into()).chain(self.tail.list_of_iter())
48 }
49}
50
51pub struct RefIter<'a,X:?Sized>(&'a dyn ListOfRefs<X>);
52
53impl<'a,X:?Sized> Iterator for RefIter<'a,X> {
54 type Item = &'a X;
55 fn next(&mut self)->Option<&'a X> {
56 let result = self.0.head_ref();
57 self.0 = self.0.tail_ref();
58 result
59 }
60}
61
62pub trait ListOfRefs<X:?Sized> {
63 fn iter(&self)->RefIter<'_,X> where Self:Sized { RefIter(self) }
64 fn head_ref(&self)->Option<&X>;
65 fn tail_ref(&self)->&dyn ListOfRefs<X>;
66}
67
68impl<X:?Sized> ListOfRefs<X> for crate::HNil {
69 fn head_ref(&self)->Option<&X> { None }
70 fn tail_ref(&self)->&dyn ListOfRefs<X> { self }
71}
72
73impl<H,T,X:?Sized> ListOfRefs<X> for crate::HCons<H,T>
74where T: ListOfRefs<X>, H:AsRef<X> {
75 fn head_ref(&self)->Option<&X> { Some(self.head.as_ref()) }
76 fn tail_ref(&self)->&dyn ListOfRefs<X> { &self.tail }
77}
78
79impl<T> List for T where T:internal::List {
80 type Head = <Self as internal::List>::IHead;
81 type Tail = <Self as internal::List>::ITail;
82 type IsEOL = <Self as internal::List>::IIsEOL;
83 const LEN:usize = <Self as internal::List>::ILEN;
84
85 #[inline(always)]
86 fn split(self)->(<Self as List>::Head, <Self as List>::Tail) { self.i_split() }
87 #[inline(always)]
88 fn head(&self)->&Self::Head { self.i_head() }
89 #[inline(always)]
90 fn tail(&self)->&Self::Tail { self.i_tail() }
91}
92
93mod internal {
94 pub trait List {
95 type IHead;
96 type ITail: List;
97 type IIsEOL;
98 const ILEN:usize;
99
100 fn i_split(self)->(Self::IHead, Self::ITail);
101 fn i_head(&self)->&Self::IHead;
102 fn i_tail(&self)->&Self::ITail;
103 }
104
105 impl List for crate::HNil {
106 type IHead = Self;
107 type ITail = Self;
108 type IIsEOL = ::typenum::True;
109 const ILEN:usize = 0;
110
111 #[inline(always)]
112 fn i_split(self)->(Self,Self) { (crate::HNil, crate::HNil) }
113 #[inline(always)]
114 fn i_head(&self)->&Self::IHead { self }
115 #[inline(always)]
116 fn i_tail(&self)->&Self::ITail { self }
117 }
118
119 impl<H,T:List> List for crate::HCons<H,T>
120 {
121 type IHead = H;
122 type ITail = T;
123 type IIsEOL = ::typenum::False;
124 const ILEN: usize = 1+T::ILEN;
125
126 #[inline(always)]
127 fn i_split(self)->(H,T) { let crate::HCons { head: h, tail: t} = self; (h,t) }
128 #[inline(always)]
129 fn i_head(&self)->&Self::IHead { &self.head }
130 #[inline(always)]
131 fn i_tail(&self)->&Self::ITail { &self.tail }
132 }
133}