use core::marker::PhantomData;
use crate::misc::Fun;
pub trait FoldSettings<T,D> : Copy {
fn op(&self, a: D, b: D) -> D;
fn delta_of(&self, t: &T) -> D;
fn empty(&self) -> D;
}
pub struct FoldSettingsStruct<T,D,OP : Fun<(D,D),D> + Copy, T2D: for<'a> Fun<&'a T,D> + Copy,EMPTY: Fun<(),D> + Copy> {
pub op_closure: OP,
pub t2d_closure: T2D,
pub empty_closure: EMPTY,
#[allow(missing_docs)]
pub _m: PhantomData<fn(T,D)->D>
}
impl<T, D, OP: Fun<(D,D),D> + Copy, T2D: for<'a> Fun<&'a T,D> + Copy, EMPTY: Fun<(),D> + Copy> Clone for FoldSettingsStruct<T, D, OP, T2D, EMPTY> {
fn clone(&self) -> Self {
Self { op_closure: self.op_closure.clone(), t2d_closure: self.t2d_closure.clone(), empty_closure: self.empty_closure.clone(), _m: self._m.clone() }
}
}
impl<T, D, OP: Fun<(D,D),D> + Copy, T2D: for<'a> Fun<&'a T,D> + Copy, EMPTY: Fun<(),D> + Copy> Copy for FoldSettingsStruct<T, D, OP, T2D, EMPTY> {}
impl<T, D, OP: Fun<(D,D),D> + Copy, T2D: for<'a> Fun<&'a T,D> + Copy, EMPTY: Fun<(),D> + Copy> FoldSettings<T,D> for FoldSettingsStruct<T, D, OP, T2D, EMPTY> {
fn op(&self, a: D, b: D) -> D {
self.op_closure.apply((a,b))
}
fn delta_of(&self, t: &T) -> D {
self.t2d_closure.apply(t)
}
fn empty(&self) -> D {
self.empty_closure.apply(())
}
}
#[derive(Clone,Copy)]
pub struct SettingsWithSize<S>(pub S);
impl<T,D: Clone, S: FoldSettings<T,D>> FoldSettings<T,(usize,D)> for SettingsWithSize<S> {
fn op(&self, (n,a): (usize,D), (m,b): (usize,D)) -> (usize,D) {
(n + m, self.0.op(a,b))
}
fn delta_of(&self, t: &T) -> (usize,D) {
(1,self.0.delta_of(t))
}
fn empty(&self) -> (usize,D) {
(0,self.0.empty())
}
}