use crate::{RandRangeU32, PCG32, PCG64};
use core::{char, fmt::Debug, hash::Hash, ops::*};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(not(feature = "serde"))]
use self::sealed::{Deserialize, Serialize};
mod sealed {
pub trait Sealed {}
pub trait Serialize {}
pub trait Deserialize<'a> {
fn make_rust_happy() -> &'a str {
""
}
}
}
impl self::sealed::Sealed for PCG32 {}
impl self::sealed::Sealed for PCG64 {}
#[cfg(not(feature = "serde"))]
impl Serialize for PCG32 {}
#[cfg(not(feature = "serde"))]
impl Serialize for PCG64 {}
#[cfg(not(feature = "serde"))]
impl Serialize for u64 {}
#[cfg(not(feature = "serde"))]
impl Serialize for u128 {}
#[cfg(not(feature = "serde"))]
impl<'a> Deserialize<'a> for PCG32 {}
#[cfg(not(feature = "serde"))]
impl<'a> Deserialize<'a> for PCG64 {}
#[cfg(not(feature = "serde"))]
impl<'a> Deserialize<'a> for u64 {}
#[cfg(not(feature = "serde"))]
impl<'a> Deserialize<'a> for u128 {}
#[doc(hidden)]
pub trait PCG:
self::sealed::Sealed
+ Sized
+ Eq
+ Hash
+ Debug
+ Clone
+ Default
+ Serialize
+ for<'a> Deserialize<'a>
{
type DoubleState: Copy
+ ShrAssign<u8>
+ Shl<u8, Output = Self::DoubleState>
+ BitAnd<Output = Self::DoubleState>
+ BitOrAssign
+ Sub<Output = Self::DoubleState>
+ Into<u128>
+ Debug
+ Eq
+ Hash
+ Default
+ Serialize
+ for<'a> Deserialize<'a>;
const ONE: Self::DoubleState;
const ZERO: Self::DoubleState;
const SZOF: usize;
fn next_wide(&mut self) -> Self::DoubleState;
}
impl PCG for PCG32 {
type DoubleState = u64;
const ONE: u64 = 1;
const ZERO: u64 = 0;
const SZOF: usize = 8;
#[inline]
fn next_wide(&mut self) -> u64 {
u64::from(self.next_u32())
}
}
impl PCG for PCG64 {
type DoubleState = u128;
const ONE: u128 = 1;
const ZERO: u128 = 0;
const SZOF: usize = 16;
#[inline]
fn next_wide(&mut self) -> u128 {
u128::from(self.next_u64())
}
}
#[derive(Clone, Eq, PartialEq, Hash, Debug, Default)]
pub struct AnyPCG<T: PCG> {
pcg: T,
extracted: <T as PCG>::DoubleState,
bits: u8, }
impl<T: PCG> AnyPCG<T> {
#[inline]
pub fn new(pcg: T) -> Self {
Self {
pcg,
extracted: <T as PCG>::ZERO,
bits: 0,
}
}
#[inline]
pub fn next_bool(&mut self) -> bool {
let next: u128 = self.next_bits(1).into();
0 != (next as u8)
}
#[inline]
pub fn next_char(&mut self) -> char {
const LIMIT: u32 = 128;
const SURR: u32 = 0xD800;
const DIFF: u32 = 0xE000 - SURR;
const MAX: u32 = (char::MAX as u32) - DIFF;
const BITS: u8 = 21;
const DIST: RandRangeU32 = RandRangeU32::new(0, MAX);
const _ASSERT_MIN_BIT_USAGE: () =
[(); 1][(((MAX > (1_u32 << (BITS - 1))) & (MAX <= (1_u32 << BITS))) as isize - 1) as usize];
let bits: u128 = self.next_bits(BITS).into();
let mut bits: u32 = bits as u32;
for _ in 0..LIMIT {
if let Some(c) = DIST.place_in_range(bits) {
let c = if c >= SURR { c + DIFF } else { c };
return char::from_u32(c).unwrap();
}
let bit = self.next_bool() as u32;
bits = (bit << (BITS - 1)) | (bits >> 1);
}
char::REPLACEMENT_CHARACTER
}
#[inline]
pub fn fill_bytes(&mut self, bytes: &mut [u8]) {
let mut i = bytes.chunks_exact_mut(4);
while let Some(chunk) = i.next() {
chunk.copy_from_slice(&self.next_u32().to_le_bytes());
}
for byte_mut in i.into_remainder() {
*byte_mut = self.next_u8();
}
}
#[inline]
pub fn next_u8(&mut self) -> u8 {
let next: u128 = self.next_bits(8).into();
next as u8
}
#[inline]
pub fn next_u16(&mut self) -> u16 {
let next: u128 = self.next_bits(16).into();
next as u16
}
#[inline]
pub fn next_u32(&mut self) -> u32 {
let next: u128 = self.next_bits(32).into();
next as u32
}
const NEW_BITS: u8 = (4 * <T as PCG>::SZOF) as u8;
const ONE: <T as PCG>::DoubleState = <T as PCG>::ONE;
fn next_bits(&mut self, n_bits: u8) -> <T as PCG>::DoubleState {
debug_assert!((n_bits > 0) & (n_bits <= Self::NEW_BITS));
if n_bits > self.bits {
self.extracted |= self.pcg.next_wide() << self.bits;
self.bits = self.bits.wrapping_add(Self::NEW_BITS);
}
let mask = (Self::ONE << n_bits) - Self::ONE;
let ret = self.extracted & mask;
self.extracted >>= n_bits;
self.bits -= n_bits;
ret
}
}
impl AnyPCG<PCG64> {
#[inline]
pub fn next_u64(&mut self) -> u64 {
let next: u128 = self.next_bits(64);
next as u64
}
#[inline]
pub fn next_u128(&mut self) -> u128 {
let lo = u128::from(self.next_u64());
let hi = u128::from(self.next_u64());
lo | (hi << 64)
}
}
impl AnyPCG<PCG32> {
#[inline]
pub fn next_u64(&mut self) -> u64 {
let lo = u64::from(self.next_u32());
let hi = u64::from(self.next_u32());
lo | (hi << 32)
}
#[inline]
pub fn next_u128(&mut self) -> u128 {
let lo = u128::from(self.next_u64());
let hi = u128::from(self.next_u64());
lo | (hi << 64)
}
}
#[cfg(feature = "serde")]
mod serde_impl {
use super::{AnyPCG, PCG};
use core::{fmt, marker::PhantomData};
use serde::{
de::{Error, MapAccess, SeqAccess, Unexpected, Visitor},
ser::SerializeStruct,
Deserialize, Deserializer, Serialize, Serializer,
};
const STRUCT_NAME: &str = "AnyPCG";
const GENR_FIELD_NAME: &str = "generator";
const EXTR_FIELD_NAME: &str = "extracted";
const BITS_FIELD_NAME: &str = "num_bits";
impl<T: PCG> Serialize for AnyPCG<T> {
fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut s = ser.serialize_struct(STRUCT_NAME, 3)?;
s.serialize_field(GENR_FIELD_NAME, &self.pcg)?;
s.serialize_field(EXTR_FIELD_NAME, &self.extracted)?;
s.serialize_field(BITS_FIELD_NAME, &self.bits)?;
s.end()
}
}
impl<'de, T: PCG> Deserialize<'de> for AnyPCG<T> {
fn deserialize<D>(de: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
de.deserialize_struct(
STRUCT_NAME,
&[GENR_FIELD_NAME, EXTR_FIELD_NAME, BITS_FIELD_NAME],
AnyPcgVis(PhantomData),
)
}
}
#[derive(Deserialize)]
#[serde(field_identifier)]
#[allow(non_camel_case_types)]
enum AnyPcgField {
generator,
extracted,
num_bits,
}
struct AnyPcgVis<T: PCG>(PhantomData<T>);
impl<'de, T: PCG> Visitor<'de> for AnyPcgVis<T> {
type Value = AnyPCG<T>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("struct AnyPCG")
}
fn visit_seq<V>(self, mut seq: V) -> Result<AnyPCG<T>, V::Error>
where
V: SeqAccess<'de>,
{
let genr = seq
.next_element()?
.ok_or_else(|| Error::invalid_length(0, &self))?;
let extr = seq
.next_element()?
.ok_or_else(|| Error::invalid_length(1, &self))?;
let bits = seq
.next_element()?
.ok_or_else(|| Error::invalid_length(2, &self))?;
if (bits as usize) > (8 * <T as PCG>::SZOF) {
return Err(Error::invalid_value(
Unexpected::Unsigned(bits as u64),
&"A number between 0 and the number of bits in `extracted`",
));
}
Ok(AnyPCG {
pcg: genr,
extracted: extr,
bits,
})
}
fn visit_map<V>(self, mut map: V) -> Result<AnyPCG<T>, V::Error>
where
V: MapAccess<'de>,
{
let mut genr = None;
let mut extr = None;
let mut bits = None;
while let Some(key) = map.next_key()? {
match key {
AnyPcgField::generator => {
if genr.is_some() {
return Err(Error::duplicate_field(GENR_FIELD_NAME));
}
genr = Some(map.next_value()?);
}
AnyPcgField::extracted => {
if extr.is_some() {
return Err(Error::duplicate_field(EXTR_FIELD_NAME));
}
extr = Some(map.next_value()?);
}
AnyPcgField::num_bits => {
if bits.is_some() {
return Err(Error::duplicate_field(GENR_FIELD_NAME));
}
bits = Some(map.next_value()?);
}
}
}
let pcg = genr.ok_or_else(|| Error::missing_field(GENR_FIELD_NAME))?;
let extracted = extr.ok_or_else(|| Error::missing_field(EXTR_FIELD_NAME))?;
let bits = bits.ok_or_else(|| Error::missing_field(BITS_FIELD_NAME))?;
if (bits as usize) > (8 * <T as PCG>::SZOF) {
return Err(Error::invalid_value(
Unexpected::Unsigned(bits as u64),
&"A number between 0 and the number of bits in `extracted`",
));
}
Ok(AnyPCG {
pcg,
extracted,
bits,
})
}
}
}
#[cfg(feature = "serde")]
pub use self::serde_impl::*;