(index<- ) ./libstd/rand/rand_impls.rs
1 // Copyright 2013 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 char;
14 use int;
15 use option::{Option, Some, None};
16 use rand::{Rand,Rng};
17 use uint;
18
19 impl Rand for int {
20 #[inline]
21 fn rand<R: Rng>(rng: &mut R) -> int {
22 if int::bits == 32 {
23 rng.gen::<i32>() as int
24 } else {
25 rng.gen::<i64>() as int
26 }
27 }
28 }
29
30 impl Rand for i8 {
31 #[inline]
32 fn rand<R: Rng>(rng: &mut R) -> i8 {
33 rng.next_u32() as i8
34 }
35 }
36
37 impl Rand for i16 {
38 #[inline]
39 fn rand<R: Rng>(rng: &mut R) -> i16 {
40 rng.next_u32() as i16
41 }
42 }
43
44 impl Rand for i32 {
45 #[inline]
46 fn rand<R: Rng>(rng: &mut R) -> i32 {
47 rng.next_u32() as i32
48 }
49 }
50
51 impl Rand for i64 {
52 #[inline]
53 fn rand<R: Rng>(rng: &mut R) -> i64 {
54 rng.next_u64() as i64
55 }
56 }
57
58 impl Rand for uint {
59 #[inline]
60 fn rand<R: Rng>(rng: &mut R) -> uint {
61 if uint::bits == 32 {
62 rng.gen::<u32>() as uint
63 } else {
64 rng.gen::<u64>() as uint
65 }
66 }
67 }
68
69 impl Rand for u8 {
70 #[inline]
71 fn rand<R: Rng>(rng: &mut R) -> u8 {
72 rng.next_u32() as u8
73 }
74 }
75
76 impl Rand for u16 {
77 #[inline]
78 fn rand<R: Rng>(rng: &mut R) -> u16 {
79 rng.next_u32() as u16
80 }
81 }
82
83 impl Rand for u32 {
84 #[inline]
85 fn rand<R: Rng>(rng: &mut R) -> u32 {
86 rng.next_u32()
87 }
88 }
89
90 impl Rand for u64 {
91 #[inline]
92 fn rand<R: Rng>(rng: &mut R) -> u64 {
93 rng.next_u64()
94 }
95 }
96
97 impl Rand for f32 {
98 /// A random `f32` in the range `[0, 1)`, using 24 bits of
99 /// precision.
100 #[inline]
101 fn rand<R: Rng>(rng: &mut R) -> f32 {
102 // using any more than 24 bits will cause (e.g.) 0xffff_ffff
103 // to correspond to 1 exactly, so we need to drop 8 to
104 // guarantee the open end.
105
106 static SCALE: f32 = (1u32 << 24) as f32;
107 (rng.next_u32() >> 8) as f32 / SCALE
108 }
109 }
110
111 impl Rand for f64 {
112 /// A random `f64` in the range `[0, 1)`, using 53 bits of
113 /// precision.
114 #[inline]
115 fn rand<R: Rng>(rng: &mut R) -> f64 {
116 // as for f32, but using more bits.
117
118 static SCALE: f64 = (1u64 << 53) as f64;
119 (rng.next_u64() >> 11) as f64 / SCALE
120 }
121 }
122
123
124 impl Rand for char {
125 #[inline]
126 fn rand<R: Rng>(rng: &mut R) -> char {
127 // a char is 21 bits
128 static CHAR_MASK: u32 = 0x001f_ffff;
129 loop {
130 // Rejection sampling. About 0.2% of numbers with at most
131 // 21-bits are invalid codepoints (surrogates), so this
132 // will succeed first go almost every time.
133 match char::from_u32(rng.next_u32() & CHAR_MASK) {
134 Some(c) => return c,
135 None => {}
136 }
137 }
138 }
139 }
140
141 impl Rand for bool {
142 #[inline]
143 fn rand<R: Rng>(rng: &mut R) -> bool {
144 rng.gen::<u8>() & 1 == 1
145 }
146 }
147
148 macro_rules! tuple_impl {
149 // use variables to indicate the arity of the tuple
150 ($($tyvar:ident),* ) => {
151 // the trailing commas are for the 1 tuple
152 impl<
153 $( $tyvar : Rand ),*
154 > Rand for ( $( $tyvar ),* , ) {
155
156 #[inline]
157 fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) {
158 (
159 // use the $tyvar's to get the appropriate number of
160 // repeats (they're not actually needed)
161 $(
162 _rng.gen::<$tyvar>()
163 ),*
164 ,
165 )
166 }
167 }
168 }
169 }
170
171 impl Rand for () {
172 #[inline]
173 fn rand<R: Rng>(_: &mut R) -> () { () }
174 }
175 tuple_impl!{A}
176 tuple_impl!{A, B}
177 tuple_impl!{A, B, C}
178 tuple_impl!{A, B, C, D}
179 tuple_impl!{A, B, C, D, E}
180 tuple_impl!{A, B, C, D, E, F}
181 tuple_impl!{A, B, C, D, E, F, G}
182 tuple_impl!{A, B, C, D, E, F, G, H}
183 tuple_impl!{A, B, C, D, E, F, G, H, I}
184 tuple_impl!{A, B, C, D, E, F, G, H, I, J}
185
186 impl<T:Rand> Rand for Option<T> {
187 #[inline]
188 fn rand<R: Rng>(rng: &mut R) -> Option<T> {
189 if rng.gen() {
190 Some(rng.gen())
191 } else {
192 None
193 }
194 }
195 }
196
197 impl<T: Rand> Rand for ~T {
198 #[inline]
199 fn rand<R: Rng>(rng: &mut R) -> ~T { ~rng.gen() }
200 }
201
202 impl<T: Rand + 'static> Rand for @T {
203 #[inline]
204 fn rand<R: Rng>(rng: &mut R) -> @T { @rng.gen() }
205 }
206
207 #[cfg(test)]
208 mod tests {
209 use rand::Rng;
210 struct ConstantRng(u64);
211 impl Rng for ConstantRng {
212 fn next_u32(&mut self) -> u32 {
213 (**self) as u32
214 }
215 fn next_u64(&mut self) -> u64 {
216 **self
217 }
218 }
219 fn floating_point_edge_cases() {
220 // the test for exact equality is correct here.
221 assert!(ConstantRng(0xffff_ffff).gen::<f32>() != 1.0)
222 assert!(ConstantRng(0xffff_ffff_ffff_ffff).gen::<f64>() != 1.0)
223 }
224 }