1use crate::{ConstDefault, Own, xorshift_basis};
7
8#[doc = crate::TAG_RAND!()]
9#[must_use]
17#[derive(Clone, Copy, Debug, PartialEq, Eq)]
18pub struct XorShift32<
19 const BASIS: usize = 1,
20 const A: usize = 5,
21 const B: usize = 17,
22 const C: usize = 13,
23>(u32);
24
25impl Default for XorShift32 {
27 fn default() -> Self {
28 Self::DEFAULT
29 }
30}
31impl ConstDefault for XorShift32 {
33 const DEFAULT: Self = Self::new_unchecked(Self::DEFAULT_SEED);
34}
35
36impl<const BASIS: usize, const A: usize, const B: usize, const C: usize>
38 XorShift32<BASIS, A, B, C>
39{
40 const DEFAULT_SEED: u32 = 0xDEFA_0017;
41
42 #[cold] #[allow(dead_code)] #[rustfmt::skip]
43 const fn cold_path_default() -> Self { Self::new_unchecked(Self::DEFAULT_SEED) }
44}
45
46impl<const BASIS: usize, const A: usize, const B: usize, const C: usize>
47 XorShift32<BASIS, A, B, C>
48{
49 pub const fn new(seed: u32) -> Self {
53 if seed == 0 { Self::cold_path_default() } else { Self(seed) }
54 }
55
56 pub const fn new_unchecked(seed: u32) -> Self {
60 debug_assert![seed != 0, "Seed must be non-zero"];
61 Self(seed)
62 }
63
64 #[must_use]
65 pub const fn inner_state(self) -> u32 {
67 self.0
68 }
69 pub const fn from_state(state: u32) -> Self {
71 Self(state)
72 }
73
74 #[must_use]
76 pub const fn current_u32(&self) -> u32 {
77 self.0
78 }
79
80 #[must_use]
84 pub fn next_u32(&mut self) -> u32 {
85 let mut x = self.0;
86 xorshift_basis!(x, BASIS, (A, B, C));
87 self.0 = x;
88 x
89 }
90
91 pub const fn peek_next_state(&self) -> Self {
93 let mut x = self.0;
94 xorshift_basis!(x, BASIS, (A, B, C));
95 Self(x)
96 }
97
98 pub const fn own_next_u32(self) -> Own<Self, u32> {
100 let s = self.peek_next_state();
101 let v = s.current_u32();
102 Own::new(s, v)
103 }
104}
105
106impl<const BASIS: usize, const A: usize, const B: usize, const C: usize>
108 XorShift32<BASIS, A, B, C>
109{
110 pub const fn new1_u32(seed: u32) -> Self {
114 Self::new(seed)
115 }
116
117 #[cfg(feature = "join")]
121 #[cfg_attr(nightly_doc, doc(cfg(feature = "join")))]
122 pub const fn new2_u16(seeds: [u16; 2]) -> Self {
123 Self::new(crate::Cast::<u32>::from_u16_le(seeds))
124 }
125
126 pub const fn new4_u8(seeds: [u8; 4]) -> Self {
130 Self::new(u32::from_le_bytes(seeds))
131 }
132}
133
134#[cfg(all(feature = "dep_rand_core", feature = "join"))]
135#[cfg_attr(nightly_doc, doc(cfg(all(feature = "dep_rand_core", feature = "join"))))]
136mod impl_rand {
137 use crate::_dep::rand_core::{RngCore, SeedableRng};
138 use crate::{Cast, XorShift32};
139
140 impl<const BASIS: usize, const A: usize, const B: usize, const C: usize> RngCore
141 for XorShift32<BASIS, A, B, C>
142 {
143 fn next_u32(&mut self) -> u32 {
145 self.next_u32()
146 }
147
148 fn next_u64(&mut self) -> u64 {
150 Cast::<u64>::from_u32_le([self.next_u32(), self.next_u32()])
151 }
152
153 fn fill_bytes(&mut self, dest: &mut [u8]) {
154 let mut i = 0;
155 while i < dest.len() {
156 let random_u32 = self.next_u32();
157 let bytes = random_u32.to_le_bytes();
158 let remaining = dest.len() - i;
159
160 if remaining >= 4 {
161 dest[i..i + 4].copy_from_slice(&bytes);
162 i += 4;
163 } else {
164 dest[i..].copy_from_slice(&bytes[..remaining]);
165 break;
166 }
167 }
168 }
169 }
170
171 impl<const BASIS: usize, const A: usize, const B: usize, const C: usize> SeedableRng
172 for XorShift32<BASIS, A, B, C>
173 {
174 type Seed = [u8; 4];
175
176 fn from_seed(seed: Self::Seed) -> Self {
179 if seed == [0; 4] {
180 Self::cold_path_default()
181 } else {
182 Self::new_unchecked(u32::from_le_bytes(seed))
183 }
184 }
185 }
186}
187
188#[doc(hidden)]
190#[rustfmt::skip]
191#[allow(dead_code)]
192pub const XOROSHIFT_32_TRIPLETS: [(u8, u8, u8); 81] = [
193 ( 1, 3,10), ( 1, 5,16), ( 1, 5,19), ( 1, 9,29), ( 1,11, 6), ( 1,11,16),
194 ( 1,19, 3), ( 1,21,20), ( 1,27,27), ( 2, 5,15), ( 2, 5,21), ( 2, 7, 7),
195 ( 2, 7, 9), ( 2, 7,25), ( 2, 9,15), ( 2,15,17), ( 2,15,25), ( 2,21, 9),
196 ( 3, 1,14), ( 3, 3,26), ( 3, 3,28), ( 3, 3,29), ( 3, 5,20), ( 3, 5,22),
197 ( 3, 5,25), ( 3, 7,29), ( 3,13, 7), ( 3,23,25), ( 3,25,24), ( 3,27,11),
198 ( 4, 3,17), ( 4, 3,27), ( 4, 5,15), ( 5, 3,21), ( 5, 7,22), ( 5, 9, 7),
199 ( 5, 9,28), ( 5, 9,31), ( 5,13, 6), ( 5,15,17), ( 5,17,13), ( 5,21,12),
200 ( 5,27, 8), ( 5,27,21), ( 5,27,25), ( 5,27,28), ( 6, 1,11), ( 6, 3,17),
201 ( 6,17, 9), ( 6,21, 7), ( 6,21,13), ( 7, 1, 9), ( 7, 1,18), ( 7, 1,25),
202 ( 7,13,25), ( 7,17,21), ( 7,25,12), ( 7,25,20), ( 8, 7,23), ( 8, 9,23),
203 ( 9, 5, 1), ( 9, 5,25), ( 9,11,19), ( 9,21,16), (10, 9,21), (10, 9,25),
204 (11, 7,12), (11,7, 16), (11,17,13), (11,21,13), (12, 9,23), (13, 3,17),
205 (13, 3,27), (13,5, 19), (13,17,15), (14, 1,15), (14,13,15), (15, 1,29),
206 (17,15,20), (17,15,23), (17,15,26)
207];