#![allow(unused)]
use std::mem::{self, MaybeUninit};
pub struct Stack<T, const S: usize = 64> {
items: [MaybeUninit<T>;S],
len: usize,
}
impl<T> Stack<T, 64> {
pub fn new() -> Self {
Self {
items: [const { MaybeUninit::uninit() };64],
len: 0,
}
}
}
impl<T, const S: usize> Stack<T, S> {
pub fn with_size() -> Self {
Self {
items: [const { MaybeUninit::uninit() };S],
len: 0,
}
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len == 0
}
#[must_use]
pub fn is_full(&self) -> bool {
self.len == S
}
pub fn len(&self) -> usize {
self.len
}
pub fn push(&mut self, item: T) -> Option<T> {
if self.len == S {
return Some(item);
}
self.items[self.len].write(item);
self.len += 1;
None
}
#[must_use]
pub fn pop(&mut self) -> Option<T> {
if self.is_empty() {
return None;
}
self.len -= 1;
let item = mem::replace(&mut self.items[self.len], MaybeUninit::uninit());
Some(unsafe { item.assume_init() })
}
pub fn as_slice(&self) -> &[T] {
unsafe { mem::transmute(&self.items[..self.len]) }
}
pub fn as_mut_slice(&mut self) -> &mut [T] {
unsafe { mem::transmute(&mut self.items[..self.len]) }
}
}
impl<T, const S: usize> Drop for Stack<T,S> {
fn drop(&mut self) {
for item in &mut self.items[..self.len] {
unsafe { item.assume_init_drop() };
}
}
}
impl<T, const S: usize> IntoIterator for Stack<T,S> {
type Item = T;
type IntoIter = IntoIter<T, S>;
fn into_iter(mut self) -> Self::IntoIter {
let len = self.len;
let items = mem::replace(&mut self.items, [const { MaybeUninit::uninit() };S]);
self.len = 0;
IntoIter { items, len }
}
}
impl<T, const S: usize> std::ops::Deref for Stack<T, S> {
type Target = [T];
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl<T, const S: usize> std::ops::DerefMut for Stack<T, S> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_mut_slice()
}
}
impl<T: std::fmt::Debug, const S: usize> std::fmt::Debug for Stack<T, S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Stack")
.field("items", &self.as_slice())
.field("len", &self.len)
.finish()
}
}
pub struct IntoIter<T, const S: usize> {
items: [MaybeUninit<T>;S],
len: usize,
}
impl<T, const S: usize> Drop for IntoIter<T,S> {
fn drop(&mut self) {
for item in &mut self.items[..self.len] {
unsafe { item.assume_init_drop() };
}
}
}
impl<T, const S: usize> ExactSizeIterator for IntoIter<T, S> { }
impl<T, const S: usize> Iterator for IntoIter<T, S> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.len == 0 {
return None;
}
self.len -= 1;
let item = mem::replace(&mut self.items[self.len], MaybeUninit::uninit());
Some(unsafe { item.assume_init() })
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len,Some(self.len))
}
}