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, remained)) = self.lengths.pop() {
104 let popped_count = len - remained;
105 if let Some((_, parent_remained)) = self.lengths.last_mut() {
106 let merged_remained = (*parent_remained).min(remained);
107 let parent_popped = *parent_remained - merged_remained;
108 *parent_remained = merged_remained;
109
110 let popped_start = self.popped.len() - popped_count;
111 drop(
112 self.popped
113 .drain(popped_start..popped_start + popped_count - parent_popped),
114 );
115 } else {
116 self.popped.truncate(self.popped.len() - popped_count);
117 }
118 }
119 }
120
121 pub fn restore(&mut self) {
124 match self.lengths.pop() {
125 Some((len_stack, remained)) => {
126 if remained < self.cache.len() {
127 self.cache.truncate(remained);
129 }
130 if len_stack > remained {
131 let rewind_count = len_stack - remained;
132 let new_len = self.popped.len() - rewind_count;
133 let recovered_elements = self.popped.drain(new_len..);
134 self.cache.extend(recovered_elements.rev());
135 debug_assert_eq!(self.popped.len(), new_len);
136 }
137 }
138 None => {
139 self.cache.clear();
140 debug_assert!(self.popped.is_empty());
143 debug_assert!(self.lengths.is_empty());
144 }
145 }
146 }
147}
148
149impl<T: Clone> Index<Range<usize>> for Stack<T> {
150 type Output = [T];
151
152 fn index(&self, range: Range<usize>) -> &[T] {
153 self.cache.index(range)
154 }
155}
156
157#[cfg(test)]
158mod test {
159 use super::Stack;
160
161 #[test]
162 fn snapshot_with_empty() {
163 let mut stack = Stack::new();
164
165 stack.snapshot();
166 assert!(stack.is_empty());
168 stack.push(0);
170 stack.restore();
171 assert!(stack.is_empty());
172 }
173
174 #[test]
175 fn snapshot_twice() {
176 let mut stack = Stack::new();
177
178 stack.push(0);
179
180 stack.snapshot();
181 stack.snapshot();
182 stack.restore();
183 stack.restore();
184
185 assert_eq!(stack[0..stack.len()], [0]);
186 }
187 #[test]
188 fn restore_without_snapshot() {
189 let mut stack = Stack::new();
190
191 stack.push(0);
192 stack.restore();
193
194 assert_eq!(stack[0..stack.len()], [0; 0]);
195 }
196
197 #[test]
198 fn snapshot_pop_restore() {
199 let mut stack = Stack::new();
200
201 stack.push(0);
202 stack.snapshot();
203 stack.pop();
204 stack.restore();
205
206 assert_eq!(stack[0..stack.len()], [0]);
207 }
208
209 #[test]
210 fn snapshot_pop_push_restore() {
211 let mut stack = Stack::new();
212
213 stack.push(0);
214 stack.snapshot();
215 stack.pop();
216 stack.push(1);
217 stack.restore();
218
219 assert_eq!(stack[0..stack.len()], [0]);
220 }
221
222 #[test]
223 fn snapshot_push_pop_restore() {
224 let mut stack = Stack::new();
225
226 stack.push(0);
227 stack.snapshot();
228 stack.push(1);
229 stack.push(2);
230 stack.pop();
231 stack.restore();
232
233 assert_eq!(stack[0..stack.len()], [0]);
234 }
235
236 #[test]
237 fn snapshot_push_clear() {
238 let mut stack = Stack::new();
239
240 stack.push(0);
241 stack.snapshot();
242 stack.push(1);
243 stack.clear_snapshot();
244
245 assert_eq!(stack[0..stack.len()], [0, 1]);
246 }
247
248 #[test]
249 fn snapshot_pop_clear() {
250 let mut stack = Stack::new();
251
252 stack.push(0);
253 stack.push(1);
254 stack.snapshot();
255 stack.pop();
256 stack.clear_snapshot();
257
258 assert_eq!(stack[0..stack.len()], [0]);
259 }
260
261 #[test]
262 fn nested_snapshot_pop_clear_restore() {
263 let mut stack = Stack::new();
264
265 stack.push(0);
266 stack.snapshot();
267 stack.snapshot();
268 stack.pop();
269 stack.clear_snapshot();
270 stack.restore();
271
272 assert_eq!(stack[0..stack.len()], [0]);
273 }
274
275 #[test]
276 fn nested_snapshot_clear_preserves_outer_boundary() {
277 let mut stack = Stack::new();
278
279 stack.push(0);
280 stack.snapshot();
281 stack.push(1);
282 stack.snapshot();
283 stack.pop();
284 stack.clear_snapshot();
285 stack.restore();
286
287 assert_eq!(stack[0..stack.len()], [0]);
288 }
289
290 #[test]
291 fn stack_ops() {
292 let mut stack = Stack::new();
293
294 assert!(stack.is_empty());
296 assert_eq!(stack.peek(), None);
297 assert_eq!(stack.pop(), None);
298
299 stack.push(0);
301 assert!(!stack.is_empty());
302 assert_eq!(stack.peek(), Some(&0));
303
304 stack.push(1);
306 assert!(!stack.is_empty());
307 assert_eq!(stack.peek(), Some(&1));
308
309 assert_eq!(stack.pop(), Some(1));
311 assert!(!stack.is_empty());
312 assert_eq!(stack.peek(), Some(&0));
313
314 stack.push(2);
316 assert!(!stack.is_empty());
317 assert_eq!(stack.peek(), Some(&2));
318
319 stack.push(3);
321 assert!(!stack.is_empty());
322 assert_eq!(stack.peek(), Some(&3));
323
324 stack.snapshot();
327
328 assert_eq!(stack.pop(), Some(3));
330 assert!(!stack.is_empty());
331 assert_eq!(stack.peek(), Some(&2));
332
333 stack.snapshot();
336
337 assert_eq!(stack.pop(), Some(2));
339 assert!(!stack.is_empty());
340 assert_eq!(stack.peek(), Some(&0));
341
342 assert_eq!(stack.pop(), Some(0));
344 assert!(stack.is_empty());
345
346 stack.restore();
349 assert_eq!(stack.pop(), Some(2));
350 assert_eq!(stack.pop(), Some(0));
351 assert_eq!(stack.pop(), None);
352
353 stack.restore();
356 assert_eq!(stack.pop(), Some(3));
357 assert_eq!(stack.pop(), Some(2));
358 assert_eq!(stack.pop(), Some(0));
359 assert_eq!(stack.pop(), None);
360 }
361}