1#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
10use rand_core::impls::fill_bytes_via_next;
11use rand_core::le::read_u64_into;
12use rand_core::{SeedableRng, RngCore, Error};
13
14use crate::Seed512;
15
16#[derive(Debug, Clone, PartialEq, Eq)]
25#[cfg_attr(feature="serde1", derive(Serialize, Deserialize))]
26pub struct Xoshiro512PlusPlus {
27 s: [u64; 8],
28}
29
30impl Xoshiro512PlusPlus {
31 pub fn jump(&mut self) {
47 impl_jump!(u64, self, [
48 0x33ed89b6e7a353f9, 0x760083d7955323be, 0x2837f2fbb5f22fae,
49 0x4b8c5674d309511c, 0xb11ac47a7ba28c25, 0xf1be7667092bcc1c,
50 0x53851efdb6df0aaf, 0x1ebbc8b23eaf25db
51 ]);
52 }
53
54 pub fn long_jump(&mut self) {
60 impl_jump!(u64, self, [
61 0x11467fef8f921d28, 0xa2a819f2e79c8ea8, 0xa8299fc284b3959a,
62 0xb4d347340ca63ee1, 0x1cb0940bedbff6ce, 0xd956c5c4fa1f8e17,
63 0x915e38fd4eda93bc, 0x5b3ccdfa5d7daca5
64 ]);
65 }
66}
67
68
69impl SeedableRng for Xoshiro512PlusPlus {
70 type Seed = Seed512;
71
72 #[inline]
75 fn from_seed(seed: Seed512) -> Xoshiro512PlusPlus {
76 deal_with_zero_seed!(seed, Self);
77 let mut state = [0; 8];
78 read_u64_into(&seed.0, &mut state);
79 Xoshiro512PlusPlus { s: state }
80 }
81
82 fn seed_from_u64(seed: u64) -> Xoshiro512PlusPlus {
84 from_splitmix!(seed)
85 }
86}
87
88impl RngCore for Xoshiro512PlusPlus {
89 #[inline]
90 fn next_u32(&mut self) -> u32 {
91 (self.next_u64() >> 32) as u32
94 }
95
96 #[inline]
97 fn next_u64(&mut self) -> u64 {
98 let result_plusplus = plusplus_u64!(self.s[2], self.s[0], 17);
99 impl_xoshiro_large!(self);
100 result_plusplus
101 }
102
103 #[inline]
104 fn fill_bytes(&mut self, dest: &mut [u8]) {
105 fill_bytes_via_next(self, dest);
106 }
107
108 #[inline]
109 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
110 self.fill_bytes(dest);
111 Ok(())
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn reference() {
121 let mut rng = Xoshiro512PlusPlus::from_seed(Seed512(
122 [1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
123 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
124 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,
125 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0]));
126 let expected = [
129 524291, 1048578, 539099140, 3299073855497, 6917532603230064654,
130 7494048333530275843, 14418333309547923463, 10960079161595355914,
131 18279570946505382726, 10209173166699159237,
132 ];
133 for &e in &expected {
134 assert_eq!(rng.next_u64(), e);
135 }
136 }
137}