#[cfg(feature = "std")]
mod pretty_printer;
mod tree_stats;
#[cfg(feature = "std")]
mod well_formed;
#[cfg(feature = "std")]
pub use pretty_printer::*;
pub use tree_stats::*;
#[cfg(feature = "std")]
pub use well_formed::*;
use super::{
ConcreteNodePtr, InnerNode16, InnerNode4, InnerNode48, InnerNodeDirect, LeafNode, Node,
NodePtr, OpaqueNodePtr,
};
use crate::raw::{match_concrete_node_ptr, InnerNode, InnerNodeCommon};
pub trait Visitable<K, T, const PREFIX_LEN: usize> {
fn super_visit_with<V: Visitor<K, T, PREFIX_LEN>>(&self, visitor: &mut V) -> V::Output;
fn visit_with<V: Visitor<K, T, PREFIX_LEN>>(&self, visitor: &mut V) -> V::Output {
self.super_visit_with(visitor)
}
}
impl<K, T, const PREFIX_LEN: usize> Visitable<K, T, PREFIX_LEN>
for OpaqueNodePtr<K, T, PREFIX_LEN>
{
fn super_visit_with<V: Visitor<K, T, PREFIX_LEN>>(&self, visitor: &mut V) -> V::Output {
match_concrete_node_ptr! {
match (self.to_node_ptr()) {
InnerNode(inner) => inner.visit_with(visitor),
LeafNode(inner) => inner.visit_with(visitor),
}
}
}
}
impl<K, T, const PREFIX_LEN: usize, N: Node<PREFIX_LEN> + Visitable<K, T, PREFIX_LEN>>
Visitable<K, T, PREFIX_LEN> for NodePtr<PREFIX_LEN, N>
{
fn super_visit_with<V: Visitor<K, T, PREFIX_LEN>>(&self, visitor: &mut V) -> V::Output {
unsafe { self.as_ref().visit_with(visitor) }
}
}
impl<K, T, const PREFIX_LEN: usize> Visitable<K, T, PREFIX_LEN> for InnerNode4<K, T, PREFIX_LEN> {
fn super_visit_with<V: Visitor<K, T, PREFIX_LEN>>(&self, visitor: &mut V) -> V::Output {
combine_inner_node_child_output(self.iter(), visitor)
}
fn visit_with<V: Visitor<K, T, PREFIX_LEN>>(&self, visitor: &mut V) -> V::Output {
visitor.visit_inner_node(self)
}
}
impl<K, T, const PREFIX_LEN: usize> Visitable<K, T, PREFIX_LEN> for InnerNode16<K, T, PREFIX_LEN> {
fn super_visit_with<V: Visitor<K, T, PREFIX_LEN>>(&self, visitor: &mut V) -> V::Output {
combine_inner_node_child_output(self.iter(), visitor)
}
fn visit_with<V: Visitor<K, T, PREFIX_LEN>>(&self, visitor: &mut V) -> V::Output {
visitor.visit_inner_node(self)
}
}
impl<K, T, const PREFIX_LEN: usize> Visitable<K, T, PREFIX_LEN> for InnerNode48<K, T, PREFIX_LEN> {
fn super_visit_with<V: Visitor<K, T, PREFIX_LEN>>(&self, visitor: &mut V) -> V::Output {
combine_inner_node_child_output(self.iter(), visitor)
}
fn visit_with<V: Visitor<K, T, PREFIX_LEN>>(&self, visitor: &mut V) -> V::Output {
visitor.visit_inner_node(self)
}
}
impl<K, T, const PREFIX_LEN: usize> Visitable<K, T, PREFIX_LEN>
for InnerNodeDirect<K, T, PREFIX_LEN>
{
fn super_visit_with<V: Visitor<K, T, PREFIX_LEN>>(&self, visitor: &mut V) -> V::Output {
combine_inner_node_child_output(self.iter(), visitor)
}
fn visit_with<V: Visitor<K, T, PREFIX_LEN>>(&self, visitor: &mut V) -> V::Output {
visitor.visit_inner_node(self)
}
}
impl<K, T, const PREFIX_LEN: usize> Visitable<K, T, PREFIX_LEN> for LeafNode<K, T, PREFIX_LEN> {
fn super_visit_with<V: Visitor<K, T, PREFIX_LEN>>(&self, visitor: &mut V) -> V::Output {
visitor.default_output()
}
fn visit_with<V: Visitor<K, T, PREFIX_LEN>>(&self, visitor: &mut V) -> V::Output {
visitor.visit_leaf(self)
}
}
pub trait Visitor<K, V, const PREFIX_LEN: usize>: Sized {
type Output;
fn default_output(&self) -> Self::Output;
fn combine_output(&self, o1: Self::Output, o2: Self::Output) -> Self::Output;
fn visit_inner_node<N>(&mut self, t: &N) -> Self::Output
where
N: InnerNode<PREFIX_LEN, Key = K, Value = V> + Visitable<K, V, PREFIX_LEN>,
{
t.super_visit_with(self)
}
fn visit_leaf(&mut self, t: &LeafNode<K, V, PREFIX_LEN>) -> Self::Output {
t.super_visit_with(self)
}
}
fn combine_inner_node_child_output<K, T, const PREFIX_LEN: usize, V: Visitor<K, T, PREFIX_LEN>>(
mut iter: impl Iterator<Item = (u8, OpaqueNodePtr<K, T, PREFIX_LEN>)>,
visitor: &mut V,
) -> V::Output {
if let Some((_, first)) = iter.next() {
let mut accum = first.visit_with(visitor);
for (_, child) in iter {
let output = child.visit_with(visitor);
accum = visitor.combine_output(accum, output);
}
accum
} else {
visitor.default_output()
}
}