use crate::pitch::PitchTy;
pub trait PyMod<Rhs = Self> {
type Output;
fn pymod(&self, rhs: Rhs) -> Self::Output;
}
pub trait AbsMod<Rhs = Self> {
type Output;
fn absmod(&self, rhs: Rhs) -> Self::Output;
}
pub trait PitchMod {
const MOD: PitchTy = crate::MODULUS;
type Output;
fn pitchmod(&self) -> Self::Output;
}
impl<S> PitchMod for S
where
S: PyMod<PitchTy>,
{
type Output = <S as PyMod<PitchTy>>::Output;
fn pitchmod(&self) -> Self::Output {
self.pymod(Self::MOD)
}
}
use core::ops::{Add, Rem};
use num::traits::{Num, Signed};
impl<T> PyMod<T> for T
where
T: Copy + Num + PartialOrd + Signed,
{
type Output = T;
fn pymod(&self, y: T) -> Self::Output {
crate::pymod(*self, y)
}
}
impl<A, B, C> AbsMod<B> for A
where
A: Copy + Add<C, Output = C> + Rem<B, Output = C>,
B: Copy,
C: Add<B, Output = C> + Rem<B, Output = C> + Signed,
{
type Output = C;
fn absmod(&self, rhs: B) -> Self::Output {
(((*self % rhs) + rhs) % rhs).abs()
}
}