use crate::*;
use num::{PrimInt, Unsigned};
use std::convert::{From, TryFrom};
use std::fmt::Debug;
use std::marker::PhantomData;
pub const U8: CheckedUints<u8> = CheckedUints {
phantom: PhantomData,
};
pub const U16: CheckedUints<u16> = CheckedUints {
phantom: PhantomData,
};
pub const U32: CheckedUints<u32> = CheckedUints {
phantom: PhantomData,
};
pub const U64: CheckedUints<u64> = CheckedUints {
phantom: PhantomData,
};
#[derive(Clone, Debug)]
pub struct CheckedUints<E>
where
E: PrimInt + Unsigned + Debug + From<u8> + TryFrom<usize>,
{
phantom: PhantomData<E>,
}
impl<E> Domain for CheckedUints<E>
where
E: PrimInt + Unsigned + Debug + From<u8> + TryFrom<usize>,
{
type Elem = E;
fn equals(&self, elem1: &Self::Elem, elem2: &Self::Elem) -> bool {
elem1 == elem2
}
}
impl<E> Semigroup for CheckedUints<E>
where
E: PrimInt + Unsigned + Debug + From<u8> + TryFrom<usize>,
{
fn mul(&self, elem1: &Self::Elem, elem2: &Self::Elem) -> Self::Elem {
elem1.checked_mul(elem2).unwrap()
}
}
impl<E> Monoid for CheckedUints<E>
where
E: PrimInt + Unsigned + Debug + From<u8> + TryFrom<usize>,
{
fn one(&self) -> Self::Elem {
1.into()
}
fn is_one(&self, elem: &Self::Elem) -> bool {
*elem == 1.into()
}
fn try_inv(&self, elem: &Self::Elem) -> Option<Self::Elem> {
if *elem == 1.into() {
Some(1.into())
} else {
None
}
}
fn invertible(&self, elem: &Self::Elem) -> bool {
*elem == 1.into()
}
}
impl<E> CommuntativeMonoid for CheckedUints<E>
where
E: PrimInt + Unsigned + Debug + From<u8> + TryFrom<usize>,
{
fn zero(&self) -> Self::Elem {
0.into()
}
fn is_zero(&self, elem: &Self::Elem) -> bool {
elem.is_zero()
}
fn add(&self, elem1: &Self::Elem, elem2: &Self::Elem) -> Self::Elem {
elem1.checked_add(elem2).unwrap()
}
}
impl<E> SemiRing for CheckedUints<E> where E: PrimInt + Unsigned + Debug + From<u8> + TryFrom<usize> {}
impl<E> PartialOrder for CheckedUints<E>
where
E: PrimInt + Unsigned + Debug + From<u8> + TryFrom<usize>,
{
fn leq(&self, elem1: &Self::Elem, elem2: &Self::Elem) -> bool {
*elem1 <= *elem2
}
}
impl<E> Lattice for CheckedUints<E>
where
E: PrimInt + Unsigned + Debug + From<u8> + TryFrom<usize>,
{
fn meet(&self, elem1: &Self::Elem, elem2: &Self::Elem) -> Self::Elem {
*elem1.min(elem2)
}
fn join(&self, elem1: &Self::Elem, elem2: &Self::Elem) -> Self::Elem {
*elem1.max(elem2)
}
}
impl<E> DistributiveLattice for CheckedUints<E> where
E: PrimInt + Unsigned + Debug + From<u8> + TryFrom<usize>
{
}