1use crate::{_xorshift_basis, Infallible, InfallibleResult, RandQualities, RandSeedable, RandTry};
7use crate::{Cast, ConstInit, Own, Slice, slice};
8
9#[doc = crate::_tags!(rand)]
10#[doc = crate::_doc_meta!{location("num/prob/rand")}]
12#[must_use]
19#[derive(Clone, Copy, Debug, PartialEq, Eq)]
20pub struct XorShift32<
21 const BASIS: usize = 1,
22 const A: usize = 5,
23 const B: usize = 17,
24 const C: usize = 13,
25>(u32);
26
27impl Default for XorShift32 {
29 fn default() -> Self {
30 Self::INIT
31 }
32}
33impl ConstInit for XorShift32 {
35 const INIT: Self = Self::new_unchecked(Self::DEFAULT_SEED);
36}
37
38impl<const BASIS: usize, const A: usize, const B: usize, const C: usize>
40 XorShift32<BASIS, A, B, C>
41{
42 #[doc(hidden)]
43 pub const DEFAULT_SEED: u32 = 0xDEFA_0017;
44
45 #[cold] #[allow(dead_code)] #[rustfmt::skip]
46 const fn cold_path_default() -> Self { Self::new_unchecked(Self::DEFAULT_SEED) }
47}
48
49impl<const BASIS: usize, const A: usize, const B: usize, const C: usize>
50 XorShift32<BASIS, A, B, C>
51{
52 pub const fn new(seed: u32) -> Self {
56 if seed == 0 { Self::cold_path_default() } else { Self(seed) }
57 }
58 pub const fn new_unchecked(seed: u32) -> Self {
62 debug_assert![seed != 0, "Seed must be non-zero"];
63 Self(seed)
64 }
65 #[must_use]
66 pub const fn inner_state(self) -> u32 {
68 self.0
69 }
70 pub const fn from_state(state: u32) -> Self {
72 Self(state)
73 }
74 #[must_use]
76 pub const fn current_u32(&self) -> u32 {
77 self.0
78 }
79 #[must_use]
83 pub const fn next_u32(&mut self) -> u32 {
84 let mut x = self.0;
85 _xorshift_basis!(x, BASIS, (A, B, C));
86 self.0 = x;
87 x
88 }
89 pub const fn peek_next_state(&self) -> Self {
91 let mut x = self.0;
92 _xorshift_basis!(x, BASIS, (A, B, C));
93 Self(x)
94 }
95 pub const fn own_next_u32(self) -> Own<Self, u32> {
97 let s = self.peek_next_state();
98 let v = s.current_u32();
99 Own::new(s, v)
100 }
101 pub const fn fill_bytes(&mut self, buffer: &mut [u8]) {
103 let mut i = 0;
104 while i < buffer.len() {
105 let random_u32 = self.next_u32();
106 let bytes = random_u32.to_le_bytes();
107 let remaining = buffer.len() - i;
108 if remaining >= 4 {
109 Slice::copy(slice!(mut buffer, i, ..i + 4), &bytes);
111 i += 4;
112 } else {
113 Slice::copy(slice!(mut buffer, i, ..), slice!(&bytes, ..remaining));
115 break;
116 }
117 }
118 }
119}
120
121impl<const BASIS: usize, const A: usize, const B: usize, const C: usize>
123 XorShift32<BASIS, A, B, C>
124{
125 pub const fn new1_u32(seed: u32) -> Self {
129 Self::new(seed)
130 }
131 pub const fn new2_u16(seeds: [u16; 2]) -> Self {
135 Self::new(Cast::<u32>::from_u16_le(seeds))
136 }
137 pub const fn new4_u8(seeds: [u8; 4]) -> Self {
141 Self::new(u32::from_le_bytes(seeds))
142 }
143
144 pub const fn next_u64(&mut self) -> u64 {
146 Cast::<u64>::from_u32_le([self.next_u32(), self.next_u32()])
147 }
148}
149
150crate::items! {
151 impl<const BASIS: usize, const A: usize, const B: usize, const C: usize> RandTry
152 for XorShift32<BASIS, A, B, C> {
153 type Error = Infallible;
154 const RAND_OUTPUT_BITS: u32 = 32;
155 const RAND_STATE_BITS: u32 = 32;
156 const RAND_QUALITIES: RandQualities = RandQualities::WEAK_PRNG;
157 fn rand_try_next_u32(&mut self) -> InfallibleResult<u32> { Ok(self.next_u32()) }
158 fn rand_try_next_u64(&mut self) -> InfallibleResult<u64> { Ok(self.next_u64()) }
159 fn rand_try_fill_bytes(&mut self, buffer: &mut [u8]) -> InfallibleResult<()> {
160 self.fill_bytes(buffer); Ok(())
161 }
162 }
163 impl<const BASIS: usize, const A: usize, const B: usize, const C: usize> RandSeedable
164 for XorShift32<BASIS, A, B, C> {
165 type RandSeed = [u8; 4];
166 #[inline(always)]
167 fn rand_from_seed(seed: Self::RandSeed) -> Self { Self::new(u32::from_le_bytes(seed)) }
169 }
170}
171crate::__impl_dep_rand_core!(XorShift32
172 <const BASIS: usize, const A: usize, const B: usize, const C: usize>);
173
174#[doc = crate::_tags!(rand)]
175#[doc = crate::_doc_meta!{location("num/prob/rand")}]
177#[doc(hidden)]
178#[rustfmt::skip]
179#[allow(dead_code)]
180pub const XOROSHIFT_32_TRIPLETS: [(u8, u8, u8); 81] = [
181 ( 1, 3,10), ( 1, 5,16), ( 1, 5,19), ( 1, 9,29), ( 1,11, 6), ( 1,11,16),
182 ( 1,19, 3), ( 1,21,20), ( 1,27,27), ( 2, 5,15), ( 2, 5,21), ( 2, 7, 7),
183 ( 2, 7, 9), ( 2, 7,25), ( 2, 9,15), ( 2,15,17), ( 2,15,25), ( 2,21, 9),
184 ( 3, 1,14), ( 3, 3,26), ( 3, 3,28), ( 3, 3,29), ( 3, 5,20), ( 3, 5,22),
185 ( 3, 5,25), ( 3, 7,29), ( 3,13, 7), ( 3,23,25), ( 3,25,24), ( 3,27,11),
186 ( 4, 3,17), ( 4, 3,27), ( 4, 5,15), ( 5, 3,21), ( 5, 7,22), ( 5, 9, 7),
187 ( 5, 9,28), ( 5, 9,31), ( 5,13, 6), ( 5,15,17), ( 5,17,13), ( 5,21,12),
188 ( 5,27, 8), ( 5,27,21), ( 5,27,25), ( 5,27,28), ( 6, 1,11), ( 6, 3,17),
189 ( 6,17, 9), ( 6,21, 7), ( 6,21,13), ( 7, 1, 9), ( 7, 1,18), ( 7, 1,25),
190 ( 7,13,25), ( 7,17,21), ( 7,25,12), ( 7,25,20), ( 8, 7,23), ( 8, 9,23),
191 ( 9, 5, 1), ( 9, 5,25), ( 9,11,19), ( 9,21,16), (10, 9,21), (10, 9,25),
192 (11, 7,12), (11,7, 16), (11,17,13), (11,21,13), (12, 9,23), (13, 3,17),
193 (13, 3,27), (13,5, 19), (13,17,15), (14, 1,15), (14,13,15), (15, 1,29),
194 (17,15,20), (17,15,23), (17,15,26)
195];