rand_xoshiro/
xoroshiro64starstar.rs1use core::convert::Infallible;
10use rand_core::{SeedableRng, TryRng, utils};
11#[cfg(feature = "serde")]
12use serde::{Deserialize, Serialize};
13
14#[allow(missing_copy_implementations)]
23#[derive(Debug, Clone, PartialEq, Eq)]
24#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25pub struct Xoroshiro64StarStar {
26 s0: u32,
27 s1: u32,
28}
29
30impl TryRng for Xoroshiro64StarStar {
31 type Error = Infallible;
32
33 #[inline]
34 fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
35 let r = starstar_u32!(self.s0);
36 impl_xoroshiro_u32!(self);
37 Ok(r)
38 }
39
40 #[inline]
41 fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
42 utils::next_u64_via_u32(self)
43 }
44
45 #[inline]
46 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> {
47 utils::fill_bytes_via_next_word(dest, || self.try_next_u32())
48 }
49}
50
51impl_state_pair!(Xoroshiro64StarStar, u32);
52
53impl SeedableRng for Xoroshiro64StarStar {
54 type Seed = [u8; 8];
55
56 fn from_seed(seed: [u8; 8]) -> Xoroshiro64StarStar {
59 let s: [_; 2] = utils::read_words(crate::common::zero_seed_fallback(&seed));
60
61 Xoroshiro64StarStar { s0: s[0], s1: s[1] }
62 }
63
64 fn seed_from_u64(seed: u64) -> Xoroshiro64StarStar {
66 from_splitmix!(seed)
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use rand_core::Rng;
74
75 #[test]
76 fn reference() {
77 let mut rng = Xoroshiro64StarStar::from_seed([1, 0, 0, 0, 2, 0, 0, 0]);
78 let expected = [
81 3802928447, 813792938, 1618621494, 2955957307, 3252880261, 1129983909, 2539651700,
82 1327610908, 1757650787, 2763843748,
83 ];
84 for &e in &expected {
85 assert_eq!(rng.next_u32(), e);
86 }
87 }
88
89 #[test]
90 fn zero_seed() {
91 let mut rng = Xoroshiro64StarStar::seed_from_u64(0);
92 assert_ne!(rng.next_u64(), 0);
93 }
94
95 #[test]
96 fn zero_seed_maps_to_seed_from_u64_zero() {
97 let from_zero = Xoroshiro64StarStar::from_seed([0u8; 8]);
98 let from_sm0 = Xoroshiro64StarStar::seed_from_u64(0);
99 assert_eq!(from_zero, from_sm0);
100 }
101
102 #[test]
103 fn state_roundtrip() {
104 let rng = Xoroshiro64StarStar::seed_from_u64(42);
105 let clone = Xoroshiro64StarStar::from_seed(rng.state());
106 assert_eq!(clone, rng);
107 }
108}