1#![no_std]
2#![recursion_limit = "130"]
3#![deny(missing_docs)]
4#![cfg_attr(test, deny(warnings))]
5
6use core::{char, mem};
18
19#[cfg(feature = "doc-comment")]
20extern crate doc_comment;
21#[cfg(feature = "doc-comment")]
22doc_comment::doctest!("../README.md");
23
24pub trait GenerateRand {
43 fn generate<R: Random + ?Sized>(rand: &mut R) -> Self;
45}
46
47pub trait Random {
88 type Error;
90
91 fn try_fill_bytes(&mut self, buf: &mut [u8]) -> Result<(), Self::Error>;
94
95 fn fill_bytes(&mut self, buf: &mut [u8]) {
98 if self.try_fill_bytes(buf).is_err() {
99 panic!("Failed getting randmness");
100 }
101 }
102
103 fn gen<T: GenerateRand>(&mut self) -> T {
105 T::generate(self)
106 }
107
108 fn get_u8(&mut self) -> u8 {
110 let mut buf = [0u8; 1];
111 self.fill_bytes(&mut buf);
112 buf[0]
113 }
114
115 fn get_u16(&mut self) -> u16 {
117 let mut buf = [0u8; 2];
118 self.fill_bytes(&mut buf);
119 unsafe { mem::transmute(buf) }
120 }
121
122 fn get_u32(&mut self) -> u32 {
124 let mut buf = [0u8; 4];
125 self.fill_bytes(&mut buf);
126 unsafe { mem::transmute(buf) }
127 }
128
129 fn get_u64(&mut self) -> u64 {
131 let mut buf = [0u8; 8];
132 self.fill_bytes(&mut buf);
133 unsafe { mem::transmute(buf) }
134 }
135
136 #[cfg(target_pointer_width = "64")]
138 fn get_usize(&mut self) -> usize {
139 self.get_u64() as usize
140 }
141
142 #[cfg(target_pointer_width = "32")]
144 fn get_usize(&mut self) -> usize {
145 self.get_u32() as usize
146 }
147
148 #[cfg(target_pointer_width = "16")]
150 fn get_usize(&mut self) -> usize {
151 self.get_u16() as usize
152 }
153
154 #[cfg(feature = "u128")]
156 fn get_u128(&mut self) -> u128 {
157 let mut buf = [0u8; 16];
158 self.fill_bytes(&mut buf);
159 unsafe { mem::transmute(buf) }
160 }
161
162 fn get_bool(&mut self) -> bool {
164 let bit = self.get_u8() & 0b1000_0000;
166 debug_assert!(bit < 2);
167 bit == 1
168 }
169}
170
171impl GenerateRand for u8 {
172 #[inline]
173 fn generate<R: Random + ?Sized>(rand: &mut R) -> Self {
174 rand.get_u8()
175 }
176}
177
178impl GenerateRand for u16 {
179 #[inline]
180 fn generate<R: Random + ?Sized>(rand: &mut R) -> Self {
181 rand.get_u16()
182 }
183}
184
185impl GenerateRand for u32 {
186 #[inline]
187 fn generate<R: Random + ?Sized>(rand: &mut R) -> Self {
188 rand.get_u32()
189 }
190}
191
192impl GenerateRand for u64 {
193 #[inline]
194 fn generate<R: Random + ?Sized>(rand: &mut R) -> Self {
195 rand.get_u64()
196 }
197}
198
199impl GenerateRand for usize {
200 #[inline]
201 fn generate<R: Random + ?Sized>(rand: &mut R) -> Self {
202 rand.get_usize()
203 }
204}
205
206#[cfg(feature = "u128")]
207impl GenerateRand for u128 {
208 #[inline]
209 fn generate<R: Random + ?Sized>(rand: &mut R) -> Self {
210 rand.get_u128()
211 }
212}
213
214impl GenerateRand for char {
215 #[inline]
216 fn generate<R: Random + ?Sized>(rand: &mut R) -> Self {
217 loop {
218 if let Some(c) = char::from_u32(rand.get_u32()) {
219 return c;
220 }
221 }
222 }
223}
224
225impl GenerateRand for bool {
226 #[inline]
227 fn generate<R: Random + ?Sized>(rand: &mut R) -> Self {
228 rand.get_bool()
229 }
230}
231
232impl GenerateRand for f64 {
235 fn generate<R: Random + ?Sized>(rand: &mut R) -> Self {
236 let mut exponent: i32 = -64;
237 let mut significand = rand.get_u64();
238 while significand == 0 {
239 exponent -= 64;
240 if exponent < -1074i32 {
241 unreachable!("The randomness is broken, got 0 16 times. (prob of 1/2^1024)");
244 }
245 significand = rand.get_u64();
246 }
247
248 let shift = significand.leading_zeros() as i32;
250 if shift > 0 {
251 exponent -= shift;
252 significand <<= shift;
253 significand |= rand.get_u64() >> (64 - shift);
254 }
255 significand |= 1;
257
258 significand as f64 * exp2(exponent)
260 }
261}
262
263impl GenerateRand for f32 {
266 fn generate<R: Random + ?Sized>(rand: &mut R) -> Self {
267 let mut exponent: i32 = -32;
268 let mut significand = rand.get_u32();
269 while significand == 0 {
270 exponent -= 32;
271 if exponent < -149i32 {
272 unreachable!("The randomness is broken, got 0 5 times. (prob of 1/2^160)");
275 }
277 significand = rand.get_u32();
278 }
279
280 let shift = significand.leading_zeros() as i32;
282 if shift != 0 {
283 exponent -= shift;
284 significand <<= shift;
285 significand |= rand.get_u32() >> (32 - shift);
286 }
287 significand |= 1;
289
290 significand as f32 * exp2f(exponent)
292 }
293}
294
295fn exp2f(exp: i32) -> f32 {
298 debug_assert!(exp > -127);
299 let bits = ((127i32 + exp) as u32) << 23u32;
300 unsafe { mem::transmute(bits) } }
302fn exp2(exp: i32) -> f64 {
303 debug_assert!(exp > -1023);
304 let bits = ((1023i32 + exp) as u64) << 52u64;
305 unsafe { mem::transmute(bits) } }
307
308macro_rules! impl_generate_rand_ifromu {
311 ($ity:ty, $uty: ty) => {
312 impl GenerateRand for $ity {
313 #[inline]
314 fn generate<R: Random + ?Sized>(rand: &mut R) -> Self {
315 debug_assert_eq!(mem::size_of::<$ity>(), mem::size_of::<$uty>());
316 <$uty>::generate(rand) as $ity
317 }
318 }
319 };
320}
321
322impl_generate_rand_ifromu! {i8, u8}
323impl_generate_rand_ifromu! {i16, u16}
324impl_generate_rand_ifromu! {i32, u32}
325impl_generate_rand_ifromu! {i64, u64}
326impl_generate_rand_ifromu! {isize, usize}
327#[cfg(feature = "u128")]
328impl_generate_rand_ifromu! {i128, u128}
329
330macro_rules! array_impls {
332 {$N:expr, $t:ident $($ts:ident)*} => {
333 impl<T: GenerateRand> GenerateRand for [T; $N] {
334 #[inline]
335 fn generate<R: Random + ?Sized>(rand: &mut R) -> Self {
336 [rand.gen::<$t>(), $(rand.gen::<$ts>()),*]
337 }
338 }
339 array_impls!{($N - 1), $($ts)*}
340 };
341 {$N:expr,} => {
342 impl<T: GenerateRand> GenerateRand for [T; $N] {
343 #[inline]
344 fn generate<R: Random + ?Sized>(_: &mut R) -> Self { [] }
345 }
346 };
347}
348
349array_impls! {128, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
350T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T}
351
352macro_rules! tuple_impls {
353 ($(
354 ($($T:ident),+),
355 )+) => {
356 $(
357 impl<$($T: GenerateRand),+> GenerateRand for ($($T,)+) {
358 #[inline]
359 fn generate<R: Random + ?Sized>(rand: &mut R) -> Self {
360 ($({ let x: $T = rand.gen(); x},)+)
361 }
362 }
363 )+
364 }
365}
366
367tuple_impls! {
368 (A),
369 (A, B),
370 (A, B, C),
371 (A, B, C, D),
372 (A, B, C, D, E),
373 (A, B, C, D, E, F),
374 (A, B, C, D, E, F, G),
375 (A, B, C, D, E, F, G, H),
376 (A, B, C, D, E, F, G, H, I),
377 (A, B, C, D, E, F, G, H, I, J),
378 (A, B, C, D, E, F, G, H, I, J, K),
379 (A, B, C, D, E, F, G, H, I, J, K, L),
380 (A, B, C, D, E, F, G, H, I, J, K, L, M),
381 (A, B, C, D, E, F, G, H, I, J, K, L, M, N),
382 (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O),
383 (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P),
384}