Skip to content

Commit efcd769

Browse files
committed
Move remaining Rand impls to the Uniform distribution
1 parent 8a556fa commit efcd769

File tree

4 files changed

+86
-98
lines changed

4 files changed

+86
-98
lines changed

src/distributions/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,14 @@ impl<'a, T, D: Distribution<T>> Distribution<T> for &'a D {
156156
/// [`StandardNormal`] distributions produce floating point numbers with
157157
/// alternative ranges or distributions.)
158158
///
159+
/// The following aggregate types also implement the distribution `Uniform` as
160+
/// long as their component types implement it:
161+
///
162+
/// * Tuples and arrays: Each element of the tuple or array is generated
163+
/// independently, using the `Uniform` distribution recursively.
164+
/// * `Option<T>`: Returns `None` with probability 0.5; otherwise generates a
165+
/// random `T` and returns `Some(T)`.
166+
///
159167
/// # Example
160168
/// ```rust
161169
/// use rand::{weak_rng, Rng};

src/distributions/other.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,78 @@ impl Distribution<bool> for Uniform {
3838
rng.gen::<u8>() & 1 == 1
3939
}
4040
}
41+
42+
macro_rules! tuple_impl {
43+
// use variables to indicate the arity of the tuple
44+
($($tyvar:ident),* ) => {
45+
// the trailing commas are for the 1 tuple
46+
impl< $( $tyvar ),* >
47+
Distribution<( $( $tyvar ),* , )>
48+
for Uniform
49+
where $( Uniform: Distribution<$tyvar> ),*
50+
{
51+
#[inline]
52+
fn sample<R: Rng>(&self, _rng: &mut R) -> ( $( $tyvar ),* , ) {
53+
(
54+
// use the $tyvar's to get the appropriate number of
55+
// repeats (they're not actually needed)
56+
$(
57+
_rng.gen::<$tyvar>()
58+
),*
59+
,
60+
)
61+
}
62+
}
63+
}
64+
}
65+
66+
impl Distribution<()> for Uniform {
67+
#[inline]
68+
fn sample<R: Rng>(&self, _: &mut R) -> () { () }
69+
}
70+
tuple_impl!{A}
71+
tuple_impl!{A, B}
72+
tuple_impl!{A, B, C}
73+
tuple_impl!{A, B, C, D}
74+
tuple_impl!{A, B, C, D, E}
75+
tuple_impl!{A, B, C, D, E, F}
76+
tuple_impl!{A, B, C, D, E, F, G}
77+
tuple_impl!{A, B, C, D, E, F, G, H}
78+
tuple_impl!{A, B, C, D, E, F, G, H, I}
79+
tuple_impl!{A, B, C, D, E, F, G, H, I, J}
80+
tuple_impl!{A, B, C, D, E, F, G, H, I, J, K}
81+
tuple_impl!{A, B, C, D, E, F, G, H, I, J, K, L}
82+
83+
macro_rules! array_impl {
84+
// recursive, given at least one type parameter:
85+
{$n:expr, $t:ident, $($ts:ident,)*} => {
86+
array_impl!{($n - 1), $($ts,)*}
87+
88+
impl<T> Distribution<[T; $n]> for Uniform where Uniform: Distribution<T> {
89+
#[inline]
90+
fn sample<R: Rng>(&self, _rng: &mut R) -> [T; $n] {
91+
[_rng.gen::<$t>(), $(_rng.gen::<$ts>()),*]
92+
}
93+
}
94+
};
95+
// empty case:
96+
{$n:expr,} => {
97+
impl<T> Distribution<[T; $n]> for Uniform {
98+
fn sample<R: Rng>(&self, _rng: &mut R) -> [T; $n] { [] }
99+
}
100+
};
101+
}
102+
103+
array_impl!{32, 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,}
104+
105+
impl<T> Distribution<Option<T>> for Uniform where Uniform: Distribution<T> {
106+
#[inline]
107+
fn sample<R: Rng>(&self, rng: &mut R) -> Option<T> {
108+
// UFCS is needed here: https://github.com/rust-lang/rust/issues/24066
109+
if rng.gen::<bool>() {
110+
Some(rng.gen())
111+
} else {
112+
None
113+
}
114+
}
115+
}

src/lib.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -312,24 +312,13 @@ pub mod isaac {
312312
// private modules
313313
mod le;
314314
mod error;
315-
mod rand_impls;
316315
mod prng;
317316

318317

319318
/// A type that can be randomly generated using an `Rng`.
320-
///
321-
/// ## Built-in Implementations
322-
///
323-
/// `Rand` is implemented for any type supporting the [`Uniform`] distribution.
324-
/// That includes: integers, floating point numbers, char, boolean.
325-
///
326-
/// The following aggregate types also implement `Rand` as long as their
327-
/// component types implement it:
328-
///
329-
/// * Tuples and arrays: Each element of the tuple or array is generated
330-
/// independently, using its own `Rand` implementation.
331-
/// * `Option<T>`: Returns `None` with probability 0.5; otherwise generates a
332-
/// random `T` and returns `Some(T)`.
319+
///
320+
/// This is merely an adaptor around the [`Uniform`] distribution for
321+
/// convenience and backwards-compatibility.
333322
///
334323
/// [`Uniform`]: distributions/struct.Uniform.html
335324
pub trait Rand : Sized {

src/rand_impls.rs

Lines changed: 0 additions & 84 deletions
This file was deleted.

0 commit comments

Comments
 (0)