pub trait Process<X: Copy, Y = X> {
fn process(&mut self, x: X) -> Y;
fn block(&mut self, x: &[X], y: &mut [Y]) {
debug_assert_eq!(x.len(), y.len());
for (x, y) in x.iter().zip(y) {
*y = self.process(*x);
}
}
}
pub trait Inplace<X: Copy>: Process<X> {
fn inplace(&mut self, xy: &mut [X]) {
for xy in xy.iter_mut() {
*xy = self.process(*xy);
}
}
}
pub trait SplitProcess<X: Copy, Y = X, S: ?Sized = ()> {
fn process(&self, state: &mut S, x: X) -> Y;
fn block(&self, state: &mut S, x: &[X], y: &mut [Y]) {
debug_assert_eq!(x.len(), y.len());
for (x, y) in x.iter().zip(y) {
*y = self.process(state, *x);
}
}
}
pub trait SplitInplace<X: Copy, S: ?Sized = ()>: SplitProcess<X, X, S> {
fn inplace(&self, state: &mut S, xy: &mut [X]) {
for xy in xy.iter_mut() {
*xy = self.process(state, *xy);
}
}
}
impl<X: Copy, Y, T: Process<X, Y>> Process<X, Y> for &mut T {
fn process(&mut self, x: X) -> Y {
T::process(self, x)
}
fn block(&mut self, x: &[X], y: &mut [Y]) {
T::block(self, x, y)
}
}
impl<X: Copy, T: Inplace<X>> Inplace<X> for &mut T {
fn inplace(&mut self, xy: &mut [X]) {
T::inplace(self, xy)
}
}
impl<X: Copy, Y, S: ?Sized, T: SplitProcess<X, Y, S>> SplitProcess<X, Y, S> for &T {
fn process(&self, state: &mut S, x: X) -> Y {
T::process(self, state, x)
}
fn block(&self, state: &mut S, x: &[X], y: &mut [Y]) {
T::block(self, state, x, y)
}
}
impl<X: Copy, S: ?Sized, T: SplitInplace<X, S>> SplitInplace<X, S> for &T {
fn inplace(&self, state: &mut S, xy: &mut [X]) {
T::inplace(self, state, xy)
}
}
impl<X: Copy, Y, S: ?Sized, T: SplitProcess<X, Y, S>> SplitProcess<X, Y, S> for &mut T {
fn process(&self, state: &mut S, x: X) -> Y {
T::process(self, state, x)
}
fn block(&self, state: &mut S, x: &[X], y: &mut [Y]) {
T::block(self, state, x, y)
}
}
impl<X: Copy, S: ?Sized, T: SplitInplace<X, S>> SplitInplace<X, S> for &mut T {
fn inplace(&self, state: &mut S, xy: &mut [X]) {
T::inplace(self, state, xy)
}
}
pub struct FnProcess<F>(pub F);
impl<F: FnMut(X) -> Y, X: Copy, Y> Process<X, Y> for FnProcess<F> {
fn process(&mut self, x: X) -> Y {
(self.0)(x)
}
}
impl<F, X: Copy> Inplace<X> for FnProcess<F> where Self: Process<X> {}
pub struct FnSplitProcess<F>(pub F);
impl<F: Fn(&mut S, X) -> Y, X: Copy, Y, S> SplitProcess<X, Y, S> for FnSplitProcess<F> {
fn process(&self, state: &mut S, x: X) -> Y {
(self.0)(state, x)
}
}
impl<F, X: Copy, S> SplitInplace<X, S> for FnSplitProcess<F> where Self: SplitProcess<X, X, S> {}