#[cfg(feature="quickcheck")]
extern crate quickcheck;
pub mod cow;
pub mod count;
pub mod iter;
pub mod test;
pub mod unbox;
use std::mem;
use std::ops::DerefMut;
pub trait BinaryTree {
type Node: Node;
fn root(&self) -> Option<&Self::Node>;
}
unsafe fn borrow<'a, T, U>(raw: *const T, _: &'a U) -> &'a T {
&*raw
}
unsafe fn borrow_mut<'a, T, U>(raw: *mut T, _: &'a U) -> &'a mut T {
&mut *raw
}
pub trait Node {
type Value;
fn left(&self) -> Option<&Self>;
fn right(&self) -> Option<&Self>;
fn value(&self) -> &Self::Value;
fn walk<'a, F>(&'a self, mut step_in: F)
where F: FnMut(&'a Self) -> WalkAction
{
use WalkAction::*;
let mut subtree = Some(self);
while let Some(mut st) = subtree {
let action = step_in(&mut st);
subtree = match action {
Left => st.left(),
Right => st.right(),
Stop => break,
};
}
}
}
pub trait NodeMut: Node + Sized {
type NodePtr: Sized + DerefMut<Target = Self>;
fn detach_left(&mut self) -> Option<Self::NodePtr>;
fn detach_right(&mut self) -> Option<Self::NodePtr>;
fn insert_left(&mut self, tree: Option<Self::NodePtr>) -> Option<Self::NodePtr>;
fn insert_right(&mut self, tree: Option<Self::NodePtr>) -> Option<Self::NodePtr>;
fn value_mut(&mut self) -> &mut Self::Value;
fn into_parts(self) -> (Self::Value, Option<Self::NodePtr>, Option<Self::NodePtr>);
fn left_mut(&mut self) -> Option<&mut Self>;
fn right_mut(&mut self) -> Option<&mut Self>;
fn rotate_left(&mut self) -> Result<(), ()> {
if let Some(mut self2) = self.detach_right() {
let mid = self2.detach_left();
self.insert_right(mid);
mem::swap(self, &mut self2);
self.insert_left(Some(self2));
Ok(())
} else {
Err(())
}
}
fn rotate_right(&mut self) -> Result<(), ()> {
if let Some(mut self2) = self.detach_left() {
let mid = self2.detach_right();
self.insert_left(mid);
mem::swap(self, &mut self2);
self.insert_right(Some(self2));
Ok(())
} else {
Err(())
}
}
fn walk_mut<'a, FI, FS>(&'a mut self, mut step_in: FI, stop: FS)
where FI: FnMut(&Self) -> WalkAction,
FS: FnOnce(&'a mut Self)
{
use WalkAction::*;
let mut node: *mut _ = self;
loop {
let action = {
let pin = ();
step_in(unsafe { borrow(node, &pin) })
};
let next = match action {
Left => unsafe { borrow_mut(node, self) }.left_mut(),
Right => unsafe { borrow_mut(node, self) }.right_mut(),
Stop => break,
};
if let Some(st) = next {
node = st;
} else {
break;
}
}
stop(unsafe { borrow_mut(node, self) });
}
fn walk_reshape<FI, FS, FO>(&mut self, mut step_in: FI, stop: FS, mut step_out: FO)
where FI: FnMut(&mut Self) -> WalkAction,
FS: FnOnce(&mut Self),
FO: FnMut(&mut Self, WalkAction)
{
use WalkAction::*;
let mut stack = Vec::with_capacity(8);
let root_action = step_in(self);
let mut subtree = match root_action {
Left => self.detach_left(),
Right => self.detach_right(),
Stop => None,
};
let mut action = root_action;
while action != Stop {
if let Some(mut st) = subtree {
action = step_in(&mut st);
subtree = match action {
Left => st.detach_left(),
Right => st.detach_right(),
Stop => None,
};
stack.push((st, action));
} else {
break;
}
}
if let Some((mut sst, _)) = stack.pop() {
stop(&mut sst);
while let Some((mut st, action)) = stack.pop() {
match action {
Left => st.insert_left(Some(sst)),
Right => st.insert_right(Some(sst)),
Stop => unreachable!(),
};
step_out(&mut st, action);
sst = st;
}
match root_action {
Left => self.insert_left(Some(sst)),
Right => self.insert_right(Some(sst)),
Stop => unreachable!(),
};
step_out(self, root_action);
} else {
stop(self)
}
}
fn insert_before<F>(&mut self, new_node: Self::NodePtr, mut step_out: F)
where F: FnMut(&mut Self, WalkAction)
{
use WalkAction::*;
if let Some(mut left) = self.detach_left() {
left.walk_reshape(|_| Right,
move |node| {
node.insert_right(Some(new_node));
},
&mut step_out);
self.insert_left(Some(left));
step_out(self, Left);
} else {
self.insert_left(Some(new_node));
}
}
fn walk_extract<FI, FE, FO>(&mut self, step_in: FI, extract: FE, mut step_out: FO) -> Option<Self::NodePtr>
where FI: FnMut(&mut Self) -> WalkAction,
FE: FnOnce(&mut Self, &mut Option<Self::NodePtr>),
FO: FnMut(&mut Self, WalkAction)
{
use WalkAction::*;
let ret = std::cell::RefCell::new(None);
self.walk_reshape(step_in,
|node| extract(node, &mut *ret.borrow_mut()),
|node, action| {
if ret.borrow().is_none() {
*ret.borrow_mut() = match action {
Left => node.detach_left(),
Right => node.detach_right(),
Stop => unreachable!(),
};
}
step_out(node, action);
});
ret.into_inner()
}
fn try_remove<F>(&mut self, mut step_out: F) -> Option<Self::NodePtr>
where F: FnMut(&mut Self, WalkAction)
{
use WalkAction::*;
if let Some(mut left) = self.detach_left() {
if self.right().is_none() {
mem::swap(&mut *left, self);
Some(left)
} else {
let mut pio = left.walk_extract(|_| Right,
|node, ret| {
if let Some(mut left) = node.detach_left() {
mem::swap(&mut *left, node);
*ret = Some(left);
}
},
&mut step_out);
if let Some(ref mut pio) = pio {
pio.insert_left(Some(left));
} else {
pio = Some(left);
}
let mut pio = pio.unwrap();
pio.insert_right(self.detach_right());
step_out(&mut pio, Left);
mem::swap(&mut *pio, self);
Some(pio) }
} else if let Some(mut right) = self.detach_right() {
mem::swap(&mut *right, self);
Some(right)
} else {
None
}
}
}
#[derive(Clone, Copy, PartialEq)]
pub enum WalkAction {
Left,
Right,
Stop,
}