1#[derive(Debug, Default, PartialEq, Clone, Copy)]
2enum Entry<T> {
3 Occupied(T),
4 #[default]
5 Empty,
6}
7
8impl<T> Entry<T> {
9 fn to_value_ref(&self) -> Option<&T> {
10 match self {
11 Self::Occupied(val) => Some(val),
12 Self::Empty => None,
13 }
14 }
15
16 fn to_value_mut(&mut self) -> Option<&mut T> {
17 match self {
18 Self::Occupied(val) => Some(val),
19 Self::Empty => None,
20 }
21 }
22
23 fn into_value(self) -> Option<T> {
24 match self {
25 Self::Occupied(val) => Some(val),
26 Self::Empty => None,
27 }
28 }
29}
30
31#[derive(Debug, Default)]
34pub struct Stack<T> {
35 inner: Vec<Entry<T>>,
36 len: usize,
37}
38
39impl<T> Stack<T> {
40 pub const fn empty() -> Self {
42 Self {
43 inner: Vec::new(),
44 len: 0,
45 }
46 }
47
48 pub fn next_index(&self) -> usize {
50 self.len
51 }
52
53 pub fn with_capacity(cap: usize) -> Self {
56 let mut inner = Vec::with_capacity(cap);
57 inner.fill_with(|| Entry::Empty);
58 Self { inner, len: 0 }
59 }
60
61 pub fn push(&mut self, value: T) {
63 let mut entry = Entry::Occupied(value);
64 if self.len < self.inner.len() {
65 std::mem::swap(&mut entry, &mut self.inner[self.len]);
66 } else {
67 self.inner.push(entry);
68 }
69 self.len += 1;
70 }
71
72 pub fn pop(&mut self) -> Option<T> {
74 if self.is_empty() {
75 return None;
76 }
77
78 let mut entry = Entry::Empty;
79 self.len -= 1;
80 std::mem::swap(&mut entry, &mut self.inner[self.len]);
81 let value = entry
82 .into_value()
83 .expect("the length would be zero if there wasn't a value present");
84 Some(value)
85 }
86
87 pub fn get(&self, index: usize) -> Option<&T> {
88 let entry = self.inner.get(index)?;
89 match entry {
90 Entry::Occupied(val) => Some(val),
91 Entry::Empty => None,
92 }
93 }
94
95 #[must_use]
101 pub fn swap(&mut self, index: usize, new_value: T) -> T {
102 let mut entry = Entry::Occupied(new_value);
103 std::mem::swap(&mut self.inner[index], &mut entry);
104 match entry {
105 Entry::Occupied(val) => val,
106 Entry::Empty => panic!("tried to take value from an empty entry"),
107 }
108 }
109
110 pub fn iter(&self) -> impl DoubleEndedIterator<Item = &T> + '_ {
112 self.inner[..self.len].iter().filter_map(Entry::to_value_ref)
113 }
114
115 pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut T> + '_ {
117 self.inner[..self.len].iter_mut().filter_map(Entry::to_value_mut)
118 }
119
120 pub fn drain(&mut self) -> StackDrain<T, impl DoubleEndedIterator<Item = T> + '_> {
131 let len = std::mem::take(&mut self.len);
132 let iter = self.inner[..len]
133 .iter_mut()
134 .rev()
135 .filter_map(|e| match std::mem::take(e) {
136 Entry::Occupied(value) => Some(value),
137 Entry::Empty => unreachable!(),
138 });
139
140 StackDrain { inner: iter, len }
141 }
142
143 pub fn clear(&mut self) {
145 self.inner[..self.len].fill_with(|| Entry::Empty);
146 self.len = 0;
147 }
148
149 pub fn is_empty(&self) -> bool {
151 self.len == 0
152 }
153
154 pub fn len(&self) -> usize {
155 self.len
156 }
157
158 pub fn reserve(&mut self, len: usize) {
159 if self.len >= len {
160 return;
161 }
162
163 self.inner.resize_with(len, || Entry::Empty);
164 }
165
166 pub fn drain_into(&mut self, local: &mut Stack<T>) {
170 if self.is_empty() {
171 return;
172 }
173 local.reserve(self.len);
174 self.drain().rev().for_each(|ent| local.push(ent));
175 }
176}
177
178impl<T: PartialEq> Stack<T> {
179 pub fn contains(&self, value: &T) -> bool {
181 self.iter().any(|v| v == value)
182 }
183}
184
185impl<T: Copy> Stack<T> {
186 pub fn drain_copy_into(&mut self, local: &mut Stack<T>) {
190 if self.is_empty() {
191 return;
192 }
193 local.reserve(self.len);
194 local.len = self.len;
195 local.inner[..self.len].copy_from_slice(&self.inner[..self.len]);
196 self.clear();
197 }
198}
199
200impl<T> FromIterator<T> for Stack<T> {
201 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
202 let inner = iter.into_iter().map(|val| Entry::Occupied(val)).collect::<Vec<_>>();
203
204 Self {
205 len: inner.len(),
206 inner,
207 }
208 }
209}
210
211pub struct StackDrain<T, I>
215where
216 I: DoubleEndedIterator<Item = T>,
217{
218 inner: I,
219 len: usize,
220}
221
222impl<T, I> StackDrain<T, I>
223where
224 I: DoubleEndedIterator<Item = T>,
225{
226 pub fn len(&self) -> usize {
227 self.len
228 }
229}
230
231impl<T, I> Iterator for StackDrain<T, I>
232where
233 I: DoubleEndedIterator<Item = T>,
234{
235 type Item = T;
236
237 fn next(&mut self) -> Option<Self::Item> {
238 self.inner.next()
239 }
240}
241
242impl<T, I> DoubleEndedIterator for StackDrain<T, I>
243where
244 I: DoubleEndedIterator<Item = T>,
245{
246 fn next_back(&mut self) -> Option<Self::Item> {
247 self.inner.next_back()
248 }
249}
250
251impl<T, I> Drop for StackDrain<T, I>
252where
253 I: DoubleEndedIterator<Item = T>,
254{
255 fn drop(&mut self) {
256 self.for_each(|_| {});
257 }
258}
259
260#[cfg(test)]
261mod test {
262 use super::*;
263
264 #[test]
265 fn drain() {
266 let mut stack = Stack::empty();
267 stack.push(1);
268 stack.push(2);
269
270 let mut iter = stack.drain();
271 assert_eq!(2, iter.next().unwrap());
272 drop(iter);
273
274 assert_eq!(stack.inner, vec![Entry::Empty, Entry::Empty]);
275 }
276}