use fastdivide;
pub trait Modulus<N, M>: Copy {
fn value(&self) -> M;
fn modulus(&self, x: N) -> N;
}
impl Modulus<u64, u32> for u32 {
#[inline]
fn value(&self) -> u32 {
*self
}
#[inline]
fn modulus(&self, x: u64) -> u64 {
x % u64::from(*self)
}
}
pub struct FastModulus6432 {
n: u32,
magic: fastdivide::DividerU64,
}
impl FastModulus6432 {
#[inline]
pub fn from(n: u32) -> FastModulus6432 {
FastModulus6432 {
n,
magic: fastdivide::DividerU64::divide_by(u64::from(n)),
}
}
}
impl<'a> Modulus<u64, u32> for &'a FastModulus6432 {
#[inline]
fn value(&self) -> u32 {
self.n
}
#[inline]
fn modulus(&self, x: u64) -> u64 {
let division = self.magic.divide(x);
x - division * u64::from(self.n)
}
}