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.
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.
11 //! The implementations of `Rand` for the built-in types.
20 fn rand
<R
: Rng
>(rng
: &mut R
) -> isize {
21 if mem
::size_of
::<isize>() == 4 {
22 rng
.gen
::<i32>() as isize
24 rng
.gen
::<i64>() as isize
31 fn rand
<R
: Rng
>(rng
: &mut R
) -> i8 {
38 fn rand
<R
: Rng
>(rng
: &mut R
) -> i16 {
45 fn rand
<R
: Rng
>(rng
: &mut R
) -> i32 {
52 fn rand
<R
: Rng
>(rng
: &mut R
) -> i64 {
57 #[cfg(feature = "i128_support")]
60 fn rand
<R
: Rng
>(rng
: &mut R
) -> i128
{
61 rng
.gen
::<u128
>() as i128
67 fn rand
<R
: Rng
>(rng
: &mut R
) -> usize {
68 if mem
::size_of
::<usize>() == 4 {
69 rng
.gen
::<u32>() as usize
71 rng
.gen
::<u64>() as usize
78 fn rand
<R
: Rng
>(rng
: &mut R
) -> u8 {
85 fn rand
<R
: Rng
>(rng
: &mut R
) -> u16 {
92 fn rand
<R
: Rng
>(rng
: &mut R
) -> u32 {
99 fn rand
<R
: Rng
>(rng
: &mut R
) -> u64 {
104 #[cfg(feature = "i128_support")]
107 fn rand
<R
: Rng
>(rng
: &mut R
) -> u128
{
108 ((rng
.next_u64() as u128
) << 64) | (rng
.next_u64() as u128
)
113 macro_rules
! float_impls
{
114 ($mod_name
:ident
, $ty
:ty
, $mantissa_bits
:expr
, $method_name
:ident
) => {
116 use {Rand, Rng, Open01, Closed01}
;
118 const SCALE
: $ty
= (1u64 << $mantissa_bits
) as $ty
;
121 /// Generate a floating point number in the half-open
122 /// interval `[0,1)`.
124 /// See `Closed01` for the closed interval `[0,1]`,
125 /// and `Open01` for the open interval `(0,1)`.
127 fn rand
<R
: Rng
>(rng
: &mut R
) -> $ty
{
131 impl Rand
for Open01
<$ty
> {
133 fn rand
<R
: Rng
>(rng
: &mut R
) -> Open01
<$ty
> {
134 // add a small amount (specifically 2 bits below
135 // the precision of f64/f32 at 1.0), so that small
136 // numbers are larger than 0, but large numbers
137 // aren't pushed to/above 1.
138 Open01(rng
.$
method_name() + 0.25 / SCALE
)
141 impl Rand
for Closed01
<$ty
> {
143 fn rand
<R
: Rng
>(rng
: &mut R
) -> Closed01
<$ty
> {
144 // rescale so that 1.0 - epsilon becomes 1.0
146 Closed01(rng
.$
method_name() * SCALE
/ (SCALE
- 1.0))
152 float_impls
! { f64_rand_impls, f64, 53, next_f64 }
153 float_impls
! { f32_rand_impls, f32, 24, next_f32 }
157 fn rand
<R
: Rng
>(rng
: &mut R
) -> char {
159 const CHAR_MASK
: u32 = 0x001f_ffff;
161 // Rejection sampling. About 0.2% of numbers with at most
162 // 21-bits are invalid codepoints (surrogates), so this
163 // will succeed first go almost every time.
164 match char::from_u32(rng
.next_u32() & CHAR_MASK
) {
174 fn rand
<R
: Rng
>(rng
: &mut R
) -> bool
{
175 rng
.gen
::<u8>() & 1 == 1
179 macro_rules
! tuple_impl
{
180 // use variables to indicate the arity of the tuple
181 ($
($tyvar
:ident
),* ) => {
182 // the trailing commas are for the 1 tuple
185 > Rand
for ( $
( $tyvar
),* , ) {
188 fn rand
<R
: Rng
>(_rng
: &mut R
) -> ( $
( $tyvar
),* , ) {
190 // use the $tyvar's to get the appropriate number of
191 // repeats (they're not actually needed)
204 fn rand
<R
: Rng
>(_
: &mut R
) -> () { () }
209 tuple_impl
!{A, B, C, D}
210 tuple_impl
!{A, B, C, D, E}
211 tuple_impl
!{A, B, C, D, E, F}
212 tuple_impl
!{A, B, C, D, E, F, G}
213 tuple_impl
!{A, B, C, D, E, F, G, H}
214 tuple_impl
!{A, B, C, D, E, F, G, H, I}
215 tuple_impl
!{A, B, C, D, E, F, G, H, I, J}
216 tuple_impl
!{A, B, C, D, E, F, G, H, I, J, K}
217 tuple_impl
!{A, B, C, D, E, F, G, H, I, J, K, L}
219 macro_rules
! array_impl
{
220 {$n:expr, $t:ident, $($ts:ident,)*}
=> {
221 array_impl
!{($n - 1), $($ts,)*}
223 impl<T
> Rand
for [T
; $n
] where T
: Rand
{
225 fn rand
<R
: Rng
>(_rng
: &mut R
) -> [T
; $n
] {
226 [_rng
.gen
::<$t
>(), $
(_rng
.gen
::<$ts
>()),*]
231 impl<T
> Rand
for [T
; $n
] {
232 fn rand
<R
: Rng
>(_rng
: &mut R
) -> [T
; $n
] { [] }
237 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,}
239 impl<T
:Rand
> Rand
for Option
<T
> {
241 fn rand
<R
: Rng
>(rng
: &mut R
) -> Option
<T
> {
252 use {Rng, thread_rng, Open01, Closed01}
;
254 struct ConstantRng(u64);
255 impl Rng
for ConstantRng
{
256 fn next_u32(&mut self) -> u32 {
257 let ConstantRng(v
) = *self;
260 fn next_u64(&mut self) -> u64 {
261 let ConstantRng(v
) = *self;
267 fn floating_point_edge_cases() {
268 // the test for exact equality is correct here.
269 assert
!(ConstantRng(0xffff_ffff).gen
::<f32>() != 1.0);
270 assert
!(ConstantRng(0xffff_ffff_ffff_ffff).gen
::<f64>() != 1.0);
275 // this is unlikely to catch an incorrect implementation that
276 // generates exactly 0 or 1, but it keeps it sane.
277 let mut rng
= thread_rng();
279 // strict inequalities
280 let Open01(f
) = rng
.gen
::<Open01
<f64>>();
281 assert
!(0.0 < f
&& f
< 1.0);
283 let Open01(f
) = rng
.gen
::<Open01
<f32>>();
284 assert
!(0.0 < f
&& f
< 1.0);
290 let mut rng
= thread_rng();
292 // strict inequalities
293 let Closed01(f
) = rng
.gen
::<Closed01
<f64>>();
294 assert
!(0.0 <= f
&& f
<= 1.0);
296 let Closed01(f
) = rng
.gen
::<Closed01
<f32>>();
297 assert
!(0.0 <= f
&& f
<= 1.0);