use std::{cell::{Ref, RefCell}, rc::Rc};
pub struct DenseLinkedListPool<T: Sized + DenseLinkedListNodeTrait> {
list: Vec<T>,
freelist: Vec<usize>,
}
impl<T: Sized + DenseLinkedListNodeTrait> DenseLinkedListPool<T> {
pub fn new(scratch: T) -> Self {
Self{
list: vec![scratch],
freelist: Vec::new(),
}
}
fn create_node(&mut self, data: T) -> usize {
if let Some(id) = self.freelist.pop() {
id
} else {
self.list.push(data);
self.list.len() - 1
}
}
fn create_in_between(&mut self, data: T, prev: usize, next: usize) -> usize {
let node = self.create_node(data);
if prev != 0 && next != 0 {
assert_eq!(self.list[prev].get_next_index(), next);
assert_eq!(self.list[next].get_prev_index(), prev);
}
if prev != 0 {
self.link_bidir_node(prev, node);
}
if next != 0 {
self.link_bidir_node(node, next);
}
node
}
fn get(&self, id: usize) -> &T {
&self.list[id]
}
fn get_mut(&mut self, id: usize) -> &mut T {
&mut self.list[id]
}
#[inline]
fn remove_node(&mut self, id: usize) {
self.freelist.push(id);
}
#[inline]
fn unlink_prev_node(&mut self, at: usize) {
self.list[at].set_next_index(0);
}
#[inline]
fn unlink_next_node(&mut self, at: usize) {
self.list[at].set_next_index(0);
}
#[inline]
fn link_bidir_node(&mut self, prev: usize, next: usize) {
self.list[next].set_prev_index(prev);
self.list[prev].set_next_index(next);
}
#[inline]
fn link_circular(&mut self, at: usize) {
self.list[at].set_prev_index(at);
self.list[at].set_next_index(at);
}
}
pub trait DenseLinkedListNodeTrait {
fn get_next_index(&self) -> usize;
fn set_next_index(&mut self, data: usize);
fn get_prev_index(&self) -> usize;
fn set_prev_index(&mut self, data: usize);
}
pub struct DenseLinkedList<T: Sized + DenseLinkedListNodeTrait> {
pool: *mut DenseLinkedListPool<T>,
root: usize,
}
impl<T: Sized + DenseLinkedListNodeTrait> DenseLinkedList<T> {
pub fn new(pool: *mut DenseLinkedListPool<T>, data: T) -> Self {
let root = pool.create_node(data);
pool.link_circular(root);
Self{
pool,
root
}
}
pub fn append(&mut self, other: Self) {
let mut pool = self.pool.borrow_mut();
let prev = pool.get(self.root).get_prev_index(); assert_ne!(prev, 0);
pool.link_bidir_node(prev, other.root); }
pub fn insert_end<const AT_FRONT: bool>(&mut self, data: T) {
let mut pool = self.pool.borrow_mut();
let prev = pool.get(self.root).get_prev_index();
assert_ne!(prev, 0);
let node = pool.create_in_between(data, prev, self.root);
if AT_FRONT {
self.root = node;
}
}
#[inline]
pub fn back(&self) -> &T {
self.pool.borrow().get(self.root)
}
#[inline]
pub fn back_mut(&mut self) -> &mut T {
self.pool.borrow_mut().get_mut(self.root)
}
pub fn iter(&self) -> DenseLinkedListIterator<T> {
DenseLinkedListIterator{
list: &self,
pool: self.pool.as_ptr(),
index: self.root
}
}
}
pub struct DenseLinkedListIterator<'a, T: Sized + DenseLinkedListNodeTrait> {
list: &'a DenseLinkedList<T>,
pool: *mut DenseLinkedListPool<T>,
index: usize,
}
impl<'a, T: Sized + DenseLinkedListNodeTrait> Iterator for DenseLinkedListIterator<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
if self.index != 0 {
let node = unsafe { self.pool.as_ref().unwrap().get(self.index) };
self.index = node.get_next_index();
if self.index == self.list.root {
None
} else {
Some(node)
}
} else {
None
}
}
}