1use crate::Source;
2
3#[derive(Clone, Copy)]
12pub struct Xorshift128Plus(u64, u64);
13
14impl Xorshift128Plus {
15 #[inline(always)]
19 pub fn new(seed: [u64; 2]) -> Self {
20 debug_assert!(
21 seed[0] | seed[1] != 0,
22 "at least one bit of the seed should be one"
23 );
24 Xorshift128Plus(seed[0], seed[1])
25 }
26}
27
28impl Source for Xorshift128Plus {
29 #[inline(always)]
30 fn read_u64(&mut self) -> u64 {
31 let (mut x, y) = (self.0, self.1);
32 self.0 = y;
33 x = x ^ (x << 23);
34 x = x ^ (x >> 17);
35 x = x ^ y ^ (y >> 26);
36 self.1 = x;
37 x.wrapping_add(y)
38 }
39}
40
41impl From<[u64; 2]> for Xorshift128Plus {
42 #[inline(always)]
43 fn from(seed: [u64; 2]) -> Self {
44 Self::new(seed)
45 }
46}
47
48impl From<Xorshift128Plus> for [u64; 2] {
49 #[inline(always)]
50 fn from(source: Xorshift128Plus) -> Self {
51 [source.0, source.1]
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use crate::Xorshift128Plus;
58
59 #[test]
60 #[should_panic]
61 fn new_zero_seed() {
62 let _ = Xorshift128Plus::new([0, 0]);
63 }
64}