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
}
}