use std::mem::MaybeUninit;
pub struct Stack<T, const N: usize> {
parents: [MaybeUninit<T>; N],
len: usize,
fallback: Vec<T>,
}
impl<T, const N: usize> Stack<T, N> {
const INIT: MaybeUninit<T> = MaybeUninit::uninit();
#[allow(dead_code)] pub fn len(&self) -> usize {
self.len
}
pub fn push(&mut self, item: T) {
if self.len < N {
unsafe { self.parents[self.len].as_mut_ptr().write(item) };
} else {
self.fallback.push(item);
}
self.len += 1;
}
pub fn pop(&mut self) -> Option<T> {
let parent = match self.len {
0 => None,
i if i <= N => {
let parent = std::mem::replace(&mut self.parents[i - 1], MaybeUninit::uninit());
Some(unsafe { parent.assume_init() })
}
_ => self.fallback.pop(),
};
self.len = self.len.saturating_sub(1);
parent
}
}
impl<T, const N: usize> Default for Stack<T, N> {
fn default() -> Self {
Self {
parents: [Self::INIT; N],
len: 0,
fallback: Vec::new(),
}
}
}