#[doc = crate::_tags!(rand)]
#[doc = crate::_doc_location!("num/prob/rand")]
pub trait Rand {
const RAND_OUTPUT_BITS: u32;
const RAND_STATE_BITS: u32;
fn rand_next_u64(&mut self) -> u64;
#[inline(always)]
fn rand_next_u32(&mut self) -> u32 {
self.rand_next_u64() as u32
}
#[inline(always)]
fn rand_next_u16(&mut self) -> u16 {
self.rand_next_u64() as u16
}
#[inline(always)]
fn rand_next_bool(&mut self) -> bool {
(self.rand_next_u64() & 1) != 0
}
fn rand_fill_bytes(&mut self, buf: &mut [u8]) {
let mut i = 0;
let len = buf.len();
while i + 8 <= len {
buf[i..i + 8].copy_from_slice(&self.rand_next_u64().to_ne_bytes());
i += 8;
}
if i < len {
let tail = self.rand_next_u64().to_ne_bytes();
buf[i..].copy_from_slice(&tail[..len - i]);
}
}
fn rand_below(&mut self, upper: u64) -> u64 {
assert!(upper > 0);
let zone = u64::MAX - (u64::MAX % upper);
loop {
let v = self.rand_next_u64();
if v < zone {
return v % upper;
}
}
}
#[inline(always)]
fn rand_range(&mut self, low: u64, high: u64) -> u64 {
assert!(low < high);
low + self.rand_below(high - low)
}
#[inline(always)]
fn rand_roll(&mut self, sides: u64) -> u64 {
self.rand_below(sides) + 1
}
fn rand_shuffle<T>(&mut self, slice: &mut [T]) {
let mut i = slice.len();
while i > 1 {
i -= 1;
let j = self.rand_below((i + 1) as u64) as usize;
slice.swap(i, j);
}
}
}