///|
/// The contract every generator satisfies: produce uniform machine words. The
/// algorithms in subpackages implement the one required method `next_u64`; the
/// other two are shared defaults. The sampling and distribution functions in
/// `moonrand` are generic over any `Rng`.
///
/// Methods take `Self` by value and keep their state in interior-mutable
/// fields (`Array` buffers and `priv mut` scalars), so a draw advances the
/// caller's generator without a mutable reference.
pub(open) trait Rng {
/// The next 64-bit word, uniformly over `[0, 2^64)`. Every algorithm
/// implements this one method; `next_u32` and `fill` are shared defaults.
fn next_u64(Self) -> UInt64
/// The next 32-bit word. The default takes the top half of a 64-bit draw.
fn next_u32(Self) -> UInt32 = _
/// Fill `buf` with uniform bytes. The default draws 8 at a time.
fn fill(Self, buf : FixedArray[Byte]) -> Unit = _
}
///|
impl Rng with fn next_u32(self) -> UInt32 {
((self.next_u64() >> 32) & 0xFFFFFFFF).to_uint()
}
///|
impl Rng with fn fill(self, buf : FixedArray[Byte]) -> Unit {
let n = buf.length()
let mut i = 0
while i < n {
let w = self.next_u64()
for j = 0; j < 8 && i + j < n; j = j + 1 {
buf[i + j] = ((w >> (j * 8)) & 0xFF).to_byte()
}
i = i + 8
}
}
///|
/// A generator fit for cryptography: ChaCha and the like. Philox and PCG pass
/// statistical tests but are not, so they do not carry this marker.
pub(open) trait Secure: Rng {}
///|
/// A generator rebuilt from a seed, for reproducible runs.
pub(open) trait Seeded: Rng {
/// Rebuild the generator from a `seed_size`-byte seed.
fn from_seed(BytesView) -> Self
/// How many seed bytes `from_seed` expects.
fn seed_size() -> Int32
}