mod imm_down_walker;
pub(crate) use imm_down_walker::ImmDownBasicWalker;
mod walker;
pub use walker::*;
mod implementations;
pub use implementations::*;
pub mod iterators;
mod iterative_deallocator;
pub use iterative_deallocator::deallocate_iteratively;
use crate::*;
pub enum BasicTree<D: ?Sized + Data, T = ()> {
Empty,
Root(Box<BasicNode<D, T>>), }
use BasicTree::*;
impl<D: Data, T> BasicTree<D, T> {
pub fn new() -> Self {
Empty
}
pub fn action(&self) -> D::Action {
match self.node() {
Some(node) => node.action,
None => Default::default(),
}
}
pub fn from_node(node: BasicNode<D, T>) -> Self {
Root(Box::new(node))
}
pub fn from_boxed_node(boxed: Box<BasicNode<D, T>>) -> Self {
Root(boxed)
}
pub fn alg_data(&self) -> Option<&T> {
Some(self.node()?.alg_data())
}
pub(crate) fn rebuild(&mut self) {
if let Root(node) = self {
node.rebuild()
}
}
pub(crate) fn access(&mut self) {
if let Root(node) = self {
node.access()
}
}
pub fn node(&self) -> Option<&BasicNode<D, T>> {
match self {
Empty => None,
Root(node) => Some(node),
}
}
pub fn node_mut(&mut self) -> Option<&mut BasicNode<D, T>> {
match self {
Empty => None,
Root(node) => Some(node),
}
}
pub fn node_boxed(&mut self) -> Option<&mut Box<BasicNode<D, T>>> {
match self {
Empty => None,
Root(node) => Some(node),
}
}
pub fn into_node(self) -> Option<BasicNode<D, T>> {
match self {
Empty => None,
Root(node) => Some(*node),
}
}
pub fn into_node_boxed(self) -> Option<Box<BasicNode<D, T>>> {
match self {
Empty => None,
Root(node) => Some(node),
}
}
pub fn assert_correctness_with<F>(&self, func: F)
where
F: Fn(&BasicNode<D, T>) + Copy,
{
if let Some(node) = self.node() {
func(node);
node.left.assert_correctness_with(func);
node.right.assert_correctness_with(func);
}
}
}
pub struct BasicNode<D: ?Sized + Data, T = ()> {
action: D::Action,
subtree_summary: D::Summary,
pub(crate) node_value: D::Value,
pub(crate) left: BasicTree<D, T>,
pub(crate) right: BasicTree<D, T>,
pub(crate) alg_data: T,
}
impl<D: Data> BasicNode<D> {
pub fn new(value: D::Value) -> BasicNode<D> {
let subtree_summary = value.to_summary();
BasicNode {
action: Default::default(),
node_value: value,
subtree_summary,
left: Empty,
right: Empty,
alg_data: (),
}
}
}
impl<D: Data, T> BasicNode<D, T> {
pub fn new_alg(value: D::Value, alg_data: T) -> BasicNode<D, T> {
let subtree_summary = value.to_summary();
BasicNode {
action: Default::default(),
node_value: value,
subtree_summary,
left: Empty,
right: Empty,
alg_data,
}
}
pub fn alg_data(&self) -> &T {
&self.alg_data
}
pub(crate) fn action(&self) -> &D::Action {
&self.action
}
pub fn subtree_summary(&self) -> D::Summary {
self.action.act(self.subtree_summary)
}
pub fn node_summary(&self) -> D::Summary {
let summary = self.node_value.to_summary();
self.action.act(summary)
}
pub fn node_value(&mut self) -> &D::Value {
self.access();
&self.node_value
}
pub fn node_value_mut(&mut self) -> &mut D::Value {
self.access();
&mut self.node_value
}
pub(crate) fn node_value_clean(&self) -> &D::Value {
assert!(self.action.is_identity());
&self.node_value
}
pub(crate) fn access(&mut self) {
if self.action.to_reverse() {
std::mem::swap(&mut self.left, &mut self.right);
}
self.left.act_subtree(self.action);
self.right.act_subtree(self.action);
self.action.act_inplace(&mut self.subtree_summary);
self.action.act_inplace(&mut self.node_value);
self.action = Default::default();
}
pub(crate) fn rebuild(&mut self) {
assert!(self.action.is_identity());
let temp = self.node_value.to_summary();
self.subtree_summary = self.left.subtree_summary() + temp + self.right.subtree_summary();
}
pub fn act(&mut self, action: D::Action) {
self.action = action + self.action;
}
pub fn act_value(&mut self, action: D::Action) {
self.access();
action.act_inplace(&mut self.node_value);
}
#[cfg(debug_assertions)]
pub fn representation<F>(&self, alg_print: &F, to_reverse: bool) -> String
where
F: Fn(&Self) -> String,
{
let xor = self.action().to_reverse() ^ to_reverse;
let shebang = if self.action().to_reverse() { "!" } else { "" };
let mut left = self.left.representation(alg_print, xor);
let mut right = self.right.representation(alg_print, xor);
if xor {
std::mem::swap(&mut left, &mut right);
}
format!("{} {} {} {}", shebang, alg_print(self), left, right)
}
pub fn assert_correctness_locally(&self)
where
D::Summary: Eq,
{
let ns = self.subtree_summary;
let os: D::Summary = self.left.subtree_summary()
+ self.node_value.to_summary()
+ self.right.subtree_summary();
assert!(ns == os, "Incorrect summaries found.");
}
}