#[inline(always)]
#[must_use]
pub(crate) const fn rapid_mum<const PROTECTED: bool>(a: u64, b: u64) -> (u64, u64) {
let r = (a as u128).wrapping_mul(b as u128);
if !PROTECTED {
(r as u64, (r >> 64) as u64)
} else {
(a ^ r as u64, b ^ (r >> 64) as u64)
}
}
#[inline(always)]
#[must_use]
pub(crate) const fn rapid_mix<const PROTECTED: bool>(a: u64, b: u64) -> u64 {
let r = (a as u128).wrapping_mul(b as u128);
if !PROTECTED {
(r as u64) ^ (r >> 64) as u64
} else {
(a ^ r as u64) ^ (b ^ (r >> 64) as u64)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rapid_mum() {
let (a, b) = rapid_mum::<false>(0, 0);
assert_eq!(a, 0);
assert_eq!(b, 0);
let (a, b) = rapid_mum::<false>(100, 100);
assert_eq!(a, 10000);
assert_eq!(b, 0);
let (a, b) = rapid_mum::<false>(u64::MAX, 2);
assert_eq!(a, u64::MAX - 1);
assert_eq!(b, 1);
}
}