use std::cell::UnsafeCell;
use std::marker::PhantomData;
use std::mem;
use std::ops::{Deref, DerefMut};
struct Own<T>(UnsafeCell<T>);
struct Ref<T>(*mut T);
struct Link<T>(Option<Box<NodeOwn<T>>>);
type LinkOwn<T> = Own<Link<T>>;
type LinkRef<T> = Ref<Link<T>>;
struct Node<T> {
next: LinkOwn<T>,
owning_link: LinkRef<T>,
val: Option<T>,
}
type NodeOwn<T> = Own<Node<T>>;
type NodeRef<T> = Ref<Node<T>>;
pub struct TailList<T> {
head: LinkOwn<T>,
}
pub struct Cursor<'node, T: 'node> {
dummy: NodeRef<T>,
phantom: PhantomData<&'node mut Node<T>>,
}
pub struct ValRef<'node, T: 'node> {
node: NodeRef<T>,
phantom: PhantomData<&'node Node<T>>,
}
pub struct TailValRef<'node, 'tail, T: 'node + 'tail> {
val_ref: ValRef<'node, T>,
phantom: PhantomData<Cursor<'tail, T>>,
}
impl<T> Own<T> {
fn new(val: T) -> Own<T> { Own(UnsafeCell::new(val)) }
}
impl<T> Link<T> {
fn new() -> Link<T> { Link(None) }
fn new_to_node(node: NodeOwn<T>) -> Link<T> {
Link(Some(Box::new(node)))
}
fn opt_node_ref(&self) -> Option<NodeRef<T>> {
self.0.as_ref().map(|owned| owned.new_ref())
}
}
impl<T> Node<T> {
fn new(val: Option<T>, owning_link: LinkRef<T>) -> Node<T> {
Node {
next: Own::new(Link::new()),
owning_link: owning_link,
val: val,
}
}
}
impl<T> TailList<T> {
pub fn new() -> TailList<T> {
TailList {
head: Own::new(Link::new()),
}
}
pub fn push(&mut self, val: T) {
insert_at(&self.head, Some(val));
}
pub fn cursor<'node>(&'node mut self) -> Cursor<'node, T> {
Cursor::new(&self.head.new_ref())
}
}
impl<'node, T: 'node> Cursor<'node, T> {
fn new(at: &LinkRef<T>) -> Cursor<'node, T> {
Cursor {
dummy: insert_at(at, None),
phantom: PhantomData,
}
}
pub fn next<'tail>(&'tail mut self) -> Option<TailValRef<'node, 'tail, T>> {
let next_ref_opt: Option<NodeRef<T>> = self.dummy.borrow_inner().next
.borrow_inner().opt_node_ref();
let next_ref = match next_ref_opt {
Some(next_ref) => next_ref,
None => return None,
};
swap_places(&self.dummy, &next_ref);
if next_ref.borrow_inner().val.is_none() {
return self.next();
}
Some(TailValRef {
val_ref: ValRef {
node: next_ref,
phantom: PhantomData,
},
phantom: PhantomData,
})
}
}
impl<'node, T: 'node> ValRef<'node, T> {
fn new(node: NodeRef<T>) -> ValRef<'node, T> {
ValRef {
node: node,
phantom: PhantomData,
}
}
pub fn insert_before(&mut self, val: T) -> ValRef<'node, T> {
ValRef::new(insert_at(&self.node.borrow_inner().owning_link, Some(val)))
}
pub fn insert_after(&mut self, val: T) -> ValRef<'node, T> {
ValRef::new(insert_at(&self.node.borrow_inner().next, Some(val)))
}
pub fn remove(self) -> T {
let val = unlink(self.node);
if let Some(val) = val {
return val;
}
unreachable!("cannot remove dummy node")
}
}
impl<'node, 'tail, T: 'node + 'tail> TailValRef<'node, 'tail, T> {
pub fn tail<'slf>(&'slf mut self) -> (&'slf ValRef<'node, T>,
Cursor<'slf, T>) {
let csr = Cursor::new(&self.val_ref.node.borrow_inner().next.new_ref());
(&self.val_ref, csr)
}
pub fn into_tail(self) -> (ValRef<'node, T>, Cursor<'tail, T>) {
let csr = Cursor::new(&self.val_ref.node.borrow_inner().next.new_ref());
(self.val_ref, csr)
}
pub fn into_passive(self) -> ValRef<'node, T> {
self.val_ref
}
pub fn insert_before(&mut self, val: T) -> ValRef<'node, T> {
self.val_ref.insert_before(val)
}
pub fn insert_after(&mut self, val: T) -> ValRef<'node, T> {
self.val_ref.insert_after(val)
}
pub fn remove(self) -> T {
self.val_ref.remove()
}
}
fn insert_at<T, L: OwnRef<Inner=Link<T>>>(link: &L, val: Option<T>) -> NodeRef<T> {
let node = Own::new(Node::new(val, link.new_ref()));
let link: &mut Link<T> = link.borrow_inner_mut();
{
let next: &mut Link<T> = node.borrow_inner().next.borrow_inner_mut();
mem::swap(link, next);
}
*link = Link::new_to_node(node);
let node_ref = link.opt_node_ref()
.expect("the option was just initialized to some");
fixup_owning_link(&node_ref.borrow_inner().next);
node_ref
}
fn swap_places<T>(a: &NodeRef<T>, b: &NodeRef<T>) {
let a_link = a.borrow_inner().owning_link.borrow_inner_mut();
let b_link = b.borrow_inner().owning_link.borrow_inner_mut();
mem::swap(a_link, b_link);
let a_next = a.borrow_inner().next.borrow_inner_mut();
let b_next = b.borrow_inner().next.borrow_inner_mut();
mem::swap(a_next, b_next);
fixup_owning_link(&a.borrow_inner().owning_link);
fixup_owning_link(&b.borrow_inner().owning_link);
fixup_owning_link(&a.borrow_inner().next);
fixup_owning_link(&b.borrow_inner().next);
}
fn unlink<T>(node_ref: NodeRef<T>) -> Option<T> {
let next: &mut Link<T> = node_ref.borrow_inner().next
.borrow_inner_mut();
let owning_link_ref: LinkRef<T> = node_ref.borrow_inner().owning_link
.clone();
let owning_link: &mut Link<T> = owning_link_ref.borrow_inner_mut();
let tmp_link_own = Own::new(Link::new());
{
let tmp_link: &mut Link<T> = tmp_link_own.borrow_inner_mut();
mem::swap(tmp_link, owning_link);
mem::swap(owning_link, next);
fixup_owning_link(&owning_link_ref);
}
unsafe {
let val: NodeOwn<T> = *tmp_link_own.0.into_inner().0
.expect("the option was just set to some");
val.0.into_inner().val
}
}
fn fixup_owning_link<T, L: OwnRef<Inner=Link<T>>>(link: &L) {
let opt_node_ref = link.borrow_inner().opt_node_ref();
if let Some(node_ref) = opt_node_ref {
let node = node_ref.borrow_inner_mut();
node.owning_link = link.new_ref();
}
}
trait OwnRef {
type Inner;
fn get_mut_ptr(&self) -> *mut Self::Inner;
fn new_ref(&self) -> Ref<Self::Inner> {
Ref(self.get_mut_ptr())
}
fn borrow_inner(&self) -> &Self::Inner {
unsafe { & *self.get_mut_ptr() }
}
fn borrow_inner_mut(&self) -> &mut Self::Inner {
unsafe { &mut *self.get_mut_ptr() }
}
}
impl<T> OwnRef for Own<T> {
type Inner = T;
fn get_mut_ptr(&self) -> *mut T { self.0.get() }
}
impl<T> OwnRef for Ref<T> {
type Inner = T;
fn get_mut_ptr(&self) -> *mut T { self.0 }
}
impl<T> Clone for Ref<T> {
fn clone(&self) -> Ref<T> {
Ref(self.0)
}
}
impl <'node, T: 'node> Drop for Cursor<'node, T> {
fn drop(&mut self) {
unlink(self.dummy.clone());
}
}
impl<'node, T: 'node> Deref for ValRef<'node, T> {
type Target = T;
fn deref(&self) -> &T {
if let Some(ref val) = self.node.borrow_inner().val {
return val;
}
unreachable!("cannot deref dummy node");
}
}
impl<'node, T: 'node> DerefMut for ValRef<'node, T> {
fn deref_mut(&mut self) -> &mut T {
if let Some(ref mut val) = self.node.borrow_inner_mut().val {
return val;
}
unreachable!("cannot deref dummy node");
}
}
impl<'node, 'tail, T: 'node + 'tail> Deref for TailValRef<'node, 'tail, T> {
type Target = T;
fn deref(&self) -> &T {
self.val_ref.deref()
}
}
impl<'node, 'tail, T: 'node + 'tail> DerefMut for TailValRef<'node, 'tail, T> {
fn deref_mut(&mut self) -> &mut T {
self.val_ref.deref_mut()
}
}
#[cfg(test)]
mod tests {
include!( "./lib_tests.rs");
}