1use rand_core::{RngCore, SeedableRng};
2
3use crate::{
4 Pcg,
5 lcg::{Integer, Lcg, Parameters},
6 output::Output
7};
8
9macro_rules! impl_rng_core {
10 () => {
11 impl_rng_core!(u8);
12 impl_rng_core!(u16);
13 impl_rng_core!(u32);
14 impl_rng_core!(u64);
15 impl_rng_core!(u128);
16 impl_rng_core!(usize);
17 };
18
19 (u8) => {
20 impl_rng_core!(u8 impl<L> for Lcg<L, u8> where L: Copy + Into<Parameters<u8>>);
21
22 impl_rng_core! { u8
23 impl<L, P, S> for Pcg<L, P, S, u8>
24 where
25 L: Copy + Into<Parameters<S>>,
26 P: Output<S, u8>,
27 S: Integer
28 }
29 };
30
31 (u16) => {
32 impl_rng_core!(u16 impl<L> for Lcg<L, u16> where L: Copy + Into<Parameters<u16>>);
33
34 impl_rng_core! { u16
35 impl<L, P, S> for Pcg<L, P, S, u16>
36 where
37 L: Copy + Into<Parameters<S>>,
38 P: Output<S, u16>,
39 S: Integer
40 }
41 };
42
43 (u32) => {
44 impl_rng_core!(u32 impl<L> for Lcg<L, u32> where L: Copy + Into<Parameters<u32>>);
45
46 impl_rng_core! { u32
47 impl<L, P, S> for Pcg<L, P, S, u32>
48 where
49 L: Copy + Into<Parameters<S>>,
50 P: Output<S, u32>,
51 S: Integer
52 }
53 };
54
55 (u64) => {
56 impl_rng_core!(u64 impl<L> for Lcg<L, u64> where L: Copy + Into<Parameters<u64>>);
57
58 impl_rng_core! { u64
59 impl<L, P, S> for Pcg<L, P, S, u64>
60 where
61 L: Copy + Into<Parameters<S>>,
62 P: Output<S, u64>,
63 S: Integer
64 }
65 };
66
67 (u128) => {
68 impl_rng_core!(u128 impl<L> for Lcg<L, u128> where L: Copy + Into<Parameters<u128>>);
69
70 impl_rng_core! { u128
71 impl<L, P, S> for Pcg<L, P, S, u128>
72 where
73 L: Copy + Into<Parameters<S>>,
74 P: Output<S, u128>,
75 S: Integer
76 }
77 };
78
79 (usize) => {
80 impl_rng_core!(usize impl<L> for Lcg<L, usize> where L: Copy + Into<Parameters<usize>>);
81 };
82
83 (u8 impl<$($t:ident),+> for $name:ident<$($t2:ident),+> where $($tt:tt)*) => {
84 impl<$($t),+> RngCore for $name<$($t2),+>
85 where
86 $($tt)*
87 {
88 fn next_u32(&mut self) -> u32 {
89 u32::from_le_bytes([
90 self.generate(),
91 self.generate(),
92 self.generate(),
93 self.generate()
94 ])
95 }
96
97 fn next_u64(&mut self) -> u64 {
98 u64::from(self.next_u32()) | (u64::from(self.next_u32()) << 32)
99 }
100
101 fn fill_bytes(&mut self, dst: &mut [u8]) {
102 dst.iter_mut().for_each(|dst| *dst = self.generate());
103 }
104 }
105 };
106
107 (u16 impl<$($t:ident),+> for $name:ident<$($t2:ident),+> where $($tt:tt)*) => {
108 #[allow(trivial_numeric_casts)]
109 impl<$($t),+> RngCore for $name<$($t2),+>
110 where
111 $($tt)*
112 {
113 fn next_u32(&mut self) -> u32 {
114 u32::from(self.generate() as u16) | (u32::from(self.generate() as u16) << 16)
115 }
116
117 fn next_u64(&mut self) -> u64 {
118 u64::from(self.next_u32()) | (u64::from(self.next_u32()) << 32)
119 }
120
121 fn fill_bytes(&mut self, dst: &mut [u8]) {
122 fill_u16(|| self.generate() as u16, dst);
123 }
124 }
125 };
126
127 (u32 impl<$($t:ident),+> for $name:ident<$($t2:ident),+> where $($tt:tt)*) => {
128 #[allow(trivial_numeric_casts)]
129 impl<$($t),+> RngCore for $name<$($t2),+>
130 where
131 $($tt)*
132 {
133 fn next_u32(&mut self) -> u32 {
134 self.generate() as u32
135 }
136
137 fn next_u64(&mut self) -> u64 {
138 u64::from(self.next_u32()) | (u64::from(self.next_u32()) << 32)
139 }
140
141 fn fill_bytes(&mut self, dst: &mut [u8]) {
142 fill_u32(|| self.generate() as u32, dst);
143 }
144 }
145 };
146
147 (u64 impl<$($t:ident),+> for $name:ident<$($t2:ident),+> where $($tt:tt)*) => {
148 #[allow(trivial_numeric_casts)]
149 impl<$($t),+> RngCore for $name<$($t2),+>
150 where
151 $($tt)*
152 {
153 fn next_u32(&mut self) -> u32 {
154 self.next_u64() as u32
155 }
156
157 fn next_u64(&mut self) -> u64 {
158 self.generate() as u64
159 }
160
161 fn fill_bytes(&mut self, dst: &mut [u8]) {
162 fill_u64(|| self.generate() as u64, dst);
163 }
164 }
165 };
166
167 (u128 impl<$($t:ident),+> for $name:ident<$($t2:ident),+> where $($tt:tt)*) => {
168 impl<$($t),+> RngCore for $name<$($t2),+>
169 where
170 $($tt)*
171 {
172 fn next_u32(&mut self) -> u32 {
173 self.next_u64() as u32
174 }
175
176 fn next_u64(&mut self) -> u64 {
177 self.generate() as u64
178 }
179
180 fn fill_bytes(&mut self, dst: &mut [u8]) {
181 fill_u128(|| self.generate(), dst);
182 }
183 }
184 };
185
186 (usize impl<$($t:ident),+> for $name:ident<$($t2:ident),+> where $($tt:tt)*) => {
187 #[cfg(target_pointer_width = "16")]
188 impl_rng_core!(u16 impl<$($t),+> for $name<$($t2),+> where $($tt)*);
189
190 #[cfg(target_pointer_width = "32")]
191 impl_rng_core!(u32 impl<$($t),+> for $name<$($t2),+> where $($tt)*);
192
193 #[cfg(target_pointer_width = "64")]
194 impl_rng_core!(u64 impl<$($t),+> for $name<$($t2),+> where $($tt)*);
195 };
196}
197
198impl_rng_core!();
199
200macro_rules! impl_fill {
201 ($name:ident, $ty:ty) => {
202 fn $name<F>(mut generate: F, dst: &mut [u8])
203 where
204 F: FnMut() -> $ty
205 {
206 let mut dst = dst.chunks_exact_mut(size_of::<$ty>());
207
208 for dst in &mut dst {
209 let dst: &mut [u8; size_of::<$ty>()] = dst.try_into().unwrap();
210 *dst = generate().to_le_bytes();
211 }
212
213 let rem = dst.into_remainder();
214
215 if !rem.is_empty() {
216 rem.copy_from_slice(&generate().to_le_bytes()[..rem.len()]);
217 }
218 }
219 };
220}
221
222impl_fill!(fill_u16, u16);
223impl_fill!(fill_u32, u32);
224impl_fill!(fill_u64, u64);
225impl_fill!(fill_u128, u128);
226
227impl<L, S> SeedableRng for Lcg<L, S>
228where
229 L: Copy + Default + Into<Parameters<S>>,
230 S: Integer
231{
232 type Seed = S::Bytes;
233
234 fn from_seed(seed: Self::Seed) -> Self {
235 Self::new(S::from_bytes(seed))
236 }
237
238 fn seed_from_u64(state: u64) -> Self {
239 Self::new(seed_from_u64(state))
240 }
241}
242
243impl<L, P, S, O> SeedableRng for Pcg<L, P, S, O>
244where
245 L: Copy + Default + Into<Parameters<S>>,
246 P: Output<S, O>,
247 S: Integer
248{
249 type Seed = S::Bytes;
250
251 fn from_seed(seed: Self::Seed) -> Self {
252 Self::new(S::from_bytes(seed))
253 }
254
255 fn seed_from_u64(state: u64) -> Self {
256 Self::new(seed_from_u64(state))
257 }
258}
259
260fn seed_from_u64<S>(seed: u64) -> S
261where
262 S: Integer
263{
264 let [mut y, mut x] = [0x6a09e667f3bcc908 ^ seed, 0xbb67ae8584caa73b];
265
266 let mut generate = || {
267 for _ in 0..8 {
268 x = x.rotate_right(16).wrapping_add(y);
269 y = y.rotate_left(7) ^ x;
270 }
271
272 y
273 };
274
275 let _ = generate();
276
277 let mut bytes = S::Bytes::default();
278 fill_u64(generate, bytes.as_mut());
279 S::from_bytes(bytes)
280}