use core::ops::Add;
pub trait Sum<Output> {
fn zero() -> Output;
fn owned(a: Self) -> Output;
fn u_owned<U>(_: &mut U, a: Self) -> Output;
fn add(a: Output, b: Output) -> Output;
fn u_add<U>(_: &mut U, a: Output, b: Output) -> Output;
}
impl<X> Sum<X> for X
where
X: Default + Add<X, Output = X>,
{
fn zero() -> X {
X::default()
}
#[inline(always)]
fn owned(a: Self) -> X {
a
}
#[inline(always)]
fn u_owned<U>(_: &mut U, a: Self) -> X {
a
}
#[inline(always)]
fn add(a: X, b: X) -> X {
a + b
}
#[inline(always)]
fn u_add<U>(_: &mut U, a: X, b: X) -> X {
a + b
}
}
impl<'a, X> Sum<X> for &'a X
where
X: Default + Add<X, Output = X> + Copy,
&'a X: Add<&'a X, Output = X>,
{
fn zero() -> X {
X::default()
}
#[inline(always)]
fn owned(a: Self) -> X {
*a
}
#[inline(always)]
fn u_owned<U>(_: &mut U, a: Self) -> X {
*a
}
#[inline(always)]
fn add(a: X, b: X) -> X {
a + b
}
#[inline(always)]
fn u_add<U>(_: &mut U, a: X, b: X) -> X {
a + b
}
}
impl<'a, X> Sum<X> for &'a mut X
where
X: Default + Add<X, Output = X> + Copy,
&'a X: Add<&'a X, Output = X>,
{
fn zero() -> X {
X::default()
}
#[inline(always)]
fn owned(a: Self) -> X {
*a
}
#[inline(always)]
fn u_owned<U>(_: &mut U, a: Self) -> X {
*a
}
#[inline(always)]
fn add(a: X, b: X) -> X {
a + b
}
#[inline(always)]
fn u_add<U>(_: &mut U, a: X, b: X) -> X {
a + b
}
}