use crate::{
edge::Edge,
phase::Phase,
};
use std::collections::BinaryHeap;
use super::{
arena::Arena,
error::{ArenaError, ArenaResult},
node_idx::NodeIdx,
util::deref,
};
pub use crate::new::arena::RmPol;
pub struct Forest<I, N, P, C> {
arena: Arena<I, N, P, C>,
roots: Vec<I>,
}
impl<I, N, P, C> Default for Forest<I, N, P, C>
where
I: NodeIdx,
N: Default
{
fn default() -> Self {
Self::with_capacity(128)
}
}
impl<I, N, P, C> Forest<I, N, P, C>
where
I: NodeIdx,
N: Default
{
pub fn with_capacity(cap: usize) -> Self {
Self {
arena: Arena::with_capacity(cap),
roots: Vec::with_capacity(512),
}
}
pub fn roots(&self) -> &[I] {
&self.roots
}
pub fn root(&self) -> I {
assert_eq!(self.roots.len(), 1, "Expected exactly 1 root node");
self.roots[0]
}
pub fn iter_roots(&self) -> NodeIter![Item = I] {
self.roots.iter().copied()
}
#[inline]
pub fn append_root(&mut self, data: N) -> I {
let root = self.add_node(data);
self.roots.push(root);
root
}
#[inline]
pub fn insert_root(&mut self, pos: usize, data: N) -> I {
let root = self.add_node(data);
self.roots.insert(pos, root);
root
}
fn register_root(&mut self, fidx: I) {
self.roots.push(fidx);
}
fn unregister_root(&mut self, fidx: I) {
self.roots = self.roots.drain(..)
.filter(|&root| root != fidx)
.collect();
}
#[inline]
pub fn clear_roots(&mut self) {
self.roots.clear();
}
#[inline]
pub fn count_roots(&self) -> usize {
self.roots.len()
}
pub fn add_node(&mut self, data: N) -> I {
self.arena.add_node(data)
}
#[must_use]
pub fn remove_tree(&mut self, fidx: I, rmpol: RmPol) -> ArenaResult<(), I> {
self.arena.remove_tree(fidx, rmpol)
}
pub fn append_edge(&mut self, pidx: I, cidx: I, pdata: P, cdata: C) {
self.arena.append_edge(pidx, cidx, pdata, cdata)
}
pub fn add_edge(
&self,
(ppos, pidx, pdata): (impl Into<Option<usize>>, I, P),
(cpos, cidx, cdata): (impl Into<Option<usize>>, I, C),
) {
self.arena.add_edge((ppos, pidx, pdata), (cpos, cidx, cdata));
}
pub fn insert_edge(
&mut self,
(ppos, pidx, pdata): (usize, I, P),
(cpos, cidx, cdata): (usize, I, C),
) {
self.arena.insert_edge((ppos, pidx, pdata), (cpos, cidx, cdata));
}
pub fn remove_edges(&self, pidxs: &[I], cidxs: &[I]) -> ArenaResult<(), I> {
self.arena.remove_edges(pidxs, cidxs)
}
#[must_use]
pub fn remove_edge(
&mut self,
pidx: I,
cidx: I,
) -> ArenaResult<(P, C), I> {
self.arena.remove_edge(pidx, cidx)
}
pub fn parent_edge(&self, src: I, dst: I) -> ArenaResult<Edge<I, &P>, I> {
self.arena.parent_edge(src, dst)
}
pub fn child_edge(&self, src: I, dst: I) -> ArenaResult<Edge<I, &C>, I> {
self.arena.child_edge(src, dst)
}
#[must_use]
#[track_caller]
pub fn copy_tree(
&mut self,
dst_node: I,
(src, root): (&Self, I),
) -> ArenaResult<(), I>
where
N: Clone,
P: Clone + Default,
C: Clone + Default,
{
self.arena.copy_tree(dst_node, (&src.arena, root))
}
#[must_use]
#[rustfmt::skip]
pub fn move_tree(&self, parent: I, root: I) -> ArenaResult<(), I>
where
C: Default,
P: Default,
{
self.arena.move_tree(parent, root)
}
#[must_use]
pub fn replace_tree(&self, target: I, root: I) -> ArenaResult<(), I> {
self.arena.replace_tree(target, root)
}
pub fn parent_ordinal(&self, pidx: I, cidx: I) -> ArenaResult<usize, I> {
self.arena.parent_ordinal(pidx, cidx)
}
pub fn child_ordinal(&self, pidx: I, cidx: I) -> ArenaResult<usize, I> {
self.arena.child_ordinal(pidx, cidx)
}
pub fn self_or_ancestors_of(&self, nidx: I) -> NodeIter![Item = I] {
self.arena.self_or_ancestors_of(nidx)
}
#[inline(always)]
pub fn ancestors_of(&self, nidx: I) -> NodeIter![Item = I] {
self.arena.ancestors_of(nidx)
}
#[inline(always)]
pub fn self_or_siblings_of(&self, nidx: I) -> NodeIter![Item = I] {
self.arena.self_or_siblings_of(nidx)
}
#[inline(always)]
pub fn siblings_of(&self, nidx: I) -> NodeIter![Item = I] {
self.arena.siblings_of(nidx)
}
#[inline(always)]
pub fn parents_of(&self, nidx: I) -> NodeIter![Item = I] {
self.arena.parents_of(nidx)
}
#[inline(always)]
pub fn children_of(&self, nidx: I) -> NodeIter![Item = I] {
self.arena.children_of(nidx)
}
#[inline(always)]
pub fn self_or_descendants_of(&self, nidx: I) -> NodeIter![Item = I] {
self.arena.self_or_descendants_of(nidx)
}
#[inline(always)]
pub fn descendants_of(&self, nidx: I) -> NodeIter![Item = I] {
self.arena.descendants_of(nidx)
}
#[inline(always)]
pub fn dfs_before(&self, start_idx: I) -> NodeIter![Item = I] {
self.arena.dfs_before(start_idx)
}
#[inline(always)]
pub fn dfs_after(&self, start_idx: I) -> NodeIter![Item = I] {
self.arena.dfs_after(start_idx)
}
pub fn dfs(&self, start_idx: I) -> NodeIter![Item = (I, Phase)] {
self.arena.dfs(start_idx)
}
pub fn bfs(&self, start_idx: I) -> NodeIter![Item = I] {
self.arena.bfs(start_idx)
}
}