use rand_core::{impls, RngCore};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct StepRng {
v: u64,
a: u64,
}
impl StepRng {
pub fn new(initial: u64, increment: u64) -> Self {
StepRng {
v: initial,
a: increment,
}
}
}
impl RngCore for StepRng {
#[inline]
fn next_u32(&mut self) -> u32 {
self.next_u64() as u32
}
#[inline]
fn next_u64(&mut self) -> u64 {
let res = self.v;
self.v = self.v.wrapping_add(self.a);
res
}
#[inline]
fn fill_bytes(&mut self, dst: &mut [u8]) {
impls::fill_bytes_via_next(self, dst)
}
}
#[cfg(test)]
mod tests {
#[cfg(any(feature = "alloc", feature = "serde"))]
use super::StepRng;
#[test]
#[cfg(feature = "serde")]
fn test_serialization_step_rng() {
let some_rng = StepRng::new(42, 7);
let de_some_rng: StepRng =
bincode::deserialize(&bincode::serialize(&some_rng).unwrap()).unwrap();
assert_eq!(some_rng.v, de_some_rng.v);
assert_eq!(some_rng.a, de_some_rng.a);
}
#[test]
#[cfg(feature = "alloc")]
fn test_bool() {
use crate::{distr::StandardUniform, Rng};
let rng = StepRng::new(0, 1 << 31);
let result: alloc::vec::Vec<bool> = rng.sample_iter(StandardUniform).take(6).collect();
assert_eq!(&result, &[false, true, false, true, false, true]);
}
}