1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
#![no_std] use core::ptr; pub trait Random: Sized { fn random<G: RandomGen>(g: &mut G) -> Self; } pub trait RandomGen { #[inline] fn gen_u32(&mut self) -> u32 { self.gen_u64() as u32 } #[inline] fn gen_u64(&mut self) -> u64 { (self.gen_u32() as u64) << 32 | (self.gen_u32() as u64) } #[inline] fn gen_f32(&mut self) -> f32 { (self.gen_u32() >> 8) as f32 / (1u64 << 24) as f32 } #[inline] fn gen_f64(&mut self) -> f64 { (self.gen_u64() >> 11) as f64 / (1u64 << 53) as f64 } #[inline] fn gen_bytes(&mut self, bs: &mut [u8]) -> usize { let l0 = bs.len(); let mut p = bs.as_mut_ptr(); let q = &mut bs[l0] as *mut _; loop { unsafe { let l = (p as usize) - (q as usize); if l >= 8 { let n = self.gen_u64(); ptr::copy_nonoverlapping(&n as *const _ as *const u8, p, 8); p = p.offset(8); } else { let n = self.gen_u32(); ptr::copy_nonoverlapping(&n as *const _ as *const u8, p, usize::min(4, l)); if l >= 4 { return l0; } p = p.offset(4); } } } } }