jaq_interpret/
rc_lazy_list.rs1use alloc::boxed::Box;
2use alloc::rc::Rc;
3use once_cell::unsync::Lazy;
4
5#[derive(Clone)]
6pub struct List<'a, T>(Rc<Lazy<Node<'a, T>, Eval<'a, T>>>);
7struct Node<'a, T>(Option<(T, List<'a, T>)>);
8type Eval<'a, T> = Box<dyn FnOnce() -> Node<'a, T> + 'a>;
9
10impl<'a, T> Drop for List<'a, T> {
11 fn drop(&mut self) {
12 while let Some((_head, tail)) = Rc::get_mut(&mut self.0)
13 .and_then(Lazy::get_mut)
14 .and_then(|node| node.0.take())
15 {
16 *self = tail;
17 }
18 }
19}
20
21impl<'a, T> Node<'a, T> {
22 fn from_iter(mut iter: impl Iterator<Item = T> + 'a) -> Self {
23 Self(iter.next().map(|x| (x, List::from_iter(iter))))
24 }
25}
26
27impl<'a, T> List<'a, T> {
28 pub fn from_iter(iter: impl Iterator<Item = T> + 'a) -> Self {
29 Self(Rc::new(Lazy::new(Box::new(|| Node::from_iter(iter)))))
30 }
31}
32
33impl<'a, T: Clone + 'a> Iterator for List<'a, T> {
34 type Item = T;
35
36 fn next(&mut self) -> Option<T> {
37 match &Lazy::force(&self.0).0 {
38 None => None,
39 Some((x, xs)) => {
40 let x = x.clone();
41 *self = xs.clone();
42 Some(x)
43 }
44 }
45 }
46}
47
48#[test]
49fn drop() {
50 let list = List::from_iter(0..100_000);
51 assert_eq!(list.clone().sum::<u64>(), 4999950000);
54 std::mem::drop(list);
57}