use crate::primitives::{Present, Absent, Bool};
use crate::primitives::stream::{StreamEq, DefaultMaxDepth};
use super::node::{Empty, Leaf, Node16};
use super::capability::Capability;
use super::insert::With;
pub trait SetUnion<Other> {
type Out;
}
pub trait SetIntersect<Other> {
type Out;
}
pub trait SupersetOf<Other>: Sized {}
pub trait SetAnd<Other> {
type Out;
}
impl<T> SetUnion<T> for Empty {
type Out = T;
}
impl<A> SetUnion<Empty> for Leaf<A> {
type Out = Leaf<A>;
}
#[macros::node16]
impl<_Slots_> SetUnion<Empty> for _Node16_ {
type Out = Self;
}
impl<A, B> SetUnion<Leaf<B>> for Leaf<A>
where
B: Capability,
Leaf<A>: With<B>,
{
type Out = <Leaf<A> as With<B>>::Out;
}
#[macros::node16]
impl<A, _Slots_> SetUnion<_Node16_> for Leaf<A>
where
A: Capability,
_Node16_: With<A>,
{
type Out = <_Node16_ as With<A>>::Out;
}
#[macros::node16]
impl<A, _Slots_> SetUnion<Leaf<A>> for _Node16_
where
A: Capability,
Self: With<A>,
{
type Out = <Self as With<A>>::Out;
}
impl<T> SetIntersect<T> for Empty {
type Out = Empty;
}
impl<A> SetIntersect<Empty> for Leaf<A> {
type Out = Empty;
}
#[macros::node16]
impl<_Slots_> SetIntersect<Empty> for _Node16_ {
type Out = Empty;
}
impl<A, B> SetIntersect<Leaf<B>> for Leaf<A>
where
A: Capability,
B: Capability,
A::Stream: StreamEq<B::Stream, DefaultMaxDepth>,
<A::Stream as StreamEq<B::Stream, DefaultMaxDepth>>::Out: IntersectLeafHelper<A>,
{
type Out = <<A::Stream as StreamEq<B::Stream, DefaultMaxDepth>>::Out as IntersectLeafHelper<A>>::Out;
}
pub trait IntersectLeafHelper<A> {
type Out;
}
impl<A> IntersectLeafHelper<A> for Present {
type Out = Leaf<A>; }
impl<A> IntersectLeafHelper<A> for Absent {
type Out = Empty; }
impl<T> SupersetOf<Empty> for T {}
impl<A> SupersetOf<Leaf<A>> for Leaf<A> {}
use super::evaluate::{Evaluate, Has};
#[macros::node16]
impl<A, _Slots_> SupersetOf<Leaf<A>> for _Node16_
where
A: Capability,
Self: Evaluate<Has<A>, Out = Present>,
{}
impl<T> SetAnd<T> for Empty {
type Out = Empty;
}
impl<C, Other> SetAnd<Other> for Leaf<C>
where
Other: LeafAndDispatch<C>,
{
type Out = <Other as LeafAndDispatch<C>>::Out;
}
pub trait LeafAndDispatch<LLeafCap> {
type Out;
}
impl<C> LeafAndDispatch<C> for Empty {
type Out = Empty;
}
impl<C1, C2> LeafAndDispatch<C1> for Leaf<C2>
where
C1: Capability,
C2: Capability,
C1::Stream: StreamEq<C2::Stream, DefaultMaxDepth>,
{
type Out = <<C1::Stream as StreamEq<C2::Stream, DefaultMaxDepth>>::Out as Bool>::If<Leaf<C1>, Empty>;
}
#[macros::node16]
impl<C, _Slots_> LeafAndDispatch<C> for _Node16_ {
type Out = Empty;
}
#[macros::node16]
impl<R, _Slots_> SetAnd<R> for _Node16_
where
R: NodeAndDispatch<_Slots_>,
{
type Out = <R as NodeAndDispatch<_Slots_>>::Out;
}
pub trait NodeAndDispatch<L0, L1, L2, L3, L4, L5, L6, L7, L8, L9, LA, LB, LC, LD, LE, LF> {
type Out;
}
impl<L0, L1, L2, L3, L4, L5, L6, L7, L8, L9, LA, LB, LC, LD, LE, LF>
NodeAndDispatch<L0, L1, L2, L3, L4, L5, L6, L7, L8, L9, LA, LB, LC, LD, LE, LF>
for Empty
{
type Out = Empty;
}
impl<C, L0, L1, L2, L3, L4, L5, L6, L7, L8, L9, LA, LB, LC, LD, LE, LF>
NodeAndDispatch<L0, L1, L2, L3, L4, L5, L6, L7, L8, L9, LA, LB, LC, LD, LE, LF>
for Leaf<C>
{
type Out = Empty;
}
#[allow(clippy::type_complexity)]
impl<
R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, RA, RB, RC, RD, RE, RF,
L0, L1, L2, L3, L4, L5, L6, L7, L8, L9, LA, LB, LC, LD, LE, LF,
>
NodeAndDispatch<L0, L1, L2, L3, L4, L5, L6, L7, L8, L9, LA, LB, LC, LD, LE, LF>
for Node16<R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, RA, RB, RC, RD, RE, RF>
where
L0: SetAnd<R0>, L1: SetAnd<R1>, L2: SetAnd<R2>, L3: SetAnd<R3>,
L4: SetAnd<R4>, L5: SetAnd<R5>, L6: SetAnd<R6>, L7: SetAnd<R7>,
L8: SetAnd<R8>, L9: SetAnd<R9>, LA: SetAnd<RA>, LB: SetAnd<RB>,
LC: SetAnd<RC>, LD: SetAnd<RD>, LE: SetAnd<RE>, LF: SetAnd<RF>,
{
type Out = Node16<
<L0 as SetAnd<R0>>::Out, <L1 as SetAnd<R1>>::Out,
<L2 as SetAnd<R2>>::Out, <L3 as SetAnd<R3>>::Out,
<L4 as SetAnd<R4>>::Out, <L5 as SetAnd<R5>>::Out,
<L6 as SetAnd<R6>>::Out, <L7 as SetAnd<R7>>::Out,
<L8 as SetAnd<R8>>::Out, <L9 as SetAnd<R9>>::Out,
<LA as SetAnd<RA>>::Out, <LB as SetAnd<RB>>::Out,
<LC as SetAnd<RC>>::Out, <LD as SetAnd<RD>>::Out,
<LE as SetAnd<RE>>::Out, <LF as SetAnd<RF>>::Out,
>;
}