use bumpalo::Bump;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
struct Node<'b, T> {
val: T,
next: Option<&'b Node<'b, T>>,
}
#[derive(Debug, Clone, Default)]
pub(crate) struct Stack<'b, T> {
head: Option<&'b Node<'b, T>>,
}
impl<T: PartialEq> PartialEq for Stack<'_, T> {
fn eq(&self, other: &Self) -> bool {
let mut lhs = self.head;
let mut rhs = other.head;
loop {
match (lhs, rhs) {
(None, None) => return true,
(Some(lhs_node), Some(rhs_node)) => {
if std::ptr::eq(lhs_node, rhs_node) {
return true;
}
if lhs_node.val != rhs_node.val {
return false;
}
lhs = lhs_node.next;
rhs = rhs_node.next;
}
_ => return false,
}
}
}
}
impl<T: Eq> Eq for Stack<'_, T> {}
impl<'b, T> Stack<'b, T> {
pub(crate) fn new() -> Self {
Self { head: None }
}
pub(crate) fn peek(&self) -> Option<&T> {
self.head.map(|n| &n.val)
}
pub(crate) fn pop(&self) -> Option<Self> {
self.head.map(|n| Self { head: n.next })
}
pub(crate) fn push(&self, v: T, alloc: &'b Bump) -> Self {
Self {
head: Some(alloc.alloc(Node {
val: v,
next: self.head,
})),
}
}
pub(crate) fn size(&self) -> usize {
std::iter::successors(self.head, |&n| n.next).count()
}
pub(crate) fn is_empty(&self) -> bool {
self.head.is_none()
}
}