poulpy_hal/
source.rs

1use rand_chacha::{ChaCha8Rng, rand_core::SeedableRng};
2use rand_core::RngCore;
3
4const MAXF64: f64 = 9007199254740992.0;
5
6pub struct Source {
7    source: ChaCha8Rng,
8}
9
10impl Source {
11    pub fn new(seed: [u8; 32]) -> Source {
12        Source {
13            source: ChaCha8Rng::from_seed(seed),
14        }
15    }
16
17    pub fn branch(&mut self) -> ([u8; 32], Self) {
18        let seed: [u8; 32] = self.new_seed();
19        (seed, Source::new(seed))
20    }
21
22    pub fn new_seed(&mut self) -> [u8; 32] {
23        let mut seed: [u8; 32] = [0u8; 32];
24        self.fill_bytes(&mut seed);
25        seed
26    }
27
28    #[inline(always)]
29    pub fn next_u64n(&mut self, max: u64, mask: u64) -> u64 {
30        let mut x: u64 = self.next_u64() & mask;
31        while x >= max {
32            x = self.next_u64() & mask;
33        }
34        x
35    }
36
37    #[inline(always)]
38    pub fn next_f64(&mut self, min: f64, max: f64) -> f64 {
39        min + ((self.next_u64() << 11 >> 11) as f64) / MAXF64 * (max - min)
40    }
41
42    pub fn next_i64(&mut self) -> i64 {
43        self.next_u64() as i64
44    }
45}
46
47impl RngCore for Source {
48    #[inline(always)]
49    fn next_u32(&mut self) -> u32 {
50        self.source.next_u32()
51    }
52
53    #[inline(always)]
54    fn next_u64(&mut self) -> u64 {
55        self.source.next_u64()
56    }
57
58    #[inline(always)]
59    fn fill_bytes(&mut self, bytes: &mut [u8]) {
60        self.source.fill_bytes(bytes)
61    }
62}