Skip to main content

nekolib/utils/
op_mul.rs

1//! 乗法に関する wrapper クラス。
2
3use 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/// 積を返す演算を持つ。
13///
14/// [`std::ops::Mul`](https://doc.rust-lang.org/std/ops/trait.Mul.html) により定義される。
15/// 単位元は [`One`]、逆元は [`MulRecip`] で定義する。
16/// 結合法則を満たすときは [`MulAssoc`]、交換法則を満たすときは [`MulComm`] を実装することで示す。
17///
18/// [`One`]: ../../traits/multiplicative/trait.One.html
19/// [`MulRecip`]: ../../traits/multiplicative/trait.MulRecip.html
20/// [`MulAssoc`]: ../../traits/multiplicative/trait.MulAssoc.html
21/// [`MulComm`]: ../../traits/multiplicative/trait.MulComm.html
22#[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}