evobench_tools/utillib/
conslist.rs1pub enum List<'t, T> {
10 Pair(T, &'t List<'t, T>),
11 Null,
12}
13
14impl<'t, T> List<'t, T> {
15 pub fn len(&self) -> usize {
16 match self {
17 List::Pair(_, r) => r.len() + 1,
18 List::Null => 0,
19 }
20 }
21
22 pub fn is_empty(&self) -> bool {
23 match self {
24 List::Pair(_, _) => false,
25 List::Null => true,
26 }
27 }
28
29 pub fn first(&self) -> Option<&T> {
30 match self {
31 List::Pair(v, _) => Some(v),
32 List::Null => None,
33 }
34 }
35
36 pub fn rest<'s>(&'s self) -> Option<&'s List<'s, T>> {
37 match self {
38 List::Pair(_, r) => Some(r),
39 List::Null => None,
40 }
41 }
42
43 pub fn last(&self) -> Option<&T> {
44 match self {
45 List::Pair(v, List::Null) => Some(v),
46 List::Pair(_, r) => r.last(),
47 List::Null => None,
48 }
49 }
50
51 pub fn as_ref_vec(&self) -> Vec<&T> {
55 let mut vs = Vec::new();
56 let mut r = self;
57 while let List::Pair(v, r2) = r {
58 vs.push(v);
59 r = r2;
60 }
61 vs
62 }
63
64 pub fn to_vec(&self) -> Vec<T>
65 where
66 T: Clone,
67 {
68 let mut vs: Vec<T> = Vec::new();
69 let mut r = self;
70 while let List::Pair(v, r2) = r {
71 vs.push(v.clone());
72 r = r2;
73 }
74 vs
75 }
76
77 pub fn any(&self, mut f: impl FnMut(&T) -> bool) -> bool {
78 let mut vs = self;
79 loop {
80 match vs {
81 List::Pair(val, list) => {
82 if f(val) {
83 return true;
84 }
85 vs = list;
86 }
87 List::Null => return false,
88 }
89 }
90 }
91}
92
93pub fn cons<'l, T>(v: T, r: &'l List<T>) -> List<'l, T> {
94 List::Pair(v, r)
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100
101 #[test]
102 fn t_() {
103 let a = List::Pair(5, &List::Null);
104 let b = List::Pair(7, &a);
105 let c = List::Pair(9, &b);
106 let d = cons(13, &b);
107 let e = cons(14, &c);
108 assert_eq!(List::Null::<i8>.as_ref_vec(), Vec::<&i8>::new());
109 assert_eq!(a.to_vec(), vec![5]);
110 assert_eq!(b.as_ref_vec(), vec![&7, &5]);
111 assert_eq!(c.rest().unwrap().to_vec(), vec![7, 5]);
112 assert_eq!(c.to_vec(), vec![9, 7, 5]);
113 assert_eq!(d.to_vec(), vec![13, 7, 5]);
114 assert_eq!(e.to_vec(), vec![14, 9, 7, 5]);
115 }
116}