randomize 2.2.0

A dead simple to use randomization library for rust.
Documentation
//! Module for PCGs that use `PhantomData` to set their stream.
//!
//! This works just like the `Pick` flavor of PCGs, except that instead of
//! storing a stream value along with the state there's a PhantomData typenum
//! that bakes some particular add constant into the generation code. If you
//! have just one generator it makes no difference. If you have more than one
//! generator is starts to be a space savings, at the expense that you can no
//! longer pick your stream at runtime.
//!
//! If you get a horribly nasty looking type error while trying to make one of
//! these things, it's probably because you picked a typenum phantom that's not
//! an odd number. You have to pick an odd number.

use super::*;

use core::{marker::PhantomData, ops::BitAnd};
use typenum::{consts::U1, Unsigned};

const DEFAULT_PHANTOM_SEED: u128 = 245720598905631564143578724636268694099;

/// A PCG with 8 bits of state, phantom stream
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct PCGPhantomU8<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  state: u8,
  phantom: PhantomData<P>,
}
impl<P> PCGPhantomU8<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  /// Seeds the generator
  pub fn seed(seed: u8) -> Self {
    let mut out = Self {
      state: 0,
      phantom: PhantomData,
    };
    let inc = unsafe { NonZeroU8::new_unchecked(P::U8) };
    out.state = lcg8(out.state, PCG_DEFAULT_MULTIPLIER_8, inc);
    out.state = out.state.wrapping_add(seed);
    out.state = lcg8(out.state, PCG_DEFAULT_MULTIPLIER_8, inc);
    out
  }
  /// Gives a generator of the exact values you put in
  pub const fn exact(state: u8) -> Self {
    Self { state, phantom: PhantomData }
  }
  /// Gives the next same-size output.
  pub fn next_u8(&mut self) -> u8 {
    let output = rxs_m_xs_8_8(self.state);
    let inc = unsafe { NonZeroU8::new_unchecked(P::U8) };
    let next_state = lcg8(self.state, PCG_DEFAULT_MULTIPLIER_8, inc);
    self.state = next_state;
    output
  }
}
impl<P> From<u64> for PCGPhantomU8<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  fn from(seed: u64) -> Self {
    Self::seed(seed as u8)
  }
}
impl<P> Default for PCGPhantomU8<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  fn default() -> Self {
    Self::seed(DEFAULT_PHANTOM_SEED as u8)
  }
}

/// A PCG with 16 bits of state, phantom stream
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct PCGPhantomU16<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  state: u16,
  phantom: PhantomData<P>,
}
impl<P> PCGPhantomU16<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  /// Seeds the generator
  pub fn seed(seed: u16) -> Self {
    let mut out = Self {
      state: 0,
      phantom: PhantomData,
    };
    let inc = unsafe { NonZeroU16::new_unchecked(P::U16) };
    out.state = lcg16(out.state, PCG_DEFAULT_MULTIPLIER_16, inc);
    out.state = out.state.wrapping_add(seed);
    out.state = lcg16(out.state, PCG_DEFAULT_MULTIPLIER_16, inc);
    out
  }
  /// Gives a generator of the exact values you put in
  pub const fn exact(state: u16) -> Self {
    Self { state, phantom: PhantomData }
  }
  /// Gives the next half-size output, using rotation
  pub fn next_u8(&mut self) -> u8 {
    let inc = unsafe { NonZeroU16::new_unchecked(P::U16) };
    let output = xsh_rr_16_8(self.state);
    let next_state = lcg16(self.state, PCG_DEFAULT_MULTIPLIER_16, inc);
    self.state = next_state;
    output
  }
  /// Gives the next half-size output, using a shift
  pub fn next_u8shift(&mut self) -> u8 {
    let inc = unsafe { NonZeroU16::new_unchecked(P::U16) };
    let output = xsh_rs_16_8(self.state);
    let next_state = lcg16(self.state, PCG_DEFAULT_MULTIPLIER_16, inc);
    self.state = next_state;
    output
  }
  /// Gives the next same-size output.
  pub fn next_u16(&mut self) -> u16 {
    let inc = unsafe { NonZeroU16::new_unchecked(P::U16) };
    let output = rxs_m_xs_16_16(self.state);
    let next_state = lcg16(self.state, PCG_DEFAULT_MULTIPLIER_16, inc);
    self.state = next_state;
    output
  }
}
impl<P> From<u64> for PCGPhantomU16<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  fn from(seed: u64) -> Self {
    Self::seed(seed as u16)
  }
}
impl<P> Default for PCGPhantomU16<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  fn default() -> Self {
    Self::seed(DEFAULT_PHANTOM_SEED as u16)
  }
}

/// A PCG with 32 bits of state, phantom stream
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct PCGPhantomU32<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  state: u32,
  phantom: PhantomData<P>,
}
impl<P> PCGPhantomU32<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  /// Seeds the generator
  pub fn seed(seed: u32) -> Self {
    let mut out = Self {
      state: 0,
      phantom: PhantomData,
    };
    let inc = unsafe { NonZeroU32::new_unchecked(P::U32) };
    out.state = lcg32(out.state, PCG_DEFAULT_MULTIPLIER_32, inc);
    out.state = out.state.wrapping_add(seed);
    out.state = lcg32(out.state, PCG_DEFAULT_MULTIPLIER_32, inc);
    out
  }
  /// Gives a generator of the exact values you put in
  pub const fn exact(state: u32) -> Self {
    Self { state, phantom: PhantomData }
  }
  /// Gives the next half-size output, using rotation
  pub fn next_u16(&mut self) -> u16 {
    let inc = unsafe { NonZeroU32::new_unchecked(P::U32) };
    let output = xsh_rr_32_16(self.state);
    let next_state = lcg32(self.state, PCG_DEFAULT_MULTIPLIER_32, inc);
    self.state = next_state;
    output
  }
  /// Gives the next half-size output, using a shift
  pub fn next_u16shift(&mut self) -> u16 {
    let inc = unsafe { NonZeroU32::new_unchecked(P::U32) };
    let output = xsh_rs_32_16(self.state);
    let next_state = lcg32(self.state, PCG_DEFAULT_MULTIPLIER_32, inc);
    self.state = next_state;
    output
  }
  /// Gives the next same-size output.
  pub fn next_u32(&mut self) -> u32 {
    let inc = unsafe { NonZeroU32::new_unchecked(P::U32) };
    let output = rxs_m_xs_32_32(self.state);
    let next_state = lcg32(self.state, PCG_DEFAULT_MULTIPLIER_32, inc);
    self.state = next_state;
    output
  }
}
impl<P> From<u64> for PCGPhantomU32<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  fn from(seed: u64) -> Self {
    Self::seed(seed as u32)
  }
}
impl<P> Default for PCGPhantomU32<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  fn default() -> Self {
    Self::seed(DEFAULT_PHANTOM_SEED as u32)
  }
}

/// A PCG with 64 bits of state, phantom stream
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct PCGPhantomU64<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  state: u64,
  phantom: PhantomData<P>,
}
impl<P> PCGPhantomU64<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  /// Seeds the generator
  pub fn seed(seed: u64) -> Self {
    let mut out = Self {
      state: 0,
      phantom: PhantomData,
    };
    let inc = unsafe { NonZeroU64::new_unchecked(P::U64) };
    out.state = lcg64(out.state, PCG_DEFAULT_MULTIPLIER_64, inc);
    out.state = out.state.wrapping_add(seed);
    out.state = lcg64(out.state, PCG_DEFAULT_MULTIPLIER_64, inc);
    out
  }
  /// Gives a generator of the exact values you put in
  pub const fn exact(state: u64) -> Self {
    Self { state, phantom: PhantomData }
  }
  /// Gives the next half-size output, using rotation
  pub fn next_u32(&mut self) -> u32 {
    let inc = unsafe { NonZeroU64::new_unchecked(P::U64) };
    let output = xsh_rr_64_32(self.state);
    let next_state = lcg64(self.state, PCG_DEFAULT_MULTIPLIER_64, inc);
    self.state = next_state;
    output
  }
  /// Gives the next half-size output, using a shift
  pub fn next_u32shift(&mut self) -> u32 {
    let inc = unsafe { NonZeroU64::new_unchecked(P::U64) };
    let output = xsh_rs_64_32(self.state);
    let next_state = lcg64(self.state, PCG_DEFAULT_MULTIPLIER_64, inc);
    self.state = next_state;
    output
  }
  /// Gives the next half-size output, using xsl rr
  pub fn next_u32xslrr(&mut self) -> u32 {
    let inc = unsafe { NonZeroU64::new_unchecked(P::U64) };
    let output = xsl_rr_64_32(self.state);
    let next_state = lcg64(self.state, PCG_DEFAULT_MULTIPLIER_64, inc);
    self.state = next_state;
    output
  }
  /// Gives the next same-size output.
  pub fn next_u64(&mut self) -> u64 {
    let inc = unsafe { NonZeroU64::new_unchecked(P::U64) };
    let output = rxs_m_xs_64_64(self.state);
    let next_state = lcg64(self.state, PCG_DEFAULT_MULTIPLIER_64, inc);
    self.state = next_state;
    output
  }
  /// Gives the next same-size output, using xsl rr rr
  pub fn next_u64xsl2rr(&mut self) -> u64 {
    let inc = unsafe { NonZeroU64::new_unchecked(P::U64) };
    let output = xsl_rr_rr_64_64(self.state);
    let next_state = lcg64(self.state, PCG_DEFAULT_MULTIPLIER_64, inc);
    self.state = next_state;
    output
  }
}
impl<P> From<u64> for PCGPhantomU64<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  fn from(seed: u64) -> Self {
    Self::seed(seed)
  }
}
impl<P> Default for PCGPhantomU64<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  fn default() -> Self {
    Self::seed(DEFAULT_PHANTOM_SEED as u64)
  }
}

/// A PCG with 128 bits of state, phantom stream
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct PCGPhantomU128<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  state: u128,
  phantom: PhantomData<P>,
}
impl<P> PCGPhantomU128<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  /// Seeds the generator
  pub fn seed(seed: u128) -> Self {
    let mut out = Self {
      state: 0,
      phantom: PhantomData,
    };
    let inc = unsafe { NonZeroU128::new_unchecked(P::U128) };
    out.state = lcg128(out.state, PCG_DEFAULT_MULTIPLIER_128, inc);
    out.state = out.state.wrapping_add(seed);
    out.state = lcg128(out.state, PCG_DEFAULT_MULTIPLIER_128, inc);
    out
  }
  /// Gives a generator of the exact values you put in
  pub const fn exact(state: u128) -> Self {
    Self { state, phantom: PhantomData }
  }
  /// Gives the next half-size output, using rotation
  pub fn next_u64(&mut self) -> u64 {
    let inc = unsafe { NonZeroU128::new_unchecked(P::U128) };
    let output = xsh_rr_128_64(self.state);
    let next_state = lcg128(self.state, PCG_DEFAULT_MULTIPLIER_128, inc);
    self.state = next_state;
    output
  }
  /// Gives the next half-size output, using a shift
  pub fn next_u64shift(&mut self) -> u64 {
    let inc = unsafe { NonZeroU128::new_unchecked(P::U128) };
    let output = xsh_rs_128_64(self.state);
    let next_state = lcg128(self.state, PCG_DEFAULT_MULTIPLIER_128, inc);
    self.state = next_state;
    output
  }
  /// Gives the next half-size output, using xsl rr
  pub fn next_u64xslrr(&mut self) -> u64 {
    let inc = unsafe { NonZeroU128::new_unchecked(P::U128) };
    let output = xsl_rr_128_64(self.state);
    let next_state = lcg128(self.state, PCG_DEFAULT_MULTIPLIER_128, inc);
    self.state = next_state;
    output
  }
  /// Gives the next same-size output.
  pub fn next_u128(&mut self) -> u128 {
    let inc = unsafe { NonZeroU128::new_unchecked(P::U128) };
    let output = rxs_m_xs_128_128(self.state);
    let next_state = lcg128(self.state, PCG_DEFAULT_MULTIPLIER_128, inc);
    self.state = next_state;
    output
  }
  /// Gives the next same-size output, using xsl rr rr
  pub fn next_u128xsl2rr(&mut self) -> u128 {
    let inc = unsafe { NonZeroU128::new_unchecked(P::U128) };
    let output = xsl_rr_rr_128_128(self.state);
    let next_state = lcg128(self.state, PCG_DEFAULT_MULTIPLIER_128, inc);
    self.state = next_state;
    output
  }
}
impl<P> From<u64> for PCGPhantomU128<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  fn from(seed: u64) -> Self {
    Self::seed(seed as u128)
  }
}
impl<P> Default for PCGPhantomU128<P>
where
  P: Unsigned + BitAnd<U1, Output = U1>,
{
  fn default() -> Self {
    Self::seed(DEFAULT_PHANTOM_SEED)
  }
}