#![no_std]
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![deny(unsafe_code)]
macro_rules! branchless_min {
($x:expr, $y:expr, $u:ty) => {
$y ^ (($x ^ $y) & (<$u>::wrapping_neg(($x < $y) as $u)))
};
}
macro_rules! branchless_max {
($x:expr, $y:expr, $u:ty) => {
$x ^ (($x ^ $y) & (<$u>::wrapping_neg(($x < $y) as $u)))
};
}
#[test]
fn test_branchless_min_and_max() {
for x in core::u8::MIN..=core::u8::MAX {
for y in core::u8::MIN..=core::u8::MAX {
assert_eq!(branchless_min!(x, y, u8), x.min(y));
assert_eq!(branchless_max!(x, y, u8), x.max(y));
}
}
for x in core::i8::MIN..=core::i8::MAX {
for y in core::i8::MIN..=core::i8::MAX {
assert_eq!(branchless_min!(x, y, i8), x.min(y));
assert_eq!(branchless_max!(x, y, i8), x.max(y));
}
}
}
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use core::ops::*;
pub mod formulas;
pub use formulas::*;
mod any;
pub use any::*;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PCG32 {
pub state: u64,
pub inc: u64,
}
impl Default for PCG32 {
#[inline]
fn default() -> Self {
Self::seed(DEFAULT_PCG_SEED as u64, DEFAULT_PCG_INC as u64)
}
}
impl From<[u64; 2]> for PCG32 {
#[inline]
fn from(value: [u64; 2]) -> Self {
Self {
state: value[0],
inc: value[1],
}
}
}
impl From<(u64, u64)> for PCG32 {
#[inline]
fn from(value: (u64, u64)) -> Self {
Self {
state: value.0,
inc: value.1,
}
}
}
impl From<PCG32> for [u64; 2] {
#[inline]
fn from(pcg: PCG32) -> Self {
[pcg.state, pcg.inc]
}
}
impl From<PCG32> for (u64, u64) {
#[inline]
fn from(pcg: PCG32) -> Self {
(pcg.state, pcg.inc)
}
}
impl PCG32 {
#[inline]
pub const fn seed(seed: u64, inc: u64) -> Self {
let inc = (inc << 1) | 1;
let mut state = pcg_core_state64(0, inc);
state = state.wrapping_add(seed);
state = pcg_core_state64(state, inc);
Self { state, inc }
}
#[inline]
pub fn next_u32(&mut self) -> u32 {
let out = xsh_rr_64_32(self.state);
self.state = pcg_core_state64(self.state, self.inc);
out
}
#[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());
}
let rem = i.into_remainder();
let rem_len = rem.len();
let b = self.next_u32().to_le_bytes();
rem.copy_from_slice(&b[..rem_len]);
}
#[inline]
pub fn jump(&mut self, delta: u64) {
self.state = jump_lcg64(delta, self.state, PCG_MULTIPLIER_64, self.inc)
}
}
#[cfg(feature = "rand_core")]
impl rand_core::RngCore for PCG32 {
fn next_u32(&mut self) -> u32 {
PCG32::next_u32(self)
}
fn next_u64(&mut self) -> u64 {
let low = PCG32::next_u32(self);
let high = PCG32::next_u32(self);
u64::from(low) | u64::from(high) << 32
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
PCG32::fill_bytes(self, dest)
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
PCG32::fill_bytes(self, dest);
Ok(())
}
}
#[cfg(feature = "rand_core")]
impl rand_core::SeedableRng for PCG32 {
type Seed = [u8; core::mem::size_of::<[u64; 2]>()];
fn from_seed(s: Self::Seed) -> Self {
let state = u64::from_le_bytes([s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]]);
let inc = u64::from_le_bytes([s[8], s[9], s[10], s[11], s[12], s[13], s[14], s[15]]);
PCG32::seed(state, inc)
}
fn seed_from_u64(u: u64) -> Self {
PCG32::seed(u, u)
}
fn from_rng<R: rand_core::RngCore>(mut rng: R) -> Result<Self, rand_core::Error> {
Ok(PCG32::seed(rng.next_u64(), rng.next_u64()))
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PCG64 {
pub state: u128,
pub inc: u128,
}
impl Default for PCG64 {
#[inline]
fn default() -> Self {
Self::seed(DEFAULT_PCG_SEED, DEFAULT_PCG_INC)
}
}
impl From<[u128; 2]> for PCG64 {
#[inline]
fn from(value: [u128; 2]) -> Self {
Self {
state: value[0],
inc: value[1],
}
}
}
impl From<(u128, u128)> for PCG64 {
#[inline]
fn from(value: (u128, u128)) -> Self {
Self {
state: value.0,
inc: value.1,
}
}
}
impl From<PCG64> for [u128; 2] {
#[inline]
fn from(pcg: PCG64) -> Self {
[pcg.state, pcg.inc]
}
}
impl From<PCG64> for (u128, u128) {
#[inline]
fn from(pcg: PCG64) -> Self {
(pcg.state, pcg.inc)
}
}
impl PCG64 {
#[inline]
pub const fn seed(seed: u128, inc: u128) -> Self {
let inc = (inc << 1) | 1;
let mut state = pcg_core_state128(0, inc);
state = state.wrapping_add(seed);
state = pcg_core_state128(state, inc);
Self { state, inc }
}
#[inline]
pub fn next_u64(&mut self) -> u64 {
let out = xsh_rr_128_64(self.state);
self.state = pcg_core_state128(self.state, self.inc);
out
}
#[inline]
pub fn fill_bytes(&mut self, bytes: &mut [u8]) {
let mut i = bytes.chunks_exact_mut(8);
while let Some(chunk) = i.next() {
chunk.copy_from_slice(&self.next_u64().to_le_bytes());
}
let rem = i.into_remainder();
let rem_len = rem.len();
let b = self.next_u64().to_le_bytes();
rem.copy_from_slice(&b[..rem_len]);
}
#[inline]
pub fn jump(&mut self, delta: u128) {
self.state = jump_lcg128(delta, self.state, PCG_MULTIPLIER_128, self.inc)
}
}
#[cfg(feature = "rand_core")]
impl rand_core::RngCore for PCG64 {
fn next_u32(&mut self) -> u32 {
PCG64::next_u64(self) as u32
}
fn next_u64(&mut self) -> u64 {
PCG64::next_u64(self)
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
PCG64::fill_bytes(self, dest)
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
PCG64::fill_bytes(self, dest);
Ok(())
}
}
#[cfg(feature = "rand_core")]
impl rand_core::SeedableRng for PCG64 {
type Seed = [u8; core::mem::size_of::<[u128; 2]>()];
fn from_seed(s: Self::Seed) -> Self {
let state = u128::from_le_bytes([
s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9], s[10], s[11], s[12], s[13],
s[14], s[15],
]);
let inc = u128::from_le_bytes([
s[16], s[17], s[18], s[19], s[20], s[21], s[22], s[23], s[24], s[25], s[26], s[27], s[28],
s[29], s[30], s[31],
]);
PCG64::seed(state, inc)
}
fn seed_from_u64(u: u64) -> Self {
let u = u128::from(u);
PCG64::seed(u, u)
}
fn from_rng<R: rand_core::RngCore>(mut rng: R) -> Result<Self, rand_core::Error> {
let mut bytes = [0; core::mem::size_of::<[u128; 2]>()];
rng.fill_bytes(&mut bytes[..]);
Ok(<PCG64 as rand_core::SeedableRng>::from_seed(bytes))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct RandRangeU32 {
base: u32,
width: u32,
threshold: u32,
}
impl RandRangeU32 {
#[inline]
pub fn try_new(a: u32, b: u32) -> Option<Self> {
let (base, max) = (a.min(b), a.max(b));
let width = max.wrapping_sub(base).wrapping_add(1);
if width > 0 {
let threshold = width.wrapping_neg() % width;
Some(Self {
base,
width,
threshold,
})
} else {
None
}
}
#[inline]
pub const fn new(a: u32, b: u32) -> Self {
let (base, max) = (branchless_min!(a, b, u32), branchless_max!(a, b, u32));
let width = max.wrapping_sub(base).wrapping_add(1);
let threshold = width.wrapping_neg() % width;
Self {
base,
width,
threshold,
}
}
#[inline]
pub const fn low(&self) -> u32 {
self.base
}
#[inline]
pub const fn high(&self) -> u32 {
self.base.wrapping_add(self.width).wrapping_sub(1)
}
#[inline]
pub fn place_in_range(&self, val: u32) -> Option<u32> {
let mul: u64 = u64::from(val).wrapping_mul(u64::from(self.width));
let low_part: u32 = mul as u32;
if low_part < self.threshold {
None
} else {
Some(((mul >> 32) as u32).wrapping_add(self.base))
}
}
#[inline]
pub fn sample(&self, gen: &mut PCG32) -> u32 {
loop {
if let Some(output) = self.place_in_range(gen.next_u32()) {
return output;
}
}
}
}
impl From<Range<u32>> for RandRangeU32 {
#[inline]
fn from(r: Range<u32>) -> Self {
Self::new(r.start.min(r.end), r.start.max(r.end) - 1)
}
}
impl From<RangeFrom<u32>> for RandRangeU32 {
#[inline]
fn from(r: RangeFrom<u32>) -> Self {
Self::new(r.start, core::u32::MAX - 1)
}
}
impl From<RangeFull> for RandRangeU32 {
#[inline]
fn from(_: RangeFull) -> Self {
Self::new(0, core::u32::MAX - 1)
}
}
impl From<RangeInclusive<u32>> for RandRangeU32 {
#[inline]
fn from(r: RangeInclusive<u32>) -> Self {
Self::new(*r.start(), *r.end())
}
}
impl From<RangeTo<u32>> for RandRangeU32 {
#[inline]
fn from(r: RangeTo<u32>) -> Self {
Self::new(0, r.end - 1)
}
}
impl From<RangeToInclusive<u32>> for RandRangeU32 {
#[inline]
fn from(r: RangeToInclusive<u32>) -> Self {
Self::new(0, r.end)
}
}