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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
#![no_std] use core::marker::PhantomData; use core::ptr; pub trait Random: Sized { fn random<G: ?Sized + 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 fill_bytes(&mut self, bs: &mut [u8]) { let mut p = bs.as_mut_ptr(); let mut l = bs.len(); loop { unsafe { if l >= 8 { let n = self.gen_u64(); ptr::copy_nonoverlapping(&n as *const _ as *const u8, p, 8); p = p.offset(8); l -= 8; } else { let n = self.gen_u32(); ptr::copy_nonoverlapping(&n as *const _ as *const u8, p, usize::min(4, l)); if 4 >= l { return; } p = p.offset(4); l -= 4; } } } } #[inline] fn gen<A: Random>(&mut self) -> A { A::random(self) } } impl<'a, G: RandomGen> RandomGen for &'a mut G { #[inline] fn gen_u32(&mut self) -> u32 { G::gen_u32(self) } #[inline] fn gen_u64(&mut self) -> u64 { G::gen_u64(self) } #[inline] fn gen_f32(&mut self) -> f32 { G::gen_f32(self) } #[inline] fn gen_f64(&mut self) -> f64 { G::gen_f64(self) } #[inline] fn fill_bytes(&mut self, bs: &mut [u8]) { G::fill_bytes(self, bs) } } #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Stream<G, A>(G, PhantomData<A>); impl<G, A> Stream<G, A> { #[inline] pub fn new(g: G) -> Self { Stream(g, PhantomData) } } impl<G: RandomGen, A: Random> Iterator for Stream<G, A> { type Item = A; #[inline] fn next(&mut self) -> Option<A> { Some(self.0.gen()) } } impl Random for u32 { #[inline] fn random<G: ?Sized + RandomGen>(g: &mut G) -> u32 { g.gen_u32() } } impl Random for u64 { #[inline] fn random<G: ?Sized + RandomGen>(g: &mut G) -> u64 { g.gen_u64() } } impl Random for i32 { #[inline] fn random<G: ?Sized + RandomGen>(g: &mut G) -> i32 { g.gen_u32() as _ } } impl Random for i64 { #[inline] fn random<G: ?Sized + RandomGen>(g: &mut G) -> i64 { g.gen_u64() as _ } } impl Random for f32 { #[inline] fn random<G: ?Sized + RandomGen>(g: &mut G) -> f32 { g.gen_f32() } } impl Random for f64 { #[inline] fn random<G: ?Sized + RandomGen>(g: &mut G) -> f64 { g.gen_f64() } } pub trait Seedable<Seed>: RandomGen { fn reseed(&mut self, _: Seed); fn from_seed(_: Seed) -> Self; }