1use alloc::vec;
11use alloc::vec::Vec;
12use core::ops::{Index, Range};
13
14#[derive(Debug)]
17pub struct Stack<T: Clone> {
18    cache: Vec<T>,
20    popped: Vec<T>,
27    lengths: Vec<(usize, usize)>,
41}
42
43impl<T: Clone> Default for Stack<T> {
44    fn default() -> Self {
45        Self::new()
46    }
47}
48
49impl<T: Clone> Stack<T> {
50    pub fn new() -> Self {
52        Stack {
53            cache: vec![],
54            popped: vec![],
55            lengths: vec![],
56        }
57    }
58
59    #[allow(dead_code)]
61    pub fn is_empty(&self) -> bool {
62        self.cache.is_empty()
63    }
64
65    pub fn peek(&self) -> Option<&T> {
67        self.cache.last()
68    }
69
70    pub fn push(&mut self, elem: T) {
72        self.cache.push(elem);
73    }
74
75    pub fn pop(&mut self) -> Option<T> {
77        let len = self.cache.len();
78        let popped = self.cache.pop();
79        if let Some(popped) = &popped {
80            if let Some((_, remained_count)) = self.lengths.last_mut() {
81                if len == *remained_count {
83                    *remained_count -= 1;
84                    self.popped.push(popped.clone());
85                }
86            }
87        }
88        popped
89    }
90
91    pub fn len(&self) -> usize {
93        self.cache.len()
94    }
95
96    pub fn snapshot(&mut self) {
98        self.lengths.push((self.cache.len(), self.cache.len()))
99    }
100
101    pub fn clear_snapshot(&mut self) {
103        if let Some((len, unpopped)) = self.lengths.pop() {
104            self.popped.truncate(self.popped.len() - (len - unpopped));
106        }
107    }
108
109    pub fn restore(&mut self) {
112        match self.lengths.pop() {
113            Some((len_stack, remained)) => {
114                if remained < self.cache.len() {
115                    self.cache.truncate(remained);
117                }
118                if len_stack > remained {
119                    let rewind_count = len_stack - remained;
120                    let new_len = self.popped.len() - rewind_count;
121                    let recovered_elements = self.popped.drain(new_len..);
122                    self.cache.extend(recovered_elements.rev());
123                    debug_assert_eq!(self.popped.len(), new_len);
124                }
125            }
126            None => {
127                self.cache.clear();
128                debug_assert!(self.popped.is_empty());
131                debug_assert!(self.lengths.is_empty());
132            }
133        }
134    }
135}
136
137impl<T: Clone> Index<Range<usize>> for Stack<T> {
138    type Output = [T];
139
140    fn index(&self, range: Range<usize>) -> &[T] {
141        self.cache.index(range)
142    }
143}
144
145#[cfg(test)]
146mod test {
147    use super::Stack;
148
149    #[test]
150    fn snapshot_with_empty() {
151        let mut stack = Stack::new();
152
153        stack.snapshot();
154        assert!(stack.is_empty());
156        stack.push(0);
158        stack.restore();
159        assert!(stack.is_empty());
160    }
161
162    #[test]
163    fn snapshot_twice() {
164        let mut stack = Stack::new();
165
166        stack.push(0);
167
168        stack.snapshot();
169        stack.snapshot();
170        stack.restore();
171        stack.restore();
172
173        assert_eq!(stack[0..stack.len()], [0]);
174    }
175    #[test]
176    fn restore_without_snapshot() {
177        let mut stack = Stack::new();
178
179        stack.push(0);
180        stack.restore();
181
182        assert_eq!(stack[0..stack.len()], [0; 0]);
183    }
184
185    #[test]
186    fn snapshot_pop_restore() {
187        let mut stack = Stack::new();
188
189        stack.push(0);
190        stack.snapshot();
191        stack.pop();
192        stack.restore();
193
194        assert_eq!(stack[0..stack.len()], [0]);
195    }
196
197    #[test]
198    fn snapshot_pop_push_restore() {
199        let mut stack = Stack::new();
200
201        stack.push(0);
202        stack.snapshot();
203        stack.pop();
204        stack.push(1);
205        stack.restore();
206
207        assert_eq!(stack[0..stack.len()], [0]);
208    }
209
210    #[test]
211    fn snapshot_push_pop_restore() {
212        let mut stack = Stack::new();
213
214        stack.push(0);
215        stack.snapshot();
216        stack.push(1);
217        stack.push(2);
218        stack.pop();
219        stack.restore();
220
221        assert_eq!(stack[0..stack.len()], [0]);
222    }
223
224    #[test]
225    fn snapshot_push_clear() {
226        let mut stack = Stack::new();
227
228        stack.push(0);
229        stack.snapshot();
230        stack.push(1);
231        stack.clear_snapshot();
232
233        assert_eq!(stack[0..stack.len()], [0, 1]);
234    }
235
236    #[test]
237    fn snapshot_pop_clear() {
238        let mut stack = Stack::new();
239
240        stack.push(0);
241        stack.push(1);
242        stack.snapshot();
243        stack.pop();
244        stack.clear_snapshot();
245
246        assert_eq!(stack[0..stack.len()], [0]);
247    }
248
249    #[test]
250    fn stack_ops() {
251        let mut stack = Stack::new();
252
253        assert!(stack.is_empty());
255        assert_eq!(stack.peek(), None);
256        assert_eq!(stack.pop(), None);
257
258        stack.push(0);
260        assert!(!stack.is_empty());
261        assert_eq!(stack.peek(), Some(&0));
262
263        stack.push(1);
265        assert!(!stack.is_empty());
266        assert_eq!(stack.peek(), Some(&1));
267
268        assert_eq!(stack.pop(), Some(1));
270        assert!(!stack.is_empty());
271        assert_eq!(stack.peek(), Some(&0));
272
273        stack.push(2);
275        assert!(!stack.is_empty());
276        assert_eq!(stack.peek(), Some(&2));
277
278        stack.push(3);
280        assert!(!stack.is_empty());
281        assert_eq!(stack.peek(), Some(&3));
282
283        stack.snapshot();
286
287        assert_eq!(stack.pop(), Some(3));
289        assert!(!stack.is_empty());
290        assert_eq!(stack.peek(), Some(&2));
291
292        stack.snapshot();
295
296        assert_eq!(stack.pop(), Some(2));
298        assert!(!stack.is_empty());
299        assert_eq!(stack.peek(), Some(&0));
300
301        assert_eq!(stack.pop(), Some(0));
303        assert!(stack.is_empty());
304
305        stack.restore();
308        assert_eq!(stack.pop(), Some(2));
309        assert_eq!(stack.pop(), Some(0));
310        assert_eq!(stack.pop(), None);
311
312        stack.restore();
315        assert_eq!(stack.pop(), Some(3));
316        assert_eq!(stack.pop(), Some(2));
317        assert_eq!(stack.pop(), Some(0));
318        assert_eq!(stack.pop(), None);
319    }
320}