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