use crate::infallible_use::fun::UMap;
use crate::sizes::{Bin, One, Size};
pub trait XapUse: Copy + Send {
type U;
type I;
type O;
type Size: Size;
type Values: IntoIterator<Item = Self::O>;
fn xap_use(&self, u: *mut Self::U, i: Self::I) -> Self::Values;
fn map<Q, H>(self, h: H) -> MapOf<Self, Q, H>
where
H: Fn(&mut Self::U, Self::O) -> Q + Copy + Send,
{
<Self::Size as Size>::u_map(self, h)
}
fn inspect<H>(self, h: H) -> InsOf<Self, H>
where
H: Fn(&mut Self::U, &Self::O) + Copy + Send,
{
<Self::Size as Size>::u_inspect(self, h)
}
fn filter<H>(self, h: H) -> FilOf<Self, H>
where
H: Fn(&mut Self::U, &Self::O) -> bool + Copy + Send,
{
<Self::Size as Size>::u_filter(self, h)
}
fn filter_map<Q, H>(self, h: H) -> FilMapOf<Self, Q, H>
where
H: Fn(&mut Self::U, Self::O) -> Option<Q> + Copy + Send,
{
<Self::Size as Size>::u_filter_map(self, h)
}
fn flat_map<V, H>(self, h: H) -> FlatMapOf<Self, V, H>
where
V: IntoIterator,
H: Fn(&mut Self::U, Self::O) -> V + Copy + Send,
{
<Self::Size as Size>::u_flat_map(self, h)
}
fn flatten(self) -> FlattenOf<Self>
where
Self::O: IntoIterator,
{
<Self::Size as Size>::u_flatten(self)
}
fn mapped<M>(self, m: M) -> MappedOf<Self, M>
where
M: UMap<U = Self::U, I = Self::O>,
{
<Self::Size as Size>::u_mapped(self, m)
}
}
pub trait XapUseOne: XapUse<Size = One> {
#[inline(always)]
fn one_value(&self, u: *mut Self::U, i: Self::I) -> Self::O {
unsafe { self.xap_use(u, i).into_iter().next().unwrap_unchecked() }
}
}
impl<X: XapUse<Size = One>> XapUseOne for X {}
pub trait XapUseBin: XapUse<Size = Bin> {
#[inline(always)]
fn bin_value(&self, u: *mut Self::U, i: Self::I) -> Option<Self::O> {
self.xap_use(u, i).into_iter().next()
}
}
impl<X: XapUse<Size = Bin>> XapUseBin for X {}
pub type MapOf<X, Q, H> = <<X as XapUse>::Size as Size>::UMap<X, Q, H>;
pub type InsOf<X, H> = <<X as XapUse>::Size as Size>::UInspect<X, H>;
pub type FilOf<X, H> = <<X as XapUse>::Size as Size>::UFilter<X, H>;
pub type FilMapOf<X, Q, H> = <<X as XapUse>::Size as Size>::UFilterMap<X, Q, H>;
pub type FlatMapOf<X, V, H> = <<X as XapUse>::Size as Size>::UFlatMap<X, V, H>;
pub type FlattenOf<X> = <<X as XapUse>::Size as Size>::UFlatten<X>;
pub type MappedOf<X, M> = <<X as XapUse>::Size as Size>::UMapped<X, M>;