use std::mem::MaybeUninit; use std::ops::{Deref, DerefMut}; pub struct StackVec { values: [MaybeUninit; CAPACITY], len: usize, } impl Deref for StackVec { type Target = [T]; fn deref(&self) -> &Self::Target { self.as_slice() } } impl DerefMut for StackVec { fn deref_mut(&mut self) -> &mut Self::Target { self.as_mut_slice() } } impl FromIterator for StackVec { fn from_iter>(iter: I) -> Self { let mut this = Self::new(); for item in iter { this.push(item); } this } } impl StackVec { pub fn new() -> Self { Self { values: MaybeUninit::uninit_array(), len: 0, } } pub fn capcity(&self) -> usize { CAPACITY } pub fn len(&self) -> usize { self.len } pub fn is_empty(&self) -> bool { self.len == 0 } pub fn as_slice(&self) -> &[T] { // safety: the first `len` elements are guaranteed to be initialized unsafe { MaybeUninit::slice_assume_init_ref(&self.values[..self.len]) } } pub fn as_mut_slice(&mut self) -> &mut [T] { // safety: the first `len` elements are guaranteed to be initialized unsafe { MaybeUninit::slice_assume_init_mut(&mut self.values[..self.len]) } } pub fn as_ptr(&self) -> *const T { self.values.as_ptr().cast() } pub fn as_mut_ptr(&mut self) -> *mut T { self.values.as_mut_ptr().cast() } pub fn try_push(&mut self, value: T) -> Option<()> { self.values.get_mut(self.len)?.write(value); self.len += 1; Some(()) } pub fn push(&mut self, value: T) { self.values[self.len].write(value); self.len += 1; } pub fn pop(&mut self) -> Option { if self.is_empty() { return None; } // safety: this value will no longer be used, and the value is valid // because it appears in the valid part of the array unsafe { self.len -= 1; Some(std::ptr::read(self.as_ptr().add(self.len()))) } } pub fn clear(&mut self) { self.len = 0; } }