(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  }