Last active
July 31, 2018 19:56
-
-
Save mverleg/c14d7fa93e3613fe8345e388222b193b to your computer and use it in GitHub Desktop.
Implement modulo operation for types that have remainder implemented (and add and clone), with specialization for copy types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Define a modulo operation, in the mathematical sense. | |
/// This differs from Rem because the result is always non-negative. | |
pub trait Modulo<T> { | |
type Output; | |
#[inline] | |
fn modulo(self, other: T) -> Self::Output; | |
} | |
/// Implement modulo operation for types that implement Rem, Add and Clone. | |
// Add and Clone are needed to shift the value by U if it is below zero. | |
// TODO @mverleg: describe constraint on output type | |
impl<U, T> Modulo<T> for U | |
where | |
T: Clone, | |
U: Rem<T>, | |
<U as Rem<T>>::Output: Add<T>, | |
<<U as Rem<T>>::Output as Add<T>>::Output: Rem<T> | |
{ | |
type Output = <<<U as Rem<T>>::Output as Add<T>>::Output as Rem<T>>::Output; | |
#[inline] | |
default fn modulo(self, other: T) -> Self::Output { | |
((self % other.clone()) + other.clone()) % other | |
} | |
} | |
/// Implement a potentially faster modulo operation for types that are Copy-able. | |
impl<U, T> Modulo<T> for U | |
where | |
T: Clone + Copy, | |
U: Rem<T>, | |
<U as Rem<T>>::Output: Add<T>, | |
<<U as Rem<T>>::Output as Add<T>>::Output: Rem<T> | |
{ | |
#[inline] | |
fn modulo(self, other: T) -> Self::Output { | |
((self % other) + other) % other | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment