]> git.proxmox.com Git - rustc.git/blame - src/librand/rand_impls.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / librand / rand_impls.rs
CommitLineData
1a4d82fc
JJ
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
1a4d82fc 13use core::char;
54a0048b 14use core::mem;
1a4d82fc 15
b039eaaf 16use {Rand, Rng};
1a4d82fc 17
c34b1796 18impl Rand for isize {
1a4d82fc 19 #[inline]
c34b1796 20 fn rand<R: Rng>(rng: &mut R) -> isize {
54a0048b 21 if mem::size_of::<isize>() == 4 {
c34b1796 22 rng.gen::<i32>() as isize
1a4d82fc 23 } else {
c34b1796 24 rng.gen::<i64>() as isize
1a4d82fc
JJ
25 }
26 }
27}
28
29impl Rand for i8 {
30 #[inline]
31 fn rand<R: Rng>(rng: &mut R) -> i8 {
32 rng.next_u32() as i8
33 }
34}
35
36impl Rand for i16 {
37 #[inline]
38 fn rand<R: Rng>(rng: &mut R) -> i16 {
39 rng.next_u32() as i16
40 }
41}
42
43impl Rand for i32 {
44 #[inline]
45 fn rand<R: Rng>(rng: &mut R) -> i32 {
46 rng.next_u32() as i32
47 }
48}
49
50impl Rand for i64 {
51 #[inline]
52 fn rand<R: Rng>(rng: &mut R) -> i64 {
53 rng.next_u64() as i64
54 }
55}
56
c34b1796 57impl Rand for usize {
1a4d82fc 58 #[inline]
c34b1796 59 fn rand<R: Rng>(rng: &mut R) -> usize {
54a0048b 60 if mem::size_of::<usize>() == 4 {
c34b1796 61 rng.gen::<u32>() as usize
1a4d82fc 62 } else {
c34b1796 63 rng.gen::<u64>() as usize
1a4d82fc
JJ
64 }
65 }
66}
67
68impl Rand for u8 {
69 #[inline]
70 fn rand<R: Rng>(rng: &mut R) -> u8 {
71 rng.next_u32() as u8
72 }
73}
74
75impl Rand for u16 {
76 #[inline]
77 fn rand<R: Rng>(rng: &mut R) -> u16 {
78 rng.next_u32() as u16
79 }
80}
81
82impl Rand for u32 {
83 #[inline]
84 fn rand<R: Rng>(rng: &mut R) -> u32 {
85 rng.next_u32()
86 }
87}
88
89impl Rand for u64 {
90 #[inline]
91 fn rand<R: Rng>(rng: &mut R) -> u64 {
92 rng.next_u64()
93 }
94}
95
96macro_rules! float_impls {
97 ($mod_name:ident, $ty:ty, $mantissa_bits:expr, $method_name:ident) => {
98 mod $mod_name {
99 use {Rand, Rng, Open01, Closed01};
100
101 const SCALE: $ty = (1u64 << $mantissa_bits) as $ty;
102
103 impl Rand for $ty {
104 /// Generate a floating point number in the half-open
105 /// interval `[0,1)`.
106 ///
107 /// See `Closed01` for the closed interval `[0,1]`,
108 /// and `Open01` for the open interval `(0,1)`.
109 #[inline]
110 fn rand<R: Rng>(rng: &mut R) -> $ty {
111 rng.$method_name()
112 }
113 }
114 impl Rand for Open01<$ty> {
115 #[inline]
116 fn rand<R: Rng>(rng: &mut R) -> Open01<$ty> {
117 // add a small amount (specifically 2 bits below
118 // the precision of f64/f32 at 1.0), so that small
119 // numbers are larger than 0, but large numbers
120 // aren't pushed to/above 1.
121 Open01(rng.$method_name() + 0.25 / SCALE)
122 }
123 }
124 impl Rand for Closed01<$ty> {
125 #[inline]
126 fn rand<R: Rng>(rng: &mut R) -> Closed01<$ty> {
127 // rescale so that 1.0 - epsilon becomes 1.0
128 // precisely.
129 Closed01(rng.$method_name() * SCALE / (SCALE - 1.0))
130 }
131 }
132 }
133 }
134}
135float_impls! { f64_rand_impls, f64, 53, next_f64 }
136float_impls! { f32_rand_impls, f32, 24, next_f32 }
137
138impl Rand for char {
139 #[inline]
140 fn rand<R: Rng>(rng: &mut R) -> char {
141 // a char is 21 bits
c34b1796 142 const CHAR_MASK: u32 = 0x001f_ffff;
1a4d82fc
JJ
143 loop {
144 // Rejection sampling. About 0.2% of numbers with at most
145 // 21-bits are invalid codepoints (surrogates), so this
146 // will succeed first go almost every time.
147 match char::from_u32(rng.next_u32() & CHAR_MASK) {
148 Some(c) => return c,
149 None => {}
150 }
151 }
152 }
153}
154
155impl Rand for bool {
156 #[inline]
157 fn rand<R: Rng>(rng: &mut R) -> bool {
158 rng.gen::<u8>() & 1 == 1
159 }
160}
161
162macro_rules! tuple_impl {
163 // use variables to indicate the arity of the tuple
164 ($($tyvar:ident),* ) => {
165 // the trailing commas are for the 1 tuple
166 impl<
167 $( $tyvar : Rand ),*
168 > Rand for ( $( $tyvar ),* , ) {
169
170 #[inline]
171 fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) {
172 (
173 // use the $tyvar's to get the appropriate number of
174 // repeats (they're not actually needed)
175 $(
176 _rng.gen::<$tyvar>()
177 ),*
178 ,
179 )
180 }
181 }
182 }
183}
184
185impl Rand for () {
186 #[inline]
b039eaaf
SL
187 fn rand<R: Rng>(_: &mut R) -> () {
188 ()
189 }
1a4d82fc
JJ
190}
191tuple_impl!{A}
192tuple_impl!{A, B}
193tuple_impl!{A, B, C}
194tuple_impl!{A, B, C, D}
195tuple_impl!{A, B, C, D, E}
196tuple_impl!{A, B, C, D, E, F}
197tuple_impl!{A, B, C, D, E, F, G}
198tuple_impl!{A, B, C, D, E, F, G, H}
199tuple_impl!{A, B, C, D, E, F, G, H, I}
200tuple_impl!{A, B, C, D, E, F, G, H, I, J}
201tuple_impl!{A, B, C, D, E, F, G, H, I, J, K}
202tuple_impl!{A, B, C, D, E, F, G, H, I, J, K, L}
203
92a42be0 204impl<T: Rand> Rand for Option<T> {
1a4d82fc
JJ
205 #[inline]
206 fn rand<R: Rng>(rng: &mut R) -> Option<T> {
207 if rng.gen() {
208 Some(rng.gen())
209 } else {
210 None
211 }
212 }
213}