1use core::{
8 mem::MaybeUninit,
9 ops::{Index, IndexMut},
10 ptr,
11};
12
13pub struct StackVec<T, const N: usize> {
32 data: [MaybeUninit<T>; N],
33 len: usize,
34}
35
36impl<T, const N: usize> StackVec<T, N> {
37 #[inline]
41 pub const fn new() -> Self {
42 Self {
43 data: unsafe { MaybeUninit::uninit().assume_init() },
45 len: 0,
46 }
47 }
48
49 #[inline]
53 pub fn push(&mut self, value: T) -> Result<(), T> {
54 if self.len >= N {
55 return Err(value);
56 }
57 unsafe {
59 self.data.get_unchecked_mut(self.len).write(value);
60 }
61 self.len += 1;
62 Ok(())
63 }
64
65 #[inline]
73 pub fn push_unchecked(&mut self, value: T) {
74 debug_assert!(self.len < N, "StackVec capacity exceeded");
75 if self.len < N {
78 unsafe {
79 self.data.get_unchecked_mut(self.len).write(value);
80 }
81 self.len += 1;
82 }
83 }
84
85 #[inline]
87 pub fn pop(&mut self) -> Option<T> {
88 if self.len == 0 {
89 return None;
90 }
91 self.len -= 1;
92 unsafe { Some(self.data.get_unchecked(self.len).assume_init_read()) }
94 }
95
96 #[inline]
98 pub const fn len(&self) -> usize {
99 self.len
100 }
101
102 #[inline]
104 pub const fn is_empty(&self) -> bool {
105 self.len == 0
106 }
107
108 #[inline]
110 pub const fn is_full(&self) -> bool {
111 self.len == N
112 }
113
114 #[inline]
116 pub const fn capacity(&self) -> usize {
117 N
118 }
119
120 #[inline]
122 pub fn clear(&mut self) {
123 while self.pop().is_some() {}
124 }
125
126 #[inline]
128 pub fn as_slice(&self) -> &[T] {
129 unsafe { core::slice::from_raw_parts(self.data.as_ptr() as *const T, self.len) }
131 }
132
133 #[inline]
135 pub fn as_mut_slice(&mut self) -> &mut [T] {
136 unsafe { core::slice::from_raw_parts_mut(self.data.as_mut_ptr() as *mut T, self.len) }
138 }
139
140 #[inline]
142 pub fn get(&self, index: usize) -> Option<&T> {
143 if index < self.len {
144 unsafe { Some(&*self.data.get_unchecked(index).as_ptr()) }
146 } else {
147 None
148 }
149 }
150
151 #[inline]
153 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
154 if index < self.len {
155 unsafe { Some(&mut *self.data.get_unchecked_mut(index).as_mut_ptr()) }
157 } else {
158 None
159 }
160 }
161}
162
163impl<T, const N: usize> Default for StackVec<T, N> {
164 #[inline]
165 fn default() -> Self {
166 Self::new()
167 }
168}
169
170impl<T: core::fmt::Debug, const N: usize> core::fmt::Debug for StackVec<T, N> {
171 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
172 f.debug_list().entries(self.as_slice()).finish()
173 }
174}
175
176impl<T, const N: usize> Drop for StackVec<T, N> {
177 fn drop(&mut self) {
178 for i in 0..self.len {
179 unsafe {
181 ptr::drop_in_place(self.data[i].as_mut_ptr());
182 }
183 }
184 }
185}
186
187impl<T, const N: usize> Index<usize> for StackVec<T, N> {
188 type Output = T;
189
190 #[inline]
191 fn index(&self, index: usize) -> &Self::Output {
192 assert!(index < self.len, "index out of bounds");
193 unsafe { &*self.data.get_unchecked(index).as_ptr() }
195 }
196}
197
198impl<T, const N: usize> IndexMut<usize> for StackVec<T, N> {
199 #[inline]
200 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
201 assert!(index < self.len, "index out of bounds");
202 unsafe { &mut *self.data.get_unchecked_mut(index).as_mut_ptr() }
204 }
205}
206
207impl<T: Clone, const N: usize> Clone for StackVec<T, N> {
208 fn clone(&self) -> Self {
209 let mut new_vec = Self::new();
210 for item in self.as_slice() {
211 let _ = new_vec.push(item.clone());
213 }
214 new_vec
215 }
216}
217
218pub struct StackVecIntoIter<T, const N: usize> {
223 vec: StackVec<T, N>,
224 index: usize,
225}
226
227impl<T, const N: usize> Iterator for StackVecIntoIter<T, N> {
228 type Item = T;
229
230 #[inline]
231 fn next(&mut self) -> Option<Self::Item> {
232 if self.index < self.vec.len {
233 let value = unsafe { self.vec.data.get_unchecked(self.index).assume_init_read() };
235 self.index += 1;
236 Some(value)
237 } else {
238 None
239 }
240 }
241
242 #[inline]
243 fn size_hint(&self) -> (usize, Option<usize>) {
244 let remaining = self.vec.len - self.index;
245 (remaining, Some(remaining))
246 }
247}
248
249impl<T, const N: usize> ExactSizeIterator for StackVecIntoIter<T, N> {}
250
251impl<T, const N: usize> Drop for StackVecIntoIter<T, N> {
252 fn drop(&mut self) {
253 for i in self.index..self.vec.len {
254 unsafe {
256 ptr::drop_in_place(self.vec.data[i].as_mut_ptr());
257 }
258 }
259 self.vec.len = 0;
261 }
262}
263
264impl<T, const N: usize> IntoIterator for StackVec<T, N> {
265 type Item = T;
266 type IntoIter = StackVecIntoIter<T, N>;
267
268 #[inline]
269 fn into_iter(self) -> Self::IntoIter {
270 StackVecIntoIter { vec: self, index: 0 }
271 }
272}
273
274impl<'a, T, const N: usize> IntoIterator for &'a StackVec<T, N> {
275 type Item = &'a T;
276 type IntoIter = core::slice::Iter<'a, T>;
277
278 #[inline]
279 fn into_iter(self) -> Self::IntoIter {
280 self.as_slice().iter()
281 }
282}
283
284impl<'a, T, const N: usize> IntoIterator for &'a mut StackVec<T, N> {
285 type Item = &'a mut T;
286 type IntoIter = core::slice::IterMut<'a, T>;
287
288 #[inline]
289 fn into_iter(self) -> Self::IntoIter {
290 self.as_mut_slice().iter_mut()
291 }
292}
293
294#[cfg(test)]
295mod tests {
296 use std::rc::Rc;
297
298 use super::*;
299
300 #[test]
301 fn test_new_and_empty() {
302 let vec: StackVec<i32, 4> = StackVec::new();
303 assert!(vec.is_empty());
304 assert_eq!(vec.len(), 0);
305 assert_eq!(vec.capacity(), 4);
306 assert!(!vec.is_full());
307 }
308
309 #[test]
310 fn test_push_and_pop() {
311 let mut vec: StackVec<i32, 4> = StackVec::new();
312
313 assert!(vec.push(1).is_ok());
314 assert!(vec.push(2).is_ok());
315 assert!(vec.push(3).is_ok());
316 assert_eq!(vec.len(), 3);
317
318 assert_eq!(vec.pop(), Some(3));
319 assert_eq!(vec.pop(), Some(2));
320 assert_eq!(vec.pop(), Some(1));
321 assert_eq!(vec.pop(), None);
322 assert!(vec.is_empty());
323 }
324
325 #[test]
326 fn test_capacity_limit() {
327 let mut vec: StackVec<i32, 2> = StackVec::new();
328
329 assert!(vec.push(1).is_ok());
330 assert!(vec.push(2).is_ok());
331 assert!(vec.is_full());
332
333 let result = vec.push(3);
335 assert_eq!(result, Err(3));
336 assert_eq!(vec.len(), 2);
337 }
338
339 #[test]
340 fn test_push_unchecked() {
341 let mut vec: StackVec<i32, 4> = StackVec::new();
342 vec.push_unchecked(1);
343 vec.push_unchecked(2);
344 assert_eq!(vec.len(), 2);
345 assert_eq!(vec[0], 1);
346 assert_eq!(vec[1], 2);
347 }
348
349 #[test]
350 #[cfg(debug_assertions)]
351 #[should_panic(expected = "StackVec capacity exceeded")]
352 fn test_push_unchecked_overflow_panics_in_debug() {
353 let mut vec: StackVec<i32, 1> = StackVec::new();
354 vec.push_unchecked(1);
355 vec.push_unchecked(2); }
357
358 #[test]
359 fn test_indexing() {
360 let mut vec: StackVec<i32, 4> = StackVec::new();
361 vec.push(10).unwrap();
362 vec.push(20).unwrap();
363
364 assert_eq!(vec[0], 10);
365 assert_eq!(vec[1], 20);
366
367 vec[0] = 100;
368 assert_eq!(vec[0], 100);
369 }
370
371 #[test]
372 #[should_panic(expected = "index out of bounds")]
373 fn test_index_out_of_bounds() {
374 let vec: StackVec<i32, 4> = StackVec::new();
375 let _ = vec[0];
376 }
377
378 #[test]
379 fn test_get() {
380 let mut vec: StackVec<i32, 4> = StackVec::new();
381 vec.push(1).unwrap();
382
383 assert_eq!(vec.get(0), Some(&1));
384 assert_eq!(vec.get(1), None);
385 }
386
387 #[test]
388 fn test_get_mut() {
389 let mut vec: StackVec<i32, 4> = StackVec::new();
390 vec.push(1).unwrap();
391
392 if let Some(val) = vec.get_mut(0) {
393 *val = 42;
394 }
395 assert_eq!(vec[0], 42);
396 }
397
398 #[test]
399 fn test_clear() {
400 let mut vec: StackVec<i32, 4> = StackVec::new();
401 vec.push(1).unwrap();
402 vec.push(2).unwrap();
403 vec.push(3).unwrap();
404
405 vec.clear();
406 assert!(vec.is_empty());
407 assert_eq!(vec.len(), 0);
408
409 vec.push(42).unwrap();
411 assert_eq!(vec[0], 42);
412 }
413
414 #[test]
415 fn test_as_slice() {
416 let mut vec: StackVec<i32, 4> = StackVec::new();
417 vec.push(1).unwrap();
418 vec.push(2).unwrap();
419 vec.push(3).unwrap();
420
421 assert_eq!(vec.as_slice(), &[1, 2, 3]);
422 }
423
424 #[test]
425 fn test_as_mut_slice() {
426 let mut vec: StackVec<i32, 4> = StackVec::new();
427 vec.push(1).unwrap();
428 vec.push(2).unwrap();
429
430 vec.as_mut_slice()[0] = 10;
431 assert_eq!(vec[0], 10);
432 }
433
434 #[test]
435 fn test_iter_ref() {
436 let mut vec: StackVec<i32, 4> = StackVec::new();
437 vec.push(1).unwrap();
438 vec.push(2).unwrap();
439 vec.push(3).unwrap();
440
441 let collected: Vec<_> = (&vec).into_iter().copied().collect();
442 assert_eq!(collected, vec![1, 2, 3]);
443 }
444
445 #[test]
446 fn test_iter_mut() {
447 let mut vec: StackVec<i32, 4> = StackVec::new();
448 vec.push(1).unwrap();
449 vec.push(2).unwrap();
450
451 for val in &mut vec {
452 *val *= 2;
453 }
454
455 assert_eq!(vec[0], 2);
456 assert_eq!(vec[1], 4);
457 }
458
459 #[test]
460 fn test_into_iter() {
461 let mut vec: StackVec<i32, 4> = StackVec::new();
462 vec.push(1).unwrap();
463 vec.push(2).unwrap();
464 vec.push(3).unwrap();
465
466 let collected: Vec<_> = vec.into_iter().collect();
467 assert_eq!(collected, vec![1, 2, 3]);
468 }
469
470 #[test]
471 fn test_clone() {
472 let mut vec: StackVec<i32, 4> = StackVec::new();
473 vec.push(1).unwrap();
474 vec.push(2).unwrap();
475
476 let cloned = vec.clone();
477 assert_eq!(cloned.len(), 2);
478 assert_eq!(cloned[0], 1);
479 assert_eq!(cloned[1], 2);
480 }
481
482 #[test]
483 fn test_drop_semantics_with_non_copy() {
484 let counter = Rc::new(());
486
487 {
488 let mut vec: StackVec<Rc<()>, 4> = StackVec::new();
489 vec.push(Rc::clone(&counter)).unwrap();
490 vec.push(Rc::clone(&counter)).unwrap();
491 vec.push(Rc::clone(&counter)).unwrap();
492
493 assert_eq!(Rc::strong_count(&counter), 4);
495 }
496
497 assert_eq!(Rc::strong_count(&counter), 1);
499 }
500
501 #[test]
502 fn test_drop_on_clear_with_non_copy() {
503 let counter = Rc::new(());
504
505 let mut vec: StackVec<Rc<()>, 4> = StackVec::new();
506 vec.push(Rc::clone(&counter)).unwrap();
507 vec.push(Rc::clone(&counter)).unwrap();
508
509 assert_eq!(Rc::strong_count(&counter), 3);
510
511 vec.clear();
512 assert_eq!(Rc::strong_count(&counter), 1);
513 }
514
515 #[test]
516 fn test_into_iter_drop_remaining() {
517 let counter = Rc::new(());
518
519 let mut vec: StackVec<Rc<()>, 4> = StackVec::new();
520 vec.push(Rc::clone(&counter)).unwrap();
521 vec.push(Rc::clone(&counter)).unwrap();
522 vec.push(Rc::clone(&counter)).unwrap();
523
524 assert_eq!(Rc::strong_count(&counter), 4);
525
526 let mut iter = vec.into_iter();
528 drop(iter.next()); drop(iter);
532
533 assert_eq!(Rc::strong_count(&counter), 1);
535 }
536
537 #[test]
538 fn test_default() {
539 let vec: StackVec<i32, 4> = StackVec::default();
540 assert!(vec.is_empty());
541 }
542
543 #[test]
544 fn test_size_hint() {
545 let mut vec: StackVec<i32, 4> = StackVec::new();
546 vec.push(1).unwrap();
547 vec.push(2).unwrap();
548 vec.push(3).unwrap();
549
550 let iter = vec.into_iter();
551 assert_eq!(iter.size_hint(), (3, Some(3)));
552 assert_eq!(iter.len(), 3);
553 }
554
555 #[test]
556 fn test_zero_capacity() {
557 let vec: StackVec<i32, 0> = StackVec::new();
558 assert!(vec.is_empty());
559 assert!(vec.is_full());
560 assert_eq!(vec.capacity(), 0);
561 }
562}