use std::{
marker::PhantomData,
ptr::NonNull,
};
use super::TempArena;
struct Node<T> {
pub value: T,
pub next: Option<NonNull<Node<T>>>,
}
impl<T> Node<T> {
#[inline]
const fn new(value: T, next: Option<NonNull<Node<T>>>) -> Self {
Self { value, next }
}
}
pub struct List<T> {
next: Option<NonNull<Node<T>>>,
len: usize,
}
impl<T> List<T> {
#[inline]
pub fn new() -> Self {
Self { next: None, len: 0, }
}
#[inline]
pub fn push(&mut self, arena: &TempArena, value: T) {
let ptr = arena.push(Node::new(value, self.next.take()));
self.next = NonNull::new(ptr as *mut _);
self.len += 1;
}
#[inline]
pub fn iter(&self) -> Iter<'_, T> {
Iter { next: self.next, marker: PhantomData, }
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
IterMut { next: self.next, marker: PhantomData, }
}
}
pub struct Iter<'l, T> {
next: Option<NonNull<Node<T>>>,
marker: PhantomData<&'l Node<T>>,
}
impl<'l, T> Iterator for Iter<'l, T> {
type Item = &'l T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.next.take().map(|node| unsafe {
let node = &*node.as_ptr();
self.next = node.next;
&node.value
})
}
}
pub struct IterMut<'l, T> {
next: Option<NonNull<Node<T>>>,
marker: PhantomData<&'l Node<T>>,
}
impl<'l, T> Iterator for IterMut<'l, T> {
type Item = &'l mut T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.next.take().map(|node| unsafe {
let node = &mut *node.as_ptr();
self.next = node.next;
&mut node.value
})
}
}