1use crate::rng::{Generator, SeedableGenerator};
2use crate::util;
3
4#[derive(Debug, PartialEq, Eq)]
11pub struct Xoshiro256pp {
12 state: [u64; 4],
13}
14
15impl Default for Xoshiro256pp {
16 fn default() -> Self {
17 Self::new_with_seed(0)
18 }
19}
20
21impl SeedableGenerator for Xoshiro256pp {
22 fn new_with_seed(seed: u64) -> Self {
23 let state = util::state_from_seed(seed);
24 let mut ret = Self { state };
25 let _discard_first = ret.u64();
26 ret
27 }
28}
29
30impl Generator for Xoshiro256pp {
31 #[inline]
32 fn try_new() -> Result<Self, getrandom::Error> {
33 let state = util::state_from_entropy()?;
34 Ok(Self { state })
35 }
36
37 #[cfg_attr(feature = "inline", inline)]
38 fn u64(&mut self) -> u64 {
39 let result = self.state[0]
40 .wrapping_add(self.state[3])
41 .rotate_left(23)
42 .wrapping_add(self.state[0]);
43 let tmp = self.state[1] << 17;
44
45 self.state[2] ^= self.state[0];
46 self.state[3] ^= self.state[1];
47 self.state[1] ^= self.state[2];
48 self.state[0] ^= self.state[3];
49
50 self.state[2] ^= tmp;
51 self.state[3] = self.state[3].rotate_left(45);
52
53 result
54 }
55}