randomize 2.2.0

A dead simple to use randomization library for rust.
Documentation
//! Different permutations that you might apply to an LCG output to make it a
//! PCG.
//!
//! * **XSH RR:** Fixed xorshift, random rotate
//!   * Gives the best combination of speed vs quality. If you're not sure what
//!     to use, default to using this permutation.
//! * **XSH RS:** Fixed xorshift, random shift
//!   * This is the next best for quality, and on some systems a random shift
//!     might be preferred over a random rotate.
//! * **RXS M XS:** Random xorshift, fixed multiply, fixed xorshift
//!   * The highest quality permutation with the slowest speed. If you're forced
//!     to keep an output size equal to your state size instead of keeping only
//!     the best bits, this is what you need.
//! * **XSL RR:** Xor high bits onto low bits, random rotate
//!   * A quick and dirty permutation for if your generator size is bigger than
//!     your machine's word size (eg: 64-bit state on a 32-bit machine).
//! * **XSL RR RR:** Xor high bits onto low bits, rotate the low bits, then
//!   rotate the high bits based on the low bits, and put it all back together
//!   * Similar to the other XSL option, all the operations take place at one
//!     size lower than the state size, so you can use this if your state is
//!     bigger than a machine word without much performance lost.
//!
//! The `RXS M XS` and `XSL RR RR` permutations have and output size _equal to
//! the input_.
//!
//! All the rest of them have an output size _equal to half the input_.
//!
//! * The constants involved change depending on the exact size of the type, so
//!   no permutations are defined for `usize`.
//! * The `XSL` permutations are only defined for inputs of `u64` and `u128`.
//! * Permutations that have a half-sized output aren't defined for `u8` inputs.
//! * Other than that, each permutation is defined for as many input types as
//!   possible.

/// XSH RR `u16` to `u8`
pub const fn xsh_rr_16_8(state: u16) -> u8 {
  ((((state >> 5) ^ state) >> 5) as u8).rotate_right((state >> 13) as u32)
}

/// XSH RR `u32` to `u16`
pub const fn xsh_rr_32_16(state: u32) -> u16 {
  ((((state >> 10) ^ state) >> 12) as u16).rotate_right((state >> 28) as u32)
}

/// XSH RR `u64` to `u32`
pub const fn xsh_rr_64_32(state: u64) -> u32 {
  ((((state >> 18) ^ state) >> 27) as u32).rotate_right((state >> 59) as u32)
}

/// XSH RR `u128` to `u64`
pub const fn xsh_rr_128_64(state: u128) -> u64 {
  ((((state >> 29) ^ state) >> 58) as u64).rotate_right((state >> 122) as u32)
}

//

/// XSH RS `u16` to `u8`
pub const fn xsh_rs_16_8(state: u16) -> u8 {
  (((state >> 7) ^ state) >> ((state >> 14) + 3)) as u8
}

/// XSH RS `u32` to `u16`
pub const fn xsh_rs_32_16(state: u32) -> u16 {
  (((state >> 11) ^ state) >> ((state >> 30) + 11)) as u16
}

/// XSH RS `u64` to `u32`
pub const fn xsh_rs_64_32(state: u64) -> u32 {
  (((state >> 22) ^ state) >> ((state >> 61) + 22)) as u32
}

/// XSH RS `u128` to `u64`
pub const fn xsh_rs_128_64(state: u128) -> u64 {
  (((state >> 43) ^ state) >> ((state >> 124) + 45)) as u64
}

//

/// RXS M XS `u8`
pub const fn rxs_m_xs_8_8(state: u8) -> u8 {
  let w = (state >> ((state >> 6).wrapping_add(2)) ^ state).wrapping_mul(217);
  w >> 6 ^ w
}

/// RXS M XS `u16`
pub const fn rxs_m_xs_16_16(state: u16) -> u16 {
  let w = (state >> ((state >> 13).wrapping_add(3)) ^ state).wrapping_mul(62169);
  w >> 11 ^ w
}

/// RXS M XS `u32`
pub const fn rxs_m_xs_32_32(state: u32) -> u32 {
  let w = (state >> ((state >> 28).wrapping_add(4)) ^ state).wrapping_mul(277803737);
  w >> 22 ^ w
}

/// RXS M XS `u64`
pub const fn rxs_m_xs_64_64(state: u64) -> u64 {
  let w = (state >> ((state >> 59).wrapping_add(5)) ^ state).wrapping_mul(12605985483714917081);
  w >> 43 ^ w
}

/// RXS M XS `u128`
pub const fn rxs_m_xs_128_128(state: u128) -> u128 {
  let w = (state >> ((state >> 122).wrapping_add(6)) ^ state).wrapping_mul(327738287884841127335028083622016905945);
  w >> 86 ^ w
}

//

/// XSL RR `u64` to `u32`
pub const fn xsl_rr_64_32(state: u64) -> u32 {
  ((state >> 32) as u32 ^ (state as u32)).rotate_right((state >> 59) as u32)
}

/// XSL RR `u128` to `u64`
pub const fn xsl_rr_128_64(state: u128) -> u64 {
  ((state >> 64) as u64 ^ (state as u64)).rotate_right((state >> 122) as u32)
}

//

/// XSL RR RR `u64`
pub const fn xsl_rr_rr_64_64(state: u64) -> u64 {
  let rot1: u32 = (state >> 59) as u32;
  let high: u32 = (state >> 32) as u32;
  let low: u32 = state as u32;
  let xor_d: u32 = high ^ low;
  let new_low: u32 = xor_d.rotate_right(rot1);
  let new_high: u32 = high.rotate_right(new_low & 31);
  ((new_high as u64) << 32) | new_low as u64
}

/// XSL RR RR `u128`
pub const fn xsl_rr_rr_128_128(state: u128) -> u128 {
  let rot1: u32 = (state >> 122) as u32;
  let high: u64 = (state >> 64) as u64;
  let low: u64 = state as u64;
  let xor_d: u64 = high ^ low;
  let new_low: u64 = xor_d.rotate_right(rot1);
  let new_high: u64 = high.rotate_right((new_low & 63) as u32);
  ((new_high as u128) << 64) | new_low as u128
}