1pub trait Rng {
3 fn next_u64(&mut self) -> u64;
5}
6
7#[inline]
9pub fn unit(rng: &mut dyn Rng) -> f64 {
10 ((rng.next_u64() >> 11) as f64) * (1.0 / 9_007_199_254_740_992.0)
11}
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq)]
15pub struct SplitMix64 {
16 state: u64,
17}
18
19impl SplitMix64 {
20 pub const fn new(seed: u64) -> Self {
22 Self { state: seed }
23 }
24}
25
26impl Rng for SplitMix64 {
27 #[inline]
28 fn next_u64(&mut self) -> u64 {
29 self.state = self.state.wrapping_add(0x9e37_79b9_7f4a_7c15);
30 let mut value = self.state;
31 value = (value ^ (value >> 30)).wrapping_mul(0xbf58_476d_1ce4_e5b9);
32 value = (value ^ (value >> 27)).wrapping_mul(0x94d0_49bb_1331_11eb);
33 value ^ (value >> 31)
34 }
35}
36
37#[derive(Clone, Debug, PartialEq, Eq)]
42pub struct TapeRng<'a> {
43 tape: &'a [u64],
44 position: usize,
45}
46
47impl<'a> TapeRng<'a> {
48 pub const fn new(tape: &'a [u64]) -> Self {
50 Self { tape, position: 0 }
51 }
52
53 pub fn remaining(&self) -> usize {
55 self.tape.len().saturating_sub(self.position)
56 }
57}
58
59impl Rng for TapeRng<'_> {
60 fn next_u64(&mut self) -> u64 {
61 let value = self.tape.get(self.position).copied().unwrap_or(0);
62 self.position = self.position.saturating_add(1);
63 value
64 }
65}
66
67#[cfg(feature = "rand_core")]
68impl<T: rand_core::RngCore + ?Sized> Rng for T {
69 #[inline]
70 fn next_u64(&mut self) -> u64 {
71 rand_core::RngCore::next_u64(self)
72 }
73}