macro_rules! _implement_crypto_rng {
($struct:ty) => {
impl crate::misc::CryptoRng for $struct {}
impl crate::misc::Rng for $struct {
#[inline]
fn u8(&mut self) -> u8 {
let [a, ..] = self.next_u32().to_be_bytes();
a
}
#[inline]
fn u8_4(&mut self) -> [u8; 4] {
self.next_u32().to_be_bytes()
}
#[inline]
fn u8_8(&mut self) -> [u8; 8] {
let [a, b, c, d, e, f, g, h] = self.next_u64().to_be_bytes();
[a, b, c, d, e, f, g, h]
}
#[inline]
fn u8_16(&mut self) -> [u8; 16] {
let [a, b, c, d, e, f, g, h] = self.next_u64().to_be_bytes();
let [i, j, k, l, m, n, o, p] = self.next_u64().to_be_bytes();
[a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p]
}
}
};
}
mod crypto_rng;
#[cfg(feature = "fastrand")]
mod fastrand;
mod from_rng;
#[cfg(feature = "rand_chacha")]
mod rand_chacha;
mod seed;
mod xorshift;
use core::{
cell::Cell,
ops::{Bound, RangeBounds},
};
pub use crypto_rng::CryptoRng;
pub use from_rng::FromRng;
pub use seed::*;
pub use xorshift::*;
pub trait Rng
where
Self: Sized,
{
#[inline]
fn elem_from_range<R, T>(&mut self, range: &R) -> Option<T>
where
R: RangeBounds<T>,
T: FromRng<Self> + PartialOrd,
{
match (range.start_bound(), range.end_bound()) {
(Bound::Included(a) | Bound::Excluded(a), Bound::Included(b)) => {
if a < b {
return None;
}
}
(Bound::Included(a) | Bound::Excluded(a), Bound::Excluded(b)) => {
if a <= b {
return None;
}
}
_ => {}
}
loop {
let random = T::from_rng(self);
if range.contains(&random) {
return Some(random);
}
}
}
#[inline]
fn fill_slice<T>(&mut self, slice: &mut [T])
where
T: FromRng<Self>,
{
for elem in slice {
*elem = T::from_rng(self);
}
}
#[inline]
fn shuffle_slice<T>(&mut self, slice: &mut [T]) {
if slice.len() <= 1 {
return;
}
for from_idx in 0..slice.len() {
let range = 0..from_idx.wrapping_add(1);
let Some(to_idx) = self.elem_from_range(&range) else {
continue;
};
slice.swap(from_idx, to_idx);
}
}
fn u8(&mut self) -> u8;
fn u8_4(&mut self) -> [u8; 4];
fn u8_8(&mut self) -> [u8; 8];
fn u8_16(&mut self) -> [u8; 16];
}
impl<T> Rng for Cell<T>
where
T: Copy + Rng,
{
#[inline]
fn u8(&mut self) -> u8 {
let mut instance = self.get();
let rslt = instance.u8();
self.set(instance);
rslt
}
#[inline]
fn u8_4(&mut self) -> [u8; 4] {
let mut instance = self.get();
let rslt = instance.u8_4();
self.set(instance);
rslt
}
#[inline]
fn u8_8(&mut self) -> [u8; 8] {
let mut instance = self.get();
let rslt = instance.u8_8();
self.set(instance);
rslt
}
#[inline]
fn u8_16(&mut self) -> [u8; 16] {
let mut instance = self.get();
let rslt = instance.u8_16();
self.set(instance);
rslt
}
}
impl<T> Rng for &Cell<T>
where
T: Copy + Rng,
{
#[inline]
fn u8(&mut self) -> u8 {
self.get().u8()
}
#[inline]
fn u8_4(&mut self) -> [u8; 4] {
self.get().u8_4()
}
#[inline]
fn u8_8(&mut self) -> [u8; 8] {
self.get().u8_8()
}
#[inline]
fn u8_16(&mut self) -> [u8; 16] {
self.get().u8_16()
}
}
impl<T> Rng for &mut T
where
T: Rng,
{
#[inline]
fn u8(&mut self) -> u8 {
(*self).u8()
}
#[inline]
fn u8_4(&mut self) -> [u8; 4] {
(*self).u8_4()
}
#[inline]
fn u8_8(&mut self) -> [u8; 8] {
(*self).u8_8()
}
#[inline]
fn u8_16(&mut self) -> [u8; 16] {
(*self).u8_16()
}
}