use super::op_add;
use super::super::traits::binop;
use super::super::traits::multiplicative;
use std::fmt::Debug;
use binop::{Associative, Commutative, Identity, Magma, PartialRecip, Recip};
use multiplicative::{MulAssoc, MulComm, MulRecip, One};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum OpMul<T> {
OpMulV,
_Marker(T),
}
pub use OpMul::OpMulV;
impl<T> Default for OpMul<T> {
fn default() -> Self { OpMulV }
}
use std::ops::Mul;
impl<T> Magma for OpMul<T>
where
T: Mul<Output = T> + Eq + Sized,
{
type Set = T;
fn op(&self, x: Self::Set, y: Self::Set) -> Self::Set { x * y }
}
impl<T> Identity for OpMul<T>
where
T: Mul<Output = T> + Eq + Sized + One,
{
fn id(&self) -> Self::Set { Self::Set::one() }
}
impl<T> PartialRecip for OpMul<T>
where
T: Mul<Output = T> + Eq + Sized + MulRecip<Output = T>,
{
fn partial_recip(&self, x: Self::Set) -> Option<Self::Set> {
Some(x.mul_recip())
}
}
impl<T> Recip for OpMul<T> where
T: Mul<Output = T> + Eq + Sized + MulRecip<Output = T>
{
}
impl<T> Associative for OpMul<T> where T: Mul<Output = T> + Eq + Sized + MulAssoc
{}
impl<T> Commutative for OpMul<T> where T: Mul<Output = T> + Eq + Sized + MulComm {}
use op_add::OpAdd;
macro_rules! impl_distributive {
( $T:ty ) => {
impl binop::Distributive<OpAdd<$T>> for OpMul<$T> {}
};
( $( $T:ty, )* ) => { $( impl_distributive!($T); )* };
}
impl_distributive! {
i8, i16, i32, i64, i128, isize,
u8, u16, u32, u64, u128, usize,
}