use crate::{ConstInit, Own, whilst};
use crate::{Infallible, InfallibleResult, RandQualities, RandSeedable, RandTry};
#[doc = crate::_tags!(rand)]
#[doc = crate::_doc_meta!{location("num/prob/rand")}]
#[doc = crate::_doc_vendor!("8bit_rng")]
#[must_use]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Xyza8a {
x: u8,
y: u8,
z: u8,
a: u8,
}
impl Default for Xyza8a {
fn default() -> Self {
Self::INIT
}
}
impl ConstInit for Xyza8a {
const INIT: Self = Self::new(Self::DEFAULT_SEED);
}
impl Xyza8a {
#[doc(hidden)]
pub const DEFAULT_SEED: [u8; 4] = [0xDE, 0xFA, 0x00, 0x17];
}
impl Xyza8a {
pub const fn new(seeds: [u8; 4]) -> Self {
Self { x: seeds[0], y: seeds[1], z: seeds[2], a: seeds[3] }
}
#[must_use]
pub const fn inner_state(self) -> [u8; 4] {
[self.x, self.y, self.z, self.a]
}
pub const fn from_state(state: [u8; 4]) -> Self {
Self { x: state[0], y: state[1], z: state[2], a: state[3] }
}
#[must_use]
pub const fn current_u8(&self) -> u8 {
self.a
}
pub const fn next_u8(&mut self) -> u8 {
let t = self.x ^ (self.x << 4);
self.x = self.y;
self.y = self.z;
self.z = self.a;
self.a = self.z ^ t ^ (self.z >> 1) ^ (t << 1);
self.a
}
pub const fn peek_next_state(&self) -> Self {
let mut new = *self;
let t = new.x ^ (new.x << 4);
new.x = new.y;
new.y = new.z;
new.z = new.a;
new.a = new.z ^ t ^ (new.z >> 1) ^ (t << 1);
new
}
pub const fn own_next_u8(self) -> Own<Self, u8> {
let s = self.peek_next_state();
let v = s.current_u8();
Own::new(s, v)
}
pub const fn fill_bytes(&mut self, buffer: &mut [u8]) {
whilst! { i in 0..buffer.len(); {
buffer[i] = self.next_u8();
}}
}
}
impl Xyza8a {
pub const fn new1_u32(seed: u32) -> Self {
Self::new(seed.to_le_bytes())
}
pub const fn new2_u16(seeds: [u16; 2]) -> Self {
let [x, y] = seeds[0].to_le_bytes();
let [z, a] = seeds[1].to_le_bytes();
Self::new([x, y, z, a])
}
pub const fn new4_u8(seeds: [u8; 4]) -> Self {
Self::new(seeds)
}
fn next_u16(&mut self) -> u16 {
u16::from_le_bytes([self.next_u8(), self.next_u8()])
}
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(),
])
}
}
#[doc = crate::_tags!(rand)]
#[doc = crate::_doc_meta!{location("num/prob/rand")}]
#[doc = crate::_doc_vendor!("8bit_rng")]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Xyza8b {
x: u8,
y: u8,
z: u8,
a: u8,
}
impl Default for Xyza8b {
fn default() -> Self {
Self::INIT
}
}
impl ConstInit for Xyza8b {
const INIT: Self = Self::new(Self::DEFAULT_SEED);
}
impl Xyza8b {
#[doc(hidden)]
pub const DEFAULT_SEED: [u8; 4] = [0xDE, 0xFA, 0x00, 0x17];
}
impl Xyza8b {
pub const fn new(seeds: [u8; 4]) -> Self {
Self { x: seeds[0], y: seeds[1], z: seeds[2], a: seeds[3] }
}
#[must_use]
pub const fn inner_state(self) -> [u8; 4] {
[self.x, self.y, self.z, self.a]
}
pub const fn from_state(state: [u8; 4]) -> Self {
Self { x: state[0], y: state[1], z: state[2], a: state[3] }
}
pub const fn current_u8(&self) -> u8 {
self.a
}
pub const fn next_u8(&mut self) -> u8 {
let t = self.x ^ (self.x >> 1);
self.x = self.y;
self.y = self.z;
self.z = self.a;
self.a = self.z ^ t ^ (self.z >> 3) ^ (t << 1);
self.a
}
pub const fn peek_next_state(&self) -> Self {
let mut new = *self;
let t = new.x ^ (new.x >> 1);
new.x = new.y;
new.y = new.z;
new.z = new.a;
new.a = new.z ^ t ^ (new.z >> 3) ^ (t << 1);
new
}
pub const fn own_next_u8(self) -> Own<Self, u8> {
let s = self.peek_next_state();
let v = s.current_u8();
Own::new(s, v)
}
pub const fn fill_bytes(&mut self, buffer: &mut [u8]) {
whilst! { i in 0..buffer.len(); {
buffer[i] = self.next_u8();
}}
}
}
impl Xyza8b {
pub const fn new1_u32(seed: u32) -> Self {
Self::new(seed.to_le_bytes())
}
pub const fn new2_u16(seeds: [u16; 2]) -> Self {
let [x, y] = seeds[0].to_le_bytes();
let [z, b] = seeds[1].to_le_bytes();
Self::new([x, y, z, b])
}
pub const fn new4_u8(seeds: [u8; 4]) -> Self {
Self::new(seeds)
}
fn next_u16(&mut self) -> u16 {
u16::from_le_bytes([self.next_u8(), self.next_u8()])
}
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(),
])
}
}
crate::items! {
impl RandTry for Xyza8a {
type Error = Infallible;
const RAND_OUTPUT_BITS: u32 = 8;
const RAND_STATE_BITS: u32 = 32;
const RAND_QUALITIES: RandQualities = RandQualities::WEAK_PRNG;
fn rand_try_next_u8(&mut self) -> InfallibleResult<u8> { Ok(self.next_u8()) }
fn rand_try_next_u16(&mut self) -> InfallibleResult<u16> { Ok(self.next_u16()) }
fn rand_try_next_u32(&mut self) -> InfallibleResult<u32> { Ok(self.next_u32()) }
fn rand_try_next_u64(&mut self) -> InfallibleResult<u64> { Ok(self.next_u64()) }
fn rand_try_fill_bytes(&mut self, buffer: &mut [u8]) -> InfallibleResult<()> {
self.fill_bytes(buffer);
Ok(())
}
}
impl RandTry for Xyza8b {
type Error = Infallible;
const RAND_OUTPUT_BITS: u32 = 8;
const RAND_STATE_BITS: u32 = 32;
const RAND_QUALITIES: RandQualities = RandQualities::WEAK_PRNG;
fn rand_try_next_u8(&mut self) -> InfallibleResult<u8> { Ok(self.next_u8()) }
fn rand_try_next_u16(&mut self) -> InfallibleResult<u16> { Ok(self.next_u16()) }
fn rand_try_next_u32(&mut self) -> InfallibleResult<u32> { Ok(self.next_u32()) }
fn rand_try_next_u64(&mut self) -> InfallibleResult<u64> { Ok(self.next_u64()) }
fn rand_try_fill_bytes(&mut self, buffer: &mut [u8]) -> InfallibleResult<()> {
self.fill_bytes(buffer);
Ok(())
}
}
impl RandSeedable for Xyza8a {
type RandSeed = [u8; 4];
fn rand_from_seed(seed: Self::RandSeed) -> Self { Self::new(seed) }
}
impl RandSeedable for Xyza8b {
type RandSeed = [u8; 4];
#[inline(always)]
fn rand_from_seed(seed: Self::RandSeed) -> Self { Self::new(seed) }
}
}
crate::__impl_dep_rand_core!(Xyza8a);
crate::__impl_dep_rand_core!(Xyza8b);