1use super::op_add;
4use super::super::traits::binop;
5use super::super::traits::multiplicative;
6
7use std::fmt::Debug;
8
9use binop::{Associative, Commutative, Identity, Magma, PartialRecip, Recip};
10use multiplicative::{MulAssoc, MulComm, MulRecip, One};
11
12#[derive(Clone, Copy, Debug, Eq, PartialEq)]
23pub enum OpMul<T> {
24 OpMulV,
25 _Marker(T),
26}
27pub use OpMul::OpMulV;
28
29impl<T> Default for OpMul<T> {
30 fn default() -> Self { OpMulV }
31}
32
33use std::ops::Mul;
34
35impl<T> Magma for OpMul<T>
36where
37 T: Mul<Output = T> + Eq + Sized,
38{
39 type Set = T;
40 fn op(&self, x: Self::Set, y: Self::Set) -> Self::Set { x * y }
41}
42impl<T> Identity for OpMul<T>
43where
44 T: Mul<Output = T> + Eq + Sized + One,
45{
46 fn id(&self) -> Self::Set { Self::Set::one() }
47}
48impl<T> PartialRecip for OpMul<T>
49where
50 T: Mul<Output = T> + Eq + Sized + MulRecip<Output = T>,
51{
52 fn partial_recip(&self, x: Self::Set) -> Option<Self::Set> {
53 Some(x.mul_recip())
54 }
55}
56impl<T> Recip for OpMul<T> where
57 T: Mul<Output = T> + Eq + Sized + MulRecip<Output = T>
58{
59}
60impl<T> Associative for OpMul<T> where T: Mul<Output = T> + Eq + Sized + MulAssoc
61{}
62impl<T> Commutative for OpMul<T> where T: Mul<Output = T> + Eq + Sized + MulComm {}
63
64use op_add::OpAdd;
65
66macro_rules! impl_distributive {
67 ( $T:ty ) => {
68 impl binop::Distributive<OpAdd<$T>> for OpMul<$T> {}
69 };
70 ( $( $T:ty, )* ) => { $( impl_distributive!($T); )* };
71}
72
73impl_distributive! {
74 i8, i16, i32, i64, i128, isize,
75 u8, u16, u32, u64, u128, usize,
76}