use std::ops::RangeTo;
use crate::{BitBlock, HierarchyIndex};
use crate::const_utils::{ConstBool, ConstInteger, ConstTrue, IsConstTrue};
use crate::iter::Iter;
use crate::ops::Map;
use crate::utils::Borrowable;
use crate::utils::function::*;
pub trait HibitTreeTypes<'this, ImplicitBounds = &'this Self>{
type Data;
type DataUnchecked;
type DataOrDefault;
type Cursor: HibitTreeCursor<'this, Tree=Self>;
}
pub trait HibitTree: Sized + Borrowable<Borrowed=Self>
where
Self: for<'this> HibitTreeTypes<'this>,
{
const EXACT_HIERARCHY: bool;
type DefaultData: ConstBool;
type LevelCount: ConstInteger;
type LevelMask : BitBlock;
fn data(&self, index: &HierarchyIndex<Self::LevelMask, Self::LevelCount>)
-> Option<<Self as HibitTreeTypes<'_>>::Data>;
unsafe fn data_unchecked(&self, index: &HierarchyIndex<Self::LevelMask, Self::LevelCount>)
-> <Self as HibitTreeTypes<'_>>::DataUnchecked;
unsafe fn data_or_default(&self, index: &HierarchyIndex<Self::LevelMask, Self::LevelCount>)
-> <Self as HibitTreeTypes<'_>>::DataOrDefault;
#[inline]
fn get(&self, index: impl TryInto<HierarchyIndex<<Self as HibitTree>::LevelMask, Self::LevelCount>>)
-> Option<<Self as HibitTreeTypes<'_>>::Data>
{
let index = index.try_into().unwrap_or_else(|_| panic!());
self.data(&index)
}
#[inline]
unsafe fn get_unchecked(&self, index: impl TryInto<HierarchyIndex<<Self as HibitTree>::LevelMask, Self::LevelCount>>)
-> <Self as HibitTreeTypes<'_>>::DataUnchecked
{
let index = index.try_into().unwrap_unchecked();
self.data_unchecked(&index)
}
#[inline]
fn get_or_default(&self, index: impl TryInto<HierarchyIndex<<Self as HibitTree>::LevelMask, Self::LevelCount>>)
-> <Self as HibitTreeTypes<'_>>::DataOrDefault
where
Self::DefaultData: IsConstTrue
{
let index = index.try_into().unwrap_or_else(|_| panic!());
unsafe{ self.data_or_default(&index) }
}
#[inline]
fn iter(&self) -> Iter<Self>{
Iter::new(self)
}
#[inline]
fn map<F>(self, f: F) -> Map<Self, F>
where
for<'a, 'b> F:
UnaryFunction<<Self as HibitTreeTypes<'a>>::Data> +
UnaryFunction<<Self as HibitTreeTypes<'a>>::DataUnchecked> +
UnaryFunction<<Self as HibitTreeTypes<'a>>::DataOrDefault> +
UnaryFunction<<<Self as HibitTreeTypes<'a>>::Cursor as HibitTreeCursorTypes<'b>>::Data > +
UnaryFunction<<<Self as HibitTreeTypes<'a>>::Cursor as HibitTreeCursorTypes<'b>>::DataUnchecked > +
UnaryFunction<<<Self as HibitTreeTypes<'a>>::Cursor as HibitTreeCursorTypes<'b>>::DataOrDefault >,
{
crate::map(self, f)
}
#[inline]
fn map_w_default<F>(self, f: F) -> Map<Self, F, ConstTrue>
where
Self::DefaultData: IsConstTrue,
for<'a, 'b> F:
UnaryFunction<<Self as HibitTreeTypes<'a>>::Data> +
UnaryFunction<<Self as HibitTreeTypes<'a>>::DataUnchecked> +
UnaryFunction<<Self as HibitTreeTypes<'a>>::DataOrDefault> +
UnaryFunction<<<Self as HibitTreeTypes<'a>>::Cursor as HibitTreeCursorTypes<'b>>::Data > +
UnaryFunction<<<Self as HibitTreeTypes<'a>>::Cursor as HibitTreeCursorTypes<'b>>::DataUnchecked > +
UnaryFunction<<<Self as HibitTreeTypes<'a>>::Cursor as HibitTreeCursorTypes<'b>>::DataOrDefault >,
{
crate::map_w_default(self, f)
}
#[inline]
fn ref_map<F>(&self, f: F) -> Map<&Self, F>
where
for<'a, 'b> F:
UnaryFunction<<Self as HibitTreeTypes<'a>>::Data> +
UnaryFunction<<Self as HibitTreeTypes<'a>>::DataUnchecked> +
UnaryFunction<<Self as HibitTreeTypes<'a>>::DataOrDefault> +
UnaryFunction<<<Self as HibitTreeTypes<'a>>::Cursor as HibitTreeCursorTypes<'b>>::Data > +
UnaryFunction<<<Self as HibitTreeTypes<'a>>::Cursor as HibitTreeCursorTypes<'b>>::DataUnchecked > +
UnaryFunction<<<Self as HibitTreeTypes<'a>>::Cursor as HibitTreeCursorTypes<'b>>::DataOrDefault >,
{
crate::map(self, f)
}
#[inline]
fn ref_map_w_default<F>(&self, f: F) -> Map<&Self, F, ConstTrue>
where
Self::DefaultData: IsConstTrue,
for<'a, 'b> F:
UnaryFunction<<Self as HibitTreeTypes<'a>>::Data> +
UnaryFunction<<Self as HibitTreeTypes<'a>>::DataUnchecked> +
UnaryFunction<<Self as HibitTreeTypes<'a>>::DataOrDefault> +
UnaryFunction<<<Self as HibitTreeTypes<'a>>::Cursor as HibitTreeCursorTypes<'b>>::Data > +
UnaryFunction<<<Self as HibitTreeTypes<'a>>::Cursor as HibitTreeCursorTypes<'b>>::DataUnchecked > +
UnaryFunction<<<Self as HibitTreeTypes<'a>>::Cursor as HibitTreeCursorTypes<'b>>::DataOrDefault >,
{
crate::map_w_default(self, f)
}
#[inline]
fn index_range() -> RangeTo<usize> {
RangeTo{
end: <Self::LevelMask as BitBlock>::Size::VALUE.pow(Self::LevelCount::VALUE as _)
}
}
}
pub trait LazyHibitTree: HibitTree {
#[inline]
fn materialize<T>(self) -> T
where
Self: RegularHibitTree,
T: FromHibitTree<
Self,
LevelMask = Self::LevelMask,
LevelCount = Self::LevelCount,
>
{
T::from_tree(self)
}
#[inline]
fn materialize_filtered<T, F>(self, f: F) -> T
where
Self: RegularHibitTree,
T: FromHibitTree<
Self,
LevelMask = Self::LevelMask,
LevelCount = Self::LevelCount,
>,
for<'a, 'b> F: UnaryFunction<&'a HibitTreeData<'b, Self>, Output=bool>
{
T::from_filtered_tree(self, f)
}
}
pub trait FromHibitTree<From: RegularHibitTree>: HibitTree
where
From: RegularHibitTree<
LevelMask = Self::LevelMask,
LevelCount = Self::LevelCount,
>
{
fn from_tree(from: From) -> Self;
fn from_filtered_tree<F>(from: From, f: F) -> Self
where
for<'a, 'b> F: UnaryFunction<&'a HibitTreeData<'b, From>, Output=bool>;
}
pub trait HibitTreeCursorTypes<'this, ImplicitBounds = &'this Self>{
type Data;
type DataUnchecked;
type DataOrDefault;
}
pub trait HibitTreeCursor<'tree>
where
Self: for<'this> HibitTreeCursorTypes<'this>,
{
type Tree: HibitTree;
fn new(tree: &'tree Self::Tree) -> Self;
unsafe fn select_level_node<N: ConstInteger>(
&mut self,
tree: &'tree Self::Tree,
level_n: N,
level_index: usize,
) -> <Self::Tree as HibitTree>::LevelMask;
unsafe fn select_level_node_unchecked<N: ConstInteger>(
&mut self,
tree: &'tree Self::Tree,
level_n: N,
level_index: usize
) -> <Self::Tree as HibitTree>::LevelMask;
unsafe fn data<'a>(
&'a self,
tree: &'tree Self::Tree,
level_index: usize
) -> Option<<Self as HibitTreeCursorTypes<'a>>::Data>;
unsafe fn data_unchecked<'a>(
&'a self,
tree: &'tree Self::Tree,
level_index: usize
) -> <Self as HibitTreeCursorTypes<'a>>::DataUnchecked;
unsafe fn data_or_default<'a>(
&'a self,
tree: &'tree Self::Tree,
level_index: usize
) -> <Self as HibitTreeCursorTypes<'a>>::DataOrDefault;
}
pub type HibitTreeData<'a, T> = <T as HibitTreeTypes<'a>>::Data;
pub type MultiHibitTreeIterItem<'a, T> = <T as MultiHibitTreeTypes<'a>>::IterItem;
pub trait RegularHibitTreeTypes<'this, ImplicitBounds = &'this Self>
: HibitTreeTypes<'this, ImplicitBounds,
DataUnchecked = <Self as HibitTreeTypes<'this, ImplicitBounds>>::Data,
DataOrDefault = <Self as HibitTreeTypes<'this, ImplicitBounds>>::Data,
Cursor: for<'a> HibitTreeCursorTypes<'a,
Data = Self::Data,
DataUnchecked = Self::Data,
DataOrDefault = Self::Data,
>,
>
{}
pub trait RegularHibitTree: HibitTree
where
Self: for<'this> RegularHibitTreeTypes<'this>
{}
impl<'this, T> RegularHibitTreeTypes<'this> for T
where
T: HibitTreeTypes<'this,
DataUnchecked = <Self as HibitTreeTypes<'this>>::Data,
DataOrDefault = <Self as HibitTreeTypes<'this>>::Data,
Cursor: for<'a> HibitTreeCursorTypes<'a,
Data = Self::Data,
DataUnchecked = Self::Data,
DataOrDefault = Self::Data,
>,
>
{}
impl<T> RegularHibitTree for T
where
T: HibitTree,
T: for<'this> RegularHibitTreeTypes<'this>
{}
pub trait MultiHibitTreeTypes<'this, ImplicitBounds = &'this Self>
: HibitTreeTypes<'this, ImplicitBounds,
Data: Iterator<Item=Self::IterItem>,
DataUnchecked: Iterator<Item=Self::IterItem>,
DataOrDefault: Iterator<Item=Self::IterItem>,
Cursor: for<'a> HibitTreeCursorTypes<'a,
Data: Iterator<Item=Self::IterItem>,
DataUnchecked: Iterator<Item=Self::IterItem>,
DataOrDefault: Iterator<Item=Self::IterItem>,
>,
>
{
type IterItem;
}
pub trait MultiHibitTree: HibitTree
where
Self: for<'this> MultiHibitTreeTypes<'this>
{
}