#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Mult13P1 {
state: u8,
}
impl Default for Mult13P1 {
fn default() -> Self {
Self::new(Self::DEFAULT_SEED)
}
}
impl Mult13P1 {
const DEFAULT_SEED: u8 = 0xDE;
}
impl Mult13P1 {
#[inline]
#[must_use]
pub const fn new(seed: u8) -> Self {
Self { state: seed }
}
#[inline(always)]
#[must_use]
pub const fn current_u8(&self) -> u8 {
self.state
}
#[inline]
#[must_use]
pub fn next_u8(&mut self) -> u8 {
let n = self.state;
let n_times_2_pow_2 = n << 2;
let n_times_2_pow_3 = n << 3;
self.state = n
.wrapping_add(n_times_2_pow_2)
.wrapping_add(n_times_2_pow_3)
.wrapping_add(1);
self.state
}
#[inline]
#[must_use]
pub const fn next_new(&self) -> Self {
let mut state = self.state;
let n_times_2_pow_2 = state << 2;
let n_times_2_pow_3 = state << 3;
state += n_times_2_pow_2 + n_times_2_pow_3 + 1;
Self { state }
}
}
impl Mult13P1 {
#[inline]
pub const fn new1_u8(seed: u8) -> Self {
Self::new(seed)
}
}
#[cfg(feature = "rand_core")]
#[cfg_attr(feature = "nightly", doc(cfg(feature = "rand_core")))]
mod impl_rand {
use super::Mult13P1;
use rand_core::{Error, RngCore, SeedableRng};
impl RngCore for Mult13P1 {
fn next_u32(&mut self) -> u32 {
u32::from_le_bytes([
self.next_u8(),
self.next_u8(),
self.next_u8(),
self.next_u8(),
])
}
fn next_u64(&mut self) -> u64 {
u64::from_le_bytes([
self.next_u8(),
self.next_u8(),
self.next_u8(),
self.next_u8(),
self.next_u8(),
self.next_u8(),
self.next_u8(),
self.next_u8(),
])
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
for byte in dest {
*byte = self.next_u8();
}
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
self.fill_bytes(dest);
Ok(())
}
}
impl SeedableRng for Mult13P1 {
type Seed = [u8; 1];
fn from_seed(seed: Self::Seed) -> Self {
Self::new(seed[0])
}
}
}