Skip to main content

core/
random.rs

1//! Random value generation.
2
3use crate::ops::RangeFull;
4
5/// A source of randomness.
6#[unstable(feature = "random", issue = "130703")]
7pub trait Rng {
8    /// Fills `bytes` with random bytes.
9    ///
10    /// Note that calling `fill_bytes` multiple times is not equivalent to calling `fill_bytes` once
11    /// with a larger buffer. An `Rng` is allowed to return different bytes for those two cases. For
12    /// instance, this allows an `Rng` to generate a word at a time and throw part of it away if not
13    /// needed.
14    fn fill_bytes(&mut self, bytes: &mut [u8]);
15}
16
17/// Implements `Rng` for mutable references to random number generators by
18/// forwarding all methods to the referenced generator.
19#[unstable(feature = "random", issue = "130703")]
20impl<'a, R: Rng + ?Sized> Rng for &'a mut R {
21    fn fill_bytes(&mut self, bytes: &mut [u8]) {
22        R::fill_bytes(self, bytes);
23    }
24}
25
26/// A trait representing a distribution of random values for a type.
27#[unstable(feature = "random", issue = "130703")]
28pub trait Distribution<T> {
29    /// Samples a random value from the distribution, using the specified random source.
30    fn sample(&self, source: &mut (impl Rng + ?Sized)) -> T;
31}
32
33impl<T, DT: Distribution<T>> Distribution<T> for &DT {
34    fn sample(&self, source: &mut (impl Rng + ?Sized)) -> T {
35        (*self).sample(source)
36    }
37}
38
39impl Distribution<bool> for RangeFull {
40    fn sample(&self, source: &mut (impl Rng + ?Sized)) -> bool {
41        let byte: u8 = RangeFull.sample(source);
42        byte & 1 == 1
43    }
44}
45
46macro_rules! impl_primitive {
47    ($t:ty) => {
48        impl Distribution<$t> for RangeFull {
49            fn sample(&self, source: &mut (impl Rng + ?Sized)) -> $t {
50                let mut bytes = (0 as $t).to_ne_bytes();
51                source.fill_bytes(&mut bytes);
52                <$t>::from_ne_bytes(bytes)
53            }
54        }
55    };
56}
57
58impl_primitive!(u8);
59impl_primitive!(i8);
60impl_primitive!(u16);
61impl_primitive!(i16);
62impl_primitive!(u32);
63impl_primitive!(i32);
64impl_primitive!(u64);
65impl_primitive!(i64);
66impl_primitive!(u128);
67impl_primitive!(i128);
68impl_primitive!(usize);
69impl_primitive!(isize);