#![doc(include = "../../doc/references.md")]
use crate::helpers::*;
use crate::numeric::*;
pub trait MulMagma: Sized + PartialEq {
fn mul(&self, other: &Self) -> Self;
}
pub trait MulMagmaLaws: MulMagma {
fn closure(&self, _x: &Self) -> bool {
true
}
}
impl<M: MulMagma> MulMagmaLaws for M {}
pub trait NumMulMagmaLaws: NumEq + MulMagma {
fn num_closure(&self, _x: &Self, _eps: &Self::Eps) -> bool {
true
}
}
impl<M: NumEq + MulMagma> NumMulMagmaLaws for M {}
macro_rules! integer_mul_magma {
($type:ty) => {
impl MulMagma for $type {
fn mul(&self, other: &Self) -> Self {
self.wrapping_mul(*other)
}
}
};
($type:ty, $($others:ty),+) => {
integer_mul_magma! {$type}
integer_mul_magma! {$($others),+}
};
}
integer_mul_magma! {
u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
}
macro_rules! float_mul_magma {
($type:ty) => {
impl MulMagma for $type {
fn mul(&self, other: &Self) -> Self {
*self * *other
}
}
};
($type:ty, $($others:ty),+) => {
float_mul_magma! {$type}
float_mul_magma! {$($others),+}
};
}
float_mul_magma! {
f32, f64
}
impl MulMagma for () {
fn mul(&self, _: &Self) -> Self {}
}
impl<A: MulMagma> MulMagma for (A,) {
fn mul(&self, other: &Self) -> Self {
(self.0.mul(&other.0), )
}
}
impl<A: MulMagma, B: MulMagma> MulMagma for (A, B) {
fn mul(&self, other: &Self) -> Self {
(self.0.mul(&other.0), self.1.mul(&other.1))
}
}
impl<A: MulMagma, B: MulMagma, C: MulMagma> MulMagma for (A, B, C) {
fn mul(&self, other: &Self) -> Self {
(self.0.mul(&other.0), self.1.mul(&other.1), self.2.mul(&other.2))
}
}
macro_rules! array_mul_magma {
($size:expr) => {
impl<T: Copy + MulMagma> MulMagma for [T; $size] {
fn mul(&self, other: &Self) -> Self {
self.map_with(other, &|x, y| x.mul(y))
}
}
};
($size:expr, $($others:expr),+) => {
array_mul_magma! {$size}
array_mul_magma! {$($others),+}
};
}
array_mul_magma! {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
}
#[cfg(test)]
mod tests;