use wrapn::{Wrap, wrap};
use crate::{_internal::impl_seed, rng::Rng};
#[repr(align(64))]
pub struct SplitMix64 {
pub(crate) s: Wrap<u64>,
}
impl SplitMix64 {
pub fn new(seed: u64) -> Self {
Self { s: wrap!(seed | 1) }
}
#[inline]
pub(crate) fn compute(mut z: u64) -> u64 {
z = (z ^ (z >> 30)).wrapping_mul(0xBF58476D1CE4E5B9);
z = (z ^ (z >> 27)).wrapping_mul(0x94D049BB133111EB);
z ^ (z >> 31)
}
}
impl_seed!(SplitMix64, 64);
impl Rng for SplitMix64 {
type Word = u64;
#[inline]
fn nextu(&mut self) -> u64 {
self.s += 0x9E3779B97F4A7C15;
Self::compute(self.s.value())
}
}
#[cfg(test)]
mod tests {
use super::*;
crate::safe_test!(SplitMix64);
}