1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
use std::ops::{
    Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
};

pub trait Operator: Copy {}

#[derive(Copy, Clone)]
pub struct Additive {}

#[derive(Copy, Clone)]
pub struct Multiplicative {}

impl Operator for Additive {}

impl Operator for Multiplicative {}

pub trait ClosedAdd<Rhs = Self>: Add<Rhs, Output = Self> + AddAssign<Rhs> {}
pub trait ClosedSub<Rhs = Self>: Sub<Rhs, Output = Self> + SubAssign<Rhs> {}
pub trait ClosedMul<Rhs = Self>: Mul<Rhs, Output = Self> + MulAssign<Rhs> {}
pub trait ClosedDiv<Rhs = Self>: Div<Rhs, Output = Self> + DivAssign<Rhs> {}
pub trait ClosedRem<Rhs = Self>: Rem<Rhs, Output = Self> + RemAssign<Rhs> {}
pub trait ClosedNeg: Neg<Output = Self> {}

pub trait ClosedOps<Rhs = Self>:
    ClosedAdd<Rhs> + ClosedSub<Rhs> + ClosedMul<Rhs> + ClosedDiv<Rhs> + ClosedRem<Rhs>
{
}

impl<T, Rhs> ClosedAdd<Rhs> for T where T: Add<Rhs, Output = T> + AddAssign<Rhs> {}
impl<T, Rhs> ClosedSub<Rhs> for T where T: Sub<Rhs, Output = T> + SubAssign<Rhs> {}
impl<T, Rhs> ClosedMul<Rhs> for T where T: Mul<Rhs, Output = T> + MulAssign<Rhs> {}
impl<T, Rhs> ClosedDiv<Rhs> for T where T: Div<Rhs, Output = T> + DivAssign<Rhs> {}
impl<T, Rhs> ClosedRem<Rhs> for T where T: Rem<Rhs, Output = T> + RemAssign<Rhs> {}
impl<T> ClosedNeg for T where T: Neg<Output = T> {}
impl<T, Rhs> ClosedOps<Rhs> for T where
    T: ClosedAdd<Rhs> + ClosedSub<Rhs> + ClosedMul<Rhs> + ClosedDiv<Rhs> + ClosedRem<Rhs>
{
}