1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
pub struct Thunk<'f,T>(Box<dyn (FnOnce()-> T) + 'f>) where T: 'f;
impl<'f,T> Thunk<'f,T> where T:'f {
pub fn new<NT,NF>(body: NF) -> Thunk<'f,NT> where
NF: (FnOnce() -> NT) + 'f
{
Thunk(Box::new(body))
}
pub fn new_const<NT: 'f>(nt: NT) -> Thunk<'f,NT> {
Self::new(|| nt)
}
pub fn map_lazy<NT,NF>(self,body: NF) -> Thunk<'f,NT> where
NF: (FnOnce(Thunk<'f,T>) -> NT) + 'f
{
Thunk::<'f,NT>::new(|| (body)(self))
}
pub fn map<NT,NF>(self,body: NF) -> Thunk<'f,NT> where
NF: (FnOnce(T) -> NT) + 'f
{
Thunk::<'f,NT>::new(|| (body)((self.0)()))
}
pub fn unwrap(self) -> T {
(self.0)()
}
}
impl<'f,T,I> From<I> for Thunk<'f,T> where
T: 'f,
I: Iterator<Item = T> + 'f
{
fn from(mut iter: I) -> Self {
Self::new(move || iter.next().unwrap())
}
}
impl<'f,T> IntoIterator for Thunk<'f,T> where
T: 'f
{
type IntoIter = IntoIter<'f,T>;
type Item = T;
fn into_iter(self) -> Self::IntoIter {
IntoIter(Some(self))
}
}
pub struct IntoIter<'f,T>(Option<Thunk<'f,T>>);
impl<'f,T> Iterator for IntoIter<'f,T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if let Some(thunk) = std::mem::take(&mut self.0) {
Some(thunk.unwrap())
} else {
None
}
}
}