use crate::infallible::fun::Map;
use crate::sizes::Size;
use crate::sizes::{Bin, One};
pub trait Xap: Copy + Send {
type I;
type O;
type Size: Size;
type Values: IntoIterator<Item = Self::O>;
fn xap(&self, i: Self::I) -> Self::Values;
fn map<Q, H>(self, h: H) -> MapOf<Self, Q, H>
where
H: Fn(Self::O) -> Q + Copy + Send,
{
<Self::Size as Size>::map(self, h)
}
fn inspect<H>(self, h: H) -> InsOf<Self, H>
where
H: Fn(&Self::O) + Copy + Send,
{
<Self::Size as Size>::inspect(self, h)
}
fn filter<H>(self, h: H) -> FilOf<Self, H>
where
H: Fn(&Self::O) -> bool + Copy + Send,
{
<Self::Size as Size>::filter(self, h)
}
fn filter_map<Q, H>(self, h: H) -> FilMapOf<Self, Q, H>
where
H: Fn(Self::O) -> Option<Q> + Copy + Send,
{
<Self::Size as Size>::filter_map(self, h)
}
fn flat_map<V, H>(self, h: H) -> FlatMapOf<Self, V, H>
where
V: IntoIterator,
H: Fn(Self::O) -> V + Copy + Send,
{
<Self::Size as Size>::flat_map(self, h)
}
fn flatten(self) -> FlattenOf<Self>
where
Self::O: IntoIterator,
{
<Self::Size as Size>::flatten(self)
}
fn mapped<M>(self, m: M) -> MappedOf<Self, M>
where
M: Map<I = Self::O>,
{
<Self::Size as Size>::mapped(self, m)
}
}
pub trait XapOne: Xap<Size = One> {
#[inline(always)]
fn one_value(&self, i: Self::I) -> Self::O {
unsafe { self.xap(i).into_iter().next().unwrap_unchecked() }
}
}
impl<X: Xap<Size = One>> XapOne for X {}
pub trait XapBin: Xap<Size = Bin> {
#[inline(always)]
fn bin_value(&self, i: Self::I) -> Option<Self::O> {
self.xap(i).into_iter().next()
}
}
impl<X: Xap<Size = Bin>> XapBin for X {}
pub type MapOf<X, Q, H> = <<X as Xap>::Size as Size>::Map<X, Q, H>;
pub type InsOf<X, H> = <<X as Xap>::Size as Size>::Inspect<X, H>;
pub type FilOf<X, H> = <<X as Xap>::Size as Size>::Filter<X, H>;
pub type FilMapOf<X, Q, H> = <<X as Xap>::Size as Size>::FilterMap<X, Q, H>;
pub type FlatMapOf<X, V, H> = <<X as Xap>::Size as Size>::FlatMap<X, V, H>;
pub type FlattenOf<X> = <<X as Xap>::Size as Size>::Flatten<X>;
pub type MappedOf<X, M> = <<X as Xap>::Size as Size>::Mapped<X, M>;