pub use std::ops::{Add, Sub, Neg};
pub use std::ops::{Mul, Div, Rem};
pub trait Inverse<O: Op> {
fn inv(self) -> Self;
}
pub fn inv<O: Op, M: Inverse<O>>(_o: O, m: M) -> M {
m.inv()
}
impl<T> Inverse<Additive> for T
where T: Neg<Output=T>
{
fn inv(self) -> Self {
-self
}
}
impl<T> Inverse<Multiplicative> for T
where T: Recip<Result=T>
{
fn inv(self) -> Self {
self.recip()
}
}
pub trait Recip {
type Result;
fn recip(self) -> Self::Result;
}
impl Recip for f32 { type Result = Self; #[inline] fn recip(self) -> f32 { 1.0 / self } }
impl Recip for f64 { type Result = Self; #[inline] fn recip(self) -> f64 { 1.0 / self } }
pub trait Op: Copy {
fn oper() -> Self;
}
#[derive(Clone, Copy)]
pub struct Additive;
impl Op for Additive {
fn oper() -> Self {
Additive
}
}
#[derive(Clone, Copy)]
pub struct Multiplicative;
impl Op for Multiplicative {
fn oper() -> Self {
Multiplicative
}
}