rand_xoshiro/
xoshiro256plusplus.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 Xoshiro256PlusPlus {
25 s: [u64; 4],
26}
27
28impl Xoshiro256PlusPlus {
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!(Xoshiro256PlusPlus, u64);
77
78impl SeedableRng for Xoshiro256PlusPlus {
79 type Seed = [u8; 32];
80
81 #[inline]
84 fn from_seed(seed: [u8; 32]) -> Xoshiro256PlusPlus {
85 Xoshiro256PlusPlus {
86 s: utils::read_words(crate::common::zero_seed_fallback(&seed)),
87 }
88 }
89
90 fn seed_from_u64(seed: u64) -> Xoshiro256PlusPlus {
92 from_splitmix!(seed)
93 }
94}
95
96impl TryRng for Xoshiro256PlusPlus {
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_plusplus = plusplus_u64!(self.s[0], self.s[3], 23);
109 impl_xoshiro_u64!(self);
110 Ok(result_plusplus)
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 = Xoshiro256PlusPlus::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 41943041,
133 58720359,
134 3588806011781223,
135 3591011842654386,
136 9228616714210784205,
137 9973669472204895162,
138 14011001112246962877,
139 12406186145184390807,
140 15849039046786891736,
141 10450023813501588000,
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 = Xoshiro256PlusPlus::from_seed([0; 32]);
151 let from_sm0 = Xoshiro256PlusPlus::seed_from_u64(0);
152 assert_eq!(from_zero, from_sm0);
153 }
154
155 #[test]
156 fn state_roundtrip() {
157 let rng = Xoshiro256PlusPlus::seed_from_u64(42);
158 let clone = Xoshiro256PlusPlus::from_seed(rng.state());
159 assert_eq!(clone, rng);
160 }
161}