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