1 // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 
11 //! The implementations of `Rand` for the built-in types.
12 
13 use core::{char, mem};
14 
15 use {Rand,Rng};
16 
17 impl Rand for isize {
18     #[inline]
rand<R: Rng>(rng: &mut R) -> isize19     fn rand<R: Rng>(rng: &mut R) -> isize {
20         if mem::size_of::<isize>() == 4 {
21             rng.gen::<i32>() as isize
22         } else {
23             rng.gen::<i64>() as isize
24         }
25     }
26 }
27 
28 impl Rand for i8 {
29     #[inline]
rand<R: Rng>(rng: &mut R) -> i830     fn rand<R: Rng>(rng: &mut R) -> i8 {
31         rng.next_u32() as i8
32     }
33 }
34 
35 impl Rand for i16 {
36     #[inline]
rand<R: Rng>(rng: &mut R) -> i1637     fn rand<R: Rng>(rng: &mut R) -> i16 {
38         rng.next_u32() as i16
39     }
40 }
41 
42 impl Rand for i32 {
43     #[inline]
rand<R: Rng>(rng: &mut R) -> i3244     fn rand<R: Rng>(rng: &mut R) -> i32 {
45         rng.next_u32() as i32
46     }
47 }
48 
49 impl Rand for i64 {
50     #[inline]
rand<R: Rng>(rng: &mut R) -> i6451     fn rand<R: Rng>(rng: &mut R) -> i64 {
52         rng.next_u64() as i64
53     }
54 }
55 
56 #[cfg(feature = "i128_support")]
57 impl Rand for i128 {
58     #[inline]
rand<R: Rng>(rng: &mut R) -> i12859     fn rand<R: Rng>(rng: &mut R) -> i128 {
60         rng.gen::<u128>() as i128
61     }
62 }
63 
64 impl Rand for usize {
65     #[inline]
rand<R: Rng>(rng: &mut R) -> usize66     fn rand<R: Rng>(rng: &mut R) -> usize {
67         if mem::size_of::<usize>() == 4 {
68             rng.gen::<u32>() as usize
69         } else {
70             rng.gen::<u64>() as usize
71         }
72     }
73 }
74 
75 impl Rand for u8 {
76     #[inline]
rand<R: Rng>(rng: &mut R) -> u877     fn rand<R: Rng>(rng: &mut R) -> u8 {
78         rng.next_u32() as u8
79     }
80 }
81 
82 impl Rand for u16 {
83     #[inline]
rand<R: Rng>(rng: &mut R) -> u1684     fn rand<R: Rng>(rng: &mut R) -> u16 {
85         rng.next_u32() as u16
86     }
87 }
88 
89 impl Rand for u32 {
90     #[inline]
rand<R: Rng>(rng: &mut R) -> u3291     fn rand<R: Rng>(rng: &mut R) -> u32 {
92         rng.next_u32()
93     }
94 }
95 
96 impl Rand for u64 {
97     #[inline]
rand<R: Rng>(rng: &mut R) -> u6498     fn rand<R: Rng>(rng: &mut R) -> u64 {
99         rng.next_u64()
100     }
101 }
102 
103 #[cfg(feature = "i128_support")]
104 impl Rand for u128 {
105     #[inline]
rand<R: Rng>(rng: &mut R) -> u128106     fn rand<R: Rng>(rng: &mut R) -> u128 {
107         ((rng.next_u64() as u128) << 64) | (rng.next_u64() as u128)
108     }
109 }
110 
111 
112 macro_rules! float_impls {
113     ($mod_name:ident, $ty:ty, $mantissa_bits:expr, $method_name:ident) => {
114         mod $mod_name {
115             use {Rand, Rng, Open01, Closed01};
116 
117             const SCALE: $ty = (1u64 << $mantissa_bits) as $ty;
118 
119             impl Rand for $ty {
120                 /// Generate a floating point number in the half-open
121                 /// interval `[0,1)`.
122                 ///
123                 /// See `Closed01` for the closed interval `[0,1]`,
124                 /// and `Open01` for the open interval `(0,1)`.
125                 #[inline]
126                 fn rand<R: Rng>(rng: &mut R) -> $ty {
127                     rng.$method_name()
128                 }
129             }
130             impl Rand for Open01<$ty> {
131                 #[inline]
132                 fn rand<R: Rng>(rng: &mut R) -> Open01<$ty> {
133                     // add a small amount (specifically 2 bits below
134                     // the precision of f64/f32 at 1.0), so that small
135                     // numbers are larger than 0, but large numbers
136                     // aren't pushed to/above 1.
137                     Open01(rng.$method_name() + 0.25 / SCALE)
138                 }
139             }
140             impl Rand for Closed01<$ty> {
141                 #[inline]
142                 fn rand<R: Rng>(rng: &mut R) -> Closed01<$ty> {
143                     // rescale so that 1.0 - epsilon becomes 1.0
144                     // precisely.
145                     Closed01(rng.$method_name() * SCALE / (SCALE - 1.0))
146                 }
147             }
148         }
149     }
150 }
151 float_impls! { f64_rand_impls, f64, 53, next_f64 }
152 float_impls! { f32_rand_impls, f32, 24, next_f32 }
153 
154 impl Rand for char {
155     #[inline]
rand<R: Rng>(rng: &mut R) -> char156     fn rand<R: Rng>(rng: &mut R) -> char {
157         // a char is 21 bits
158         const CHAR_MASK: u32 = 0x001f_ffff;
159         loop {
160             // Rejection sampling. About 0.2% of numbers with at most
161             // 21-bits are invalid codepoints (surrogates), so this
162             // will succeed first go almost every time.
163             match char::from_u32(rng.next_u32() & CHAR_MASK) {
164                 Some(c) => return c,
165                 None => {}
166             }
167         }
168     }
169 }
170 
171 impl Rand for bool {
172     #[inline]
rand<R: Rng>(rng: &mut R) -> bool173     fn rand<R: Rng>(rng: &mut R) -> bool {
174         rng.gen::<u8>() & 1 == 1
175     }
176 }
177 
178 macro_rules! tuple_impl {
179     // use variables to indicate the arity of the tuple
180     ($($tyvar:ident),* ) => {
181         // the trailing commas are for the 1 tuple
182         impl<
183             $( $tyvar : Rand ),*
184             > Rand for ( $( $tyvar ),* , ) {
185 
186             #[inline]
187             fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) {
188                 (
189                     // use the $tyvar's to get the appropriate number of
190                     // repeats (they're not actually needed)
191                     $(
192                         _rng.gen::<$tyvar>()
193                     ),*
194                     ,
195                 )
196             }
197         }
198     }
199 }
200 
201 impl Rand for () {
202     #[inline]
rand<R: Rng>(_: &mut R) -> ()203     fn rand<R: Rng>(_: &mut R) -> () { () }
204 }
205 tuple_impl!{A}
206 tuple_impl!{A, B}
207 tuple_impl!{A, B, C}
208 tuple_impl!{A, B, C, D}
209 tuple_impl!{A, B, C, D, E}
210 tuple_impl!{A, B, C, D, E, F}
211 tuple_impl!{A, B, C, D, E, F, G}
212 tuple_impl!{A, B, C, D, E, F, G, H}
213 tuple_impl!{A, B, C, D, E, F, G, H, I}
214 tuple_impl!{A, B, C, D, E, F, G, H, I, J}
215 tuple_impl!{A, B, C, D, E, F, G, H, I, J, K}
216 tuple_impl!{A, B, C, D, E, F, G, H, I, J, K, L}
217 
218 macro_rules! array_impl {
219     {$n:expr, $t:ident, $($ts:ident,)*} => {
220         array_impl!{($n - 1), $($ts,)*}
221 
222         impl<T> Rand for [T; $n] where T: Rand {
223             #[inline]
224             fn rand<R: Rng>(_rng: &mut R) -> [T; $n] {
225                 [_rng.gen::<$t>(), $(_rng.gen::<$ts>()),*]
226             }
227         }
228     };
229     {$n:expr,} => {
230         impl<T> Rand for [T; $n] {
231             fn rand<R: Rng>(_rng: &mut R) -> [T; $n] { [] }
232         }
233     };
234 }
235 
236 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,}
237 
238 impl<T:Rand> Rand for Option<T> {
239     #[inline]
rand<R: Rng>(rng: &mut R) -> Option<T>240     fn rand<R: Rng>(rng: &mut R) -> Option<T> {
241         if rng.gen() {
242             Some(rng.gen())
243         } else {
244             None
245         }
246     }
247 }
248 
249 #[cfg(test)]
250 mod tests {
251     use {Rng, thread_rng, Open01, Closed01};
252 
253     struct ConstantRng(u64);
254     impl Rng for ConstantRng {
next_u32(&mut self) -> u32255         fn next_u32(&mut self) -> u32 {
256             let ConstantRng(v) = *self;
257             v as u32
258         }
next_u64(&mut self) -> u64259         fn next_u64(&mut self) -> u64 {
260             let ConstantRng(v) = *self;
261             v
262         }
263     }
264 
265     #[test]
floating_point_edge_cases()266     fn floating_point_edge_cases() {
267         // the test for exact equality is correct here.
268         assert!(ConstantRng(0xffff_ffff).gen::<f32>() != 1.0);
269         assert!(ConstantRng(0xffff_ffff_ffff_ffff).gen::<f64>() != 1.0);
270     }
271 
272     #[test]
rand_open()273     fn rand_open() {
274         // this is unlikely to catch an incorrect implementation that
275         // generates exactly 0 or 1, but it keeps it sane.
276         let mut rng = thread_rng();
277         for _ in 0..1_000 {
278             // strict inequalities
279             let Open01(f) = rng.gen::<Open01<f64>>();
280             assert!(0.0 < f && f < 1.0);
281 
282             let Open01(f) = rng.gen::<Open01<f32>>();
283             assert!(0.0 < f && f < 1.0);
284         }
285     }
286 
287     #[test]
rand_closed()288     fn rand_closed() {
289         let mut rng = thread_rng();
290         for _ in 0..1_000 {
291             // strict inequalities
292             let Closed01(f) = rng.gen::<Closed01<f64>>();
293             assert!(0.0 <= f && f <= 1.0);
294 
295             let Closed01(f) = rng.gen::<Closed01<f32>>();
296             assert!(0.0 <= f && f <= 1.0);
297         }
298     }
299 }
300