rand_xoshiro/
xoshiro256starstar.rs1use core::convert::Infallible;
10use rand_core::{Rng, SeedableRng, TryRng, utils};
11#[cfg(feature = "serde")]
12use serde::{Deserialize, Serialize};
13
14#[derive(Debug, Clone, PartialEq, Eq)]
23#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
24pub struct Xoshiro256StarStar {
25 s: [u64; 4],
26}
27
28impl Xoshiro256StarStar {
29 pub fn jump(&mut self) {
45 impl_jump!(
46 u64,
47 self,
48 [
49 0x180ec6d33cfd0aba,
50 0xd5a61266f0c9392c,
51 0xa9582618e03fc9aa,
52 0x39abdc4529b1661c
53 ]
54 );
55 }
56
57 pub fn long_jump(&mut self) {
63 impl_jump!(
64 u64,
65 self,
66 [
67 0x76e15d3efefdcbbf,
68 0xc5004e441c522fb3,
69 0x77710069854ee241,
70 0x39109bb02acbe635
71 ]
72 );
73 }
74}
75
76impl_state_array_of_four!(Xoshiro256StarStar, u64);
77
78impl SeedableRng for Xoshiro256StarStar {
79 type Seed = [u8; 32];
80
81 #[inline]
84 fn from_seed(seed: [u8; 32]) -> Xoshiro256StarStar {
85 Xoshiro256StarStar {
86 s: utils::read_words(crate::common::zero_seed_fallback(&seed)),
87 }
88 }
89
90 fn seed_from_u64(seed: u64) -> Xoshiro256StarStar {
92 from_splitmix!(seed)
93 }
94}
95
96impl TryRng for Xoshiro256StarStar {
97 type Error = Infallible;
98
99 #[inline]
100 fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
101 Ok((self.next_u64() >> 32) as u32)
104 }
105
106 #[inline]
107 fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
108 let result_starstar = starstar_u64!(self.s[1]);
109 impl_xoshiro_u64!(self);
110 Ok(result_starstar)
111 }
112
113 #[inline]
114 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> {
115 utils::fill_bytes_via_next_word(dest, || self.try_next_u64())
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122
123 #[test]
124 fn reference() {
125 let mut rng = Xoshiro256StarStar::from_seed([
126 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
127 0, 0, 0,
128 ]);
129 let expected = [
132 11520,
133 0,
134 1509978240,
135 1215971899390074240,
136 1216172134540287360,
137 607988272756665600,
138 16172922978634559625,
139 8476171486693032832,
140 10595114339597558777,
141 2904607092377533576,
142 ];
143 for &e in &expected {
144 assert_eq!(rng.next_u64(), e);
145 }
146 }
147
148 #[test]
149 fn zero_seed_maps_to_seed_from_u64_zero() {
150 let from_zero = Xoshiro256StarStar::from_seed([0u8; 32]);
151 let from_sm0 = Xoshiro256StarStar::seed_from_u64(0);
152 assert_eq!(from_zero, from_sm0);
153 }
154
155 #[test]
156 fn state_roundtrip() {
157 let rng = Xoshiro256StarStar::seed_from_u64(42);
158 let clone = Xoshiro256StarStar::from_seed(rng.state());
159 assert_eq!(clone, rng);
160 }
161}