pcg_random/
rand.rs

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}