use orx_selfref_col::{
    references::iter::ArrayLeftMostPtrIter, MemoryReclaimer, NodePtr, Refs, RefsArrayLeftMost,
    RefsSingle, RefsVec, Variant,
};
pub trait TreeVariant:
    Variant<Ends = RefsSingle<Self>, Prev = RefsSingle<Self>, Next = Self::Children>
{
    type Reclaimer: MemoryReclaimer<Self>;
    type Children: RefsChildren<Self> + Refs;
}
pub trait RefsChildren<V: Variant> {
    type ChildrenPtrIter<'a>: ExactSizeIterator<Item = &'a NodePtr<V>>
        + DoubleEndedIterator
        + Default
    where
        V: 'a,
        Self: 'a;
    fn num_children(&self) -> usize;
    fn children_ptr(&self) -> Self::ChildrenPtrIter<'_>;
    fn get_ptr(&self, i: usize) -> Option<&NodePtr<V>>;
    fn push(&mut self, node_ptr: NodePtr<V>);
    fn insert(&mut self, position: usize, node_ptr: NodePtr<V>);
    fn replace_with(
        &mut self,
        old_node_ptr: &NodePtr<V>,
        new_node_ptr: NodePtr<V>,
    ) -> Option<usize>;
}
impl<V: Variant> RefsChildren<V> for RefsVec<V> {
    type ChildrenPtrIter<'a>
        = core::slice::Iter<'a, NodePtr<V>>
    where
        V: 'a,
        Self: 'a;
    #[inline(always)]
    fn num_children(&self) -> usize {
        self.len()
    }
    #[inline(always)]
    fn children_ptr(&self) -> Self::ChildrenPtrIter<'_> {
        self.iter()
    }
    #[inline(always)]
    fn get_ptr(&self, i: usize) -> Option<&NodePtr<V>> {
        self.get(i)
    }
    #[inline(always)]
    fn push(&mut self, node_ptr: NodePtr<V>) {
        self.push(node_ptr);
    }
    #[inline(always)]
    fn insert(&mut self, position: usize, node_ptr: NodePtr<V>) {
        RefsVec::insert(self, position, node_ptr);
    }
    #[inline(always)]
    fn replace_with(
        &mut self,
        old_node_ptr: &NodePtr<V>,
        new_node_ptr: NodePtr<V>,
    ) -> Option<usize> {
        RefsVec::replace_with(self, old_node_ptr, new_node_ptr)
    }
}
impl<const D: usize, V: Variant> RefsChildren<V> for RefsArrayLeftMost<D, V> {
    type ChildrenPtrIter<'a>
        = ArrayLeftMostPtrIter<'a, V>
    where
        V: 'a,
        Self: 'a;
    #[inline(always)]
    fn num_children(&self) -> usize {
        self.len()
    }
    #[inline(always)]
    fn children_ptr(&self) -> Self::ChildrenPtrIter<'_> {
        self.iter()
    }
    #[inline(always)]
    fn get_ptr(&self, i: usize) -> Option<&NodePtr<V>> {
        self.get(i)
    }
    #[inline(always)]
    fn push(&mut self, node_ptr: NodePtr<V>) {
        self.push(node_ptr);
    }
    #[inline(always)]
    fn insert(&mut self, position: usize, node_ptr: NodePtr<V>) {
        RefsArrayLeftMost::insert(self, position, node_ptr);
    }
    #[inline(always)]
    fn replace_with(
        &mut self,
        old_node_ptr: &NodePtr<V>,
        new_node_ptr: NodePtr<V>,
    ) -> Option<usize> {
        RefsArrayLeftMost::replace_with(self, old_node_ptr, new_node_ptr)
    }
}