1pub struct Lazy<T> {
10 f : Option<Box<dyn FnOnce() -> T>>,
11 val : Option<T>,
12}
13
14impl<T> Lazy<T> {
15 pub fn new<F : FnOnce() -> T + 'static>(f : F) -> Lazy<T> {
17 Lazy {
18 f : Some(Box::new(f)),
19 val : None,
20 }
21 }
22
23 pub fn force(&mut self) {
25 if self.f.is_some() {
26 let mut f = None;
27 std::mem::swap(&mut f, &mut self.f);
28
29 let f = f.unwrap();
30 let result = (f)();
31 self.val = Some(result);
32 }
33 }
34
35 pub fn into_inner(mut self) -> T {
38 self.force();
39 let Lazy { f : _ , val } = self;
40 val.unwrap()
41 }
42
43 pub fn as_ref(&mut self) -> &T {
45 self.force();
46 self.val.as_ref().unwrap()
47 }
48}
49
50impl<T> AsMut<T> for Lazy<T> {
51 fn as_mut(&mut self) -> &mut T {
53 self.force();
54 self.val.as_mut().unwrap()
55 }
56}
57
58impl<T> Default for Lazy<T>
59 where T : Default {
60 fn default() -> Self {
61 Lazy {
62 f : None,
63 val : Some(T::default())
64 }
65 }
66}
67
68pub struct Seq<T>(Vec<Lazy<T>>);
70
71impl<T> Seq<T> {
72 pub fn new() -> Seq<T> {
74 Seq(Vec::new())
75 }
76
77 pub fn is_empty(&self) -> bool {
79 self.len() == 0
80 }
81
82 pub fn capacity(&self) -> usize {
84 self.0.capacity()
85 }
86
87 pub fn len(&self) -> usize {
89 self.0.len()
90 }
91
92 pub fn with_capacity(capacity : usize) -> Seq<T> {
94 Seq(Vec::with_capacity(capacity))
95 }
96
97 pub fn push<F : FnOnce() -> T + 'static>(&mut self, value : F) {
99 self.0.push(Lazy::new(value))
100 }
101
102 pub fn pop(&mut self) -> Option<T> {
104 let lazy = self.0.pop();
105 lazy.map(|l| l.into_inner())
106 }
107
108 pub fn force_all(&mut self) {
110 for i in 0..self.0.len() {
111 self.0[i].force()
112 }
113 }
114
115 pub fn to_vec(self) -> Vec<T> {
117 let Seq(vec) = self;
118
119 vec
120 .into_iter()
121 .map(|x| x.into_inner())
122 .collect()
123 }
124
125 pub fn to_lazy_vec(self) -> Vec<Lazy<T>> {
128 let Seq(vec) = self;
129 vec
130 }
131
132 pub fn get(&mut self, index : usize) -> Option<&T> {
134 self.0.get_mut(index).map(|l| { l.force(); l.as_ref() })
135 }
136
137 pub fn get_mut(&mut self, index : usize) -> Option<&mut T> {
139 self.0.get_mut(index).map(|l| { l.force(); l.as_mut() })
140 }
141}
142
143impl<T> From<Vec<Box<dyn FnOnce() -> T>>> for Seq<T> {
144 fn from(vec : Vec<Box<dyn FnOnce() -> T>>) -> Self {
145 Seq(
146 vec
147 .into_iter()
148 .map(|b| Lazy { f : Some(b), val : None })
149 .collect()
150 )
151 }
152}
153
154impl<T> From<Vec<T>> for Seq<T> {
155 fn from(vec : Vec<T>) -> Self {
156 Seq(
157 vec
158 .into_iter()
159 .map(|v| Lazy { f : None, val : Some(v) })
160 .collect()
161 )
162 }
163}
164
165impl<T> Default for Seq<T> {
166 fn default() -> Self {
167 Self::new()
168 }
169}
170
171#[macro_export]
173macro_rules! seq {
174 () => (
175 lazy_seq::Seq::new()
176 );
177 ($elem:expr; $n:expr) => (
178 {
179 let mut seq = Seq::with_capacity($n);
180 for _ in 0..$n {
181 seq.push($elem);
182 }
183 seq
184 }
185 );
186 ($($x:expr),+ $(,)?) => (
187 {
188 let mut seq = Seq::new();
189 $(seq.push($x);)*
190 seq
191 }
192 );
193}
194
195#[cfg(test)]
196mod tests {
197 use std::rc::Rc;
198 use std::cell::RefCell;
199 use crate::{Lazy, Seq, seq};
200 #[test]
201 pub fn lazy_correct() {
202 let counter = Rc::new(RefCell::new(0));
203 let counter_new = counter.clone();
204 let mut lazy = Lazy::new(
205 move || {
206 *counter_new.borrow_mut() += 1;
207 5 + 5
208 });
209 let result = lazy.as_ref();
210 assert_eq!(10, *result);
211 }
212
213 #[test]
214 pub fn seq_correct() {
215
216 let counter = Rc::new(RefCell::new(0));
217 let counter_new = counter.clone();
218
219 let mut seq = seq![
220 || { 0 }; 9
221 ];
222
223 assert_eq!(9, seq.len());
224
225 seq.push(move || {
226 *counter_new.borrow_mut() += 1;
227 println!("{:?}", counter_new);
228 5 + 5
229 });
230
231 assert_eq!(10, seq.len());
232
233 assert_eq!(0, *counter.borrow());
234
235 let _ = seq.get(9).unwrap();
236
237 assert_eq!(1, *counter.borrow());
238
239 seq.force_all();
240 let result = seq.pop();
241 assert_eq!(9, seq.len());
242 assert_eq!(1, *counter.borrow());
243 assert_eq!(10, result.unwrap());
244 }
245}