extern crate typed_arena;
use std::cell::{self, RefCell};
use std::fmt;
use std::ops::{Deref, DerefMut};
pub struct NodeRef<'a, T: 'a>(&'a RefCell<Node<'a, T>>);
struct Node<'a, T: 'a> {
parent: Link<'a, T>,
previous_sibling: Link<'a, T>,
next_sibling: Link<'a, T>,
first_child: Link<'a, T>,
last_child: Link<'a, T>,
data: T,
}
type Link<'a, T> = Option<&'a RefCell<Node<'a, T>>>;
pub struct Arena<'a, T: 'a>(typed_arena::Arena<RefCell<Node<'a, T>>>);
impl<'a, T> Arena<'a, T> {
pub fn new() -> Arena<'a, T> {
Arena(typed_arena::Arena::new())
}
pub fn new_node(&'a self, data: T) -> NodeRef<'a, T> {
NodeRef(self.0.alloc(RefCell::new(Node {
parent: None,
first_child: None,
last_child: None,
previous_sibling: None,
next_sibling: None,
data: data,
})))
}
}
fn same_ref<T>(a: &T, b: &T) -> bool {
a as *const T == b as *const T
}
impl<'a, T> Copy for NodeRef<'a, T> {}
impl<'a, T> Clone for NodeRef<'a, T> {
fn clone(&self) -> NodeRef<'a, T> { *self }
}
impl<'a, T: fmt::Debug> fmt::Debug for NodeRef<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&*self.borrow(), f)
}
}
impl<'a, T> NodeRef<'a, T> {
pub fn parent(self) -> Option<NodeRef<'a, T>> {
self.0.borrow().parent.map(NodeRef)
}
pub fn first_child(self) -> Option<NodeRef<'a, T>> {
self.0.borrow().first_child.map(NodeRef)
}
pub fn last_child(self) -> Option<NodeRef<'a, T>> {
self.0.borrow().last_child.map(NodeRef)
}
pub fn previous_sibling(self) -> Option<NodeRef<'a, T>> {
self.0.borrow().previous_sibling.map(NodeRef)
}
pub fn next_sibling(self) -> Option<NodeRef<'a, T>> {
self.0.borrow().next_sibling.map(NodeRef)
}
pub fn borrow(self) -> Ref<'a, T> {
Ref { _ref: self.0.borrow() }
}
pub fn borrow_mut(self) -> RefMut<'a, T> {
RefMut { _ref: self.0.borrow_mut() }
}
pub fn same_node(self, other: NodeRef<'a, T>) -> bool {
same_ref(self.0, other.0)
}
pub fn ancestors(self) -> Ancestors<'a, T> {
Ancestors(Some(self))
}
pub fn preceding_siblings(self) -> PrecedingSiblings<'a, T> {
PrecedingSiblings(Some(self))
}
pub fn following_siblings(self) -> FollowingSiblings<'a, T> {
FollowingSiblings(Some(self))
}
pub fn children(self) -> Children<'a, T> {
Children(self.first_child())
}
pub fn reverse_children(self) -> ReverseChildren<'a, T> {
ReverseChildren(self.last_child())
}
pub fn descendants(self) -> Descendants<'a, T> {
Descendants(self.traverse())
}
pub fn traverse(self) -> Traverse<'a, T> {
Traverse {
root: self,
next: Some(NodeEdge::Start(self)),
}
}
pub fn reverse_traverse(self) -> ReverseTraverse<'a, T> {
ReverseTraverse {
root: self,
next: Some(NodeEdge::End(self)),
}
}
pub fn detach(self) {
self.0.borrow_mut().detach();
}
pub fn append(self, new_child: NodeRef<'a, T>) {
let mut self_borrow = self.0.borrow_mut();
let mut new_child_borrow = new_child.0.borrow_mut();
new_child_borrow.detach();
new_child_borrow.parent = Some(self.0);
if let Some(last_child) = self_borrow.last_child.take() {
new_child_borrow.previous_sibling = Some(last_child);
debug_assert!(last_child.borrow().next_sibling.is_none());
last_child.borrow_mut().next_sibling = Some(new_child.0);
} else {
debug_assert!(self_borrow.first_child.is_none());
self_borrow.first_child = Some(new_child.0);
}
self_borrow.last_child = Some(new_child.0);
}
pub fn prepend(self, new_child: NodeRef<'a, T>) {
let mut self_borrow = self.0.borrow_mut();
let mut new_child_borrow = new_child.0.borrow_mut();
new_child_borrow.detach();
new_child_borrow.parent = Some(self.0);
if let Some(first_child) = self_borrow.first_child.take() {
debug_assert!(first_child.borrow().previous_sibling.is_none());
first_child.borrow_mut().previous_sibling = Some(new_child.0);
new_child_borrow.next_sibling = Some(first_child);
} else {
debug_assert!(self_borrow.first_child.is_none());
self_borrow.last_child = Some(new_child.0);
}
self_borrow.first_child = Some(new_child.0);
}
pub fn insert_after(self, new_sibling: NodeRef<'a, T>) {
let mut self_borrow = self.0.borrow_mut();
let mut new_sibling_borrow = new_sibling.0.borrow_mut();
new_sibling_borrow.detach();
new_sibling_borrow.parent = self_borrow.parent;
new_sibling_borrow.previous_sibling = Some(self.0);
if let Some(next_sibling) = self_borrow.next_sibling.take() {
debug_assert!(same_ref(next_sibling.borrow().previous_sibling.unwrap(), self.0));
next_sibling.borrow_mut().previous_sibling = Some(new_sibling.0);
new_sibling_borrow.next_sibling = Some(next_sibling);
} else if let Some(parent) = self_borrow.parent {
debug_assert!(same_ref(parent.borrow().last_child.unwrap(), self.0));
parent.borrow_mut().last_child = Some(new_sibling.0);
}
self_borrow.next_sibling = Some(new_sibling.0);
}
pub fn insert_before(self, new_sibling: NodeRef<'a, T>) {
let mut self_borrow = self.0.borrow_mut();
let mut new_sibling_borrow = new_sibling.0.borrow_mut();
new_sibling_borrow.detach();
new_sibling_borrow.parent = self_borrow.parent;
new_sibling_borrow.next_sibling = Some(self.0);
if let Some(previous_sibling) = self_borrow.previous_sibling.take() {
new_sibling_borrow.previous_sibling = Some(previous_sibling);
debug_assert!(same_ref(previous_sibling.borrow().next_sibling.unwrap(), self.0));
previous_sibling.borrow_mut().next_sibling = Some(new_sibling.0);
} else if let Some(parent) = self_borrow.parent {
debug_assert!(same_ref(parent.borrow().first_child.unwrap(), self.0));
parent.borrow_mut().first_child = Some(new_sibling.0);
}
self_borrow.previous_sibling = Some(new_sibling.0);
}
}
pub struct Ref<'a, T: 'a> {
_ref: cell::Ref<'a, Node<'a, T>>
}
pub struct RefMut<'a, T: 'a> {
_ref: cell::RefMut<'a, Node<'a, T>>
}
impl<'a, T> Deref for Ref<'a, T> {
type Target = T;
fn deref(&self) -> &T { &self._ref.data }
}
impl<'a, T> Deref for RefMut<'a, T> {
type Target = T;
fn deref(&self) -> &T { &self._ref.data }
}
impl<'a, T> DerefMut for RefMut<'a, T> {
fn deref_mut(&mut self) -> &mut T { &mut self._ref.data }
}
impl<'a, T> Node<'a, T> {
fn detach(&mut self) {
let parent = self.parent.take();
let previous_sibling = self.previous_sibling.take();
let next_sibling = self.next_sibling.take();
if let Some(next_sibling) = next_sibling {
next_sibling.borrow_mut().previous_sibling = previous_sibling;
} else if let Some(parent) = parent {
parent.borrow_mut().last_child = previous_sibling;
}
if let Some(previous_sibling) = previous_sibling {
previous_sibling.borrow_mut().next_sibling = next_sibling;
} else if let Some(parent) = parent {
parent.borrow_mut().first_child = next_sibling;
}
}
}
macro_rules! impl_node_iterator {
($name: ident, $next: expr) => {
impl<'a, T> Iterator for $name<'a, T> {
type Item = NodeRef<'a, T>;
fn next(&mut self) -> Option<NodeRef<'a, T>> {
match self.0.take() {
Some(node) => {
self.0 = $next(node);
Some(node)
}
None => None
}
}
}
}
}
pub struct Ancestors<'a, T: 'a>(Option<NodeRef<'a, T>>);
impl_node_iterator!(Ancestors, |node: NodeRef<'a, T>| node.parent());
pub struct PrecedingSiblings<'a, T: 'a>(Option<NodeRef<'a, T>>);
impl_node_iterator!(PrecedingSiblings, |node: NodeRef<'a, T>| node.previous_sibling());
pub struct FollowingSiblings<'a, T: 'a>(Option<NodeRef<'a, T>>);
impl_node_iterator!(FollowingSiblings, |node: NodeRef<'a, T>| node.next_sibling());
pub struct Children<'a, T: 'a>(Option<NodeRef<'a, T>>);
impl_node_iterator!(Children, |node: NodeRef<'a, T>| node.next_sibling());
pub struct ReverseChildren<'a, T: 'a>(Option<NodeRef<'a, T>>);
impl_node_iterator!(ReverseChildren, |node: NodeRef<'a, T>| node.previous_sibling());
pub struct Descendants<'a, T: 'a>(Traverse<'a, T>);
impl<'a, T> Iterator for Descendants<'a, T> {
type Item = NodeRef<'a, T>;
fn next(&mut self) -> Option<NodeRef<'a, T>> {
loop {
match self.0.next() {
Some(NodeEdge::Start(node)) => return Some(node),
Some(NodeEdge::End(_)) => {}
None => return None
}
}
}
}
#[derive(Debug, Clone)]
pub enum NodeEdge<T> {
Start(T),
End(T),
}
pub struct Traverse<'a, T: 'a> {
root: NodeRef<'a, T>,
next: Option<NodeEdge<NodeRef<'a, T>>>,
}
impl<'a, T> Iterator for Traverse<'a, T> {
type Item = NodeEdge<NodeRef<'a, T>>;
fn next(&mut self) -> Option<NodeEdge<NodeRef<'a, T>>> {
match self.next.take() {
Some(item) => {
self.next = match item {
NodeEdge::Start(ref node) => {
match node.first_child() {
Some(first_child) => Some(NodeEdge::Start(first_child)),
None => Some(NodeEdge::End(node.clone()))
}
}
NodeEdge::End(ref node) => {
if node.same_node(self.root) {
None
} else {
match node.next_sibling() {
Some(next_sibling) => Some(NodeEdge::Start(next_sibling)),
None => match node.parent() {
Some(parent) => Some(NodeEdge::End(parent)),
None => None
}
}
}
}
};
Some(item)
}
None => None
}
}
}
pub struct ReverseTraverse<'a, T: 'a> {
root: NodeRef<'a, T>,
next: Option<NodeEdge<NodeRef<'a, T>>>,
}
impl<'a, T> Iterator for ReverseTraverse<'a, T> {
type Item = NodeEdge<NodeRef<'a, T>>;
fn next(&mut self) -> Option<NodeEdge<NodeRef<'a, T>>> {
match self.next.take() {
Some(item) => {
self.next = match item {
NodeEdge::End(ref node) => {
match node.last_child() {
Some(last_child) => Some(NodeEdge::End(last_child)),
None => Some(NodeEdge::Start(node.clone()))
}
}
NodeEdge::Start(ref node) => {
if node.same_node(self.root) {
None
} else {
match node.previous_sibling() {
Some(previous_sibling) => Some(NodeEdge::End(previous_sibling)),
None => match node.parent() {
Some(parent) => Some(NodeEdge::Start(parent)),
None => None
}
}
}
}
};
Some(item)
}
None => None
}
}
}
#[test]
fn it_works() {
struct DropTracker<'a>(&'a cell::Cell<u32>);
impl<'a> Drop for DropTracker<'a> {
fn drop(&mut self) {
self.0.set(self.0.get() + 1);
}
}
let drop_counter = cell::Cell::new(0);
{
let mut new_counter = 0;
let arena = Arena::new();
let mut new = || {
new_counter += 1;
arena.new_node((new_counter, DropTracker(&drop_counter)))
};
let a = new(); a.append(new()); a.append(new()); a.prepend(new()); let b = new(); b.append(a.clone());
a.insert_before(new()); a.insert_before(new()); a.insert_after(new()); a.insert_after(new()); let c = new(); b.append(c.clone());
assert_eq!(drop_counter.get(), 0);
c.previous_sibling().unwrap().detach();
assert_eq!(drop_counter.get(), 0);
assert_eq!(b.descendants().map(|node| {
let borrow = node.borrow();
borrow.0
}).collect::<Vec<_>>(), [
5, 6, 7, 1, 4, 2, 3, 9, 10
]);
}
assert_eq!(drop_counter.get(), 10);
}