#[derive(Clone, Copy)]
pub struct LinkedList {
pub head: *mut usize,
}
unsafe impl Send for LinkedList{}
impl LinkedList {
pub const fn new() -> LinkedList {
return LinkedList{
head: ptr::null_mut(),
};
}
pub fn empty(&self) -> bool {
return self.head.is_null();
}
pub unsafe fn push(&mut self, item: *mut usize) {
*item = self.head as usize;
self.head = item;
}
pub fn pop(&mut self) -> Option<*mut usize> {
return match self.empty() {
true => None,
false => {
let item: *mut usize = self.head;
self.head = unsafe{ *item as *mut usize };
Some(item)
}
};
}
pub fn iterator(&self) -> Iter {
return Iter{
current: self.head,
list: PhantomData,
}
}
pub fn iterator_mut(&mut self) -> IterMut {
return IterMut{
previous: &mut self.head as *mut *mut usize as *mut usize,
current: self.head,
list: PhantomData,
};
}
}
impl Debug for LinkedList {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_list().entries(self.iterator()).finish()
}
}
pub struct ListNode {
pub previous: *mut usize,
pub current: *mut usize,
}
impl ListNode {
pub fn pop(self) -> *mut usize {
unsafe{
*(self.previous) = *(self.current);
}
return self.current;
}
pub fn value(&self) -> *mut usize {
return self.current;
}
}
pub struct Iter<'a> {
pub current: *mut usize,
list: PhantomData<&'a LinkedList>,
}
impl<'a> Iterator for Iter<'a> {
type Item = *mut usize;
fn next(&mut self) -> Option<Self::Item> {
return if self.current.is_null() {
None
} else {
let item: *mut usize = self.current;
let next: *mut usize = unsafe{ *item as *mut usize };
self.current = next;
Some(item)
}
}
}
pub struct IterMut<'a> {
list: PhantomData<&'a mut LinkedList>,
pub current: *mut usize,
pub previous: *mut usize,
}
impl<'a> Iterator for IterMut<'a> {
type Item = ListNode;
fn next(&mut self) -> Option<Self::Item> {
return if self.current.is_null() {
None
} else {
let result = ListNode{
current: self.current,
previous: self.previous,
};
self.previous = self.current;
self.current = unsafe{ *self.current as *mut usize };
Some(result)
};
}
}
use {
core::{
fmt::{Debug, Formatter},
marker::PhantomData,
ptr,
},
};