libcore: Remove mutable fields from rand.

This commit is contained in:
Patrick Walton
2013-05-02 23:09:50 -07:00
parent ee78d811e4
commit b2d1ac100f
6 changed files with 107 additions and 90 deletions

View File

@@ -56,7 +56,7 @@ fn resize_at(capacity: uint) -> uint {
pub fn linear_map_with_capacity<K:Eq + Hash,V>( pub fn linear_map_with_capacity<K:Eq + Hash,V>(
initial_capacity: uint) -> HashMap<K, V> { initial_capacity: uint) -> HashMap<K, V> {
let r = rand::task_rng(); let mut r = rand::task_rng();
linear_map_with_capacity_and_keys(r.gen(), r.gen(), linear_map_with_capacity_and_keys(r.gen(), r.gen(),
initial_capacity) initial_capacity)
} }

View File

@@ -55,12 +55,12 @@ pub mod distributions;
/// A type that can be randomly generated using an Rng /// A type that can be randomly generated using an Rng
pub trait Rand { pub trait Rand {
fn rand<R: Rng>(rng: &R) -> Self; fn rand<R: Rng>(rng: &mut R) -> Self;
} }
impl Rand for int { impl Rand for int {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> int { fn rand<R: Rng>(rng: &mut R) -> int {
if int::bits == 32 { if int::bits == 32 {
rng.next() as int rng.next() as int
} else { } else {
@@ -71,35 +71,35 @@ impl Rand for int {
impl Rand for i8 { impl Rand for i8 {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> i8 { fn rand<R: Rng>(rng: &mut R) -> i8 {
rng.next() as i8 rng.next() as i8
} }
} }
impl Rand for i16 { impl Rand for i16 {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> i16 { fn rand<R: Rng>(rng: &mut R) -> i16 {
rng.next() as i16 rng.next() as i16
} }
} }
impl Rand for i32 { impl Rand for i32 {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> i32 { fn rand<R: Rng>(rng: &mut R) -> i32 {
rng.next() as i32 rng.next() as i32
} }
} }
impl Rand for i64 { impl Rand for i64 {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> i64 { fn rand<R: Rng>(rng: &mut R) -> i64 {
(rng.next() as i64 << 32) | rng.next() as i64 (rng.next() as i64 << 32) | rng.next() as i64
} }
} }
impl Rand for uint { impl Rand for uint {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> uint { fn rand<R: Rng>(rng: &mut R) -> uint {
if uint::bits == 32 { if uint::bits == 32 {
rng.next() as uint rng.next() as uint
} else { } else {
@@ -110,42 +110,42 @@ impl Rand for uint {
impl Rand for u8 { impl Rand for u8 {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> u8 { fn rand<R: Rng>(rng: &mut R) -> u8 {
rng.next() as u8 rng.next() as u8
} }
} }
impl Rand for u16 { impl Rand for u16 {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> u16 { fn rand<R: Rng>(rng: &mut R) -> u16 {
rng.next() as u16 rng.next() as u16
} }
} }
impl Rand for u32 { impl Rand for u32 {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> u32 { fn rand<R: Rng>(rng: &mut R) -> u32 {
rng.next() rng.next()
} }
} }
impl Rand for u64 { impl Rand for u64 {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> u64 { fn rand<R: Rng>(rng: &mut R) -> u64 {
(rng.next() as u64 << 32) | rng.next() as u64 (rng.next() as u64 << 32) | rng.next() as u64
} }
} }
impl Rand for float { impl Rand for float {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> float { fn rand<R: Rng>(rng: &mut R) -> float {
rng.gen::<f64>() as float rng.gen::<f64>() as float
} }
} }
impl Rand for f32 { impl Rand for f32 {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> f32 { fn rand<R: Rng>(rng: &mut R) -> f32 {
rng.gen::<f64>() as f32 rng.gen::<f64>() as f32
} }
} }
@@ -153,7 +153,7 @@ impl Rand for f32 {
static scale : f64 = (u32::max_value as f64) + 1.0f64; static scale : f64 = (u32::max_value as f64) + 1.0f64;
impl Rand for f64 { impl Rand for f64 {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> f64 { fn rand<R: Rng>(rng: &mut R) -> f64 {
let u1 = rng.next() as f64; let u1 = rng.next() as f64;
let u2 = rng.next() as f64; let u2 = rng.next() as f64;
let u3 = rng.next() as f64; let u3 = rng.next() as f64;
@@ -164,14 +164,14 @@ impl Rand for f64 {
impl Rand for char { impl Rand for char {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> char { fn rand<R: Rng>(rng: &mut R) -> char {
rng.next() as char rng.next() as char
} }
} }
impl Rand for bool { impl Rand for bool {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> bool { fn rand<R: Rng>(rng: &mut R) -> bool {
rng.next() & 1u32 == 1u32 rng.next() & 1u32 == 1u32
} }
} }
@@ -185,7 +185,7 @@ macro_rules! tuple_impl {
> Rand for ( $( $tyvar ),* , ) { > Rand for ( $( $tyvar ),* , ) {
#[inline] #[inline]
fn rand<R: Rng>(_rng: &R) -> ( $( $tyvar ),* , ) { fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) {
( (
// use the $tyvar's to get the appropriate number of // use the $tyvar's to get the appropriate number of
// repeats (they're not actually needed) // repeats (they're not actually needed)
@@ -201,7 +201,7 @@ macro_rules! tuple_impl {
impl Rand for () { impl Rand for () {
#[inline] #[inline]
fn rand<R: Rng>(_: &R) -> () { () } fn rand<R: Rng>(_: &mut R) -> () { () }
} }
tuple_impl!{A} tuple_impl!{A}
tuple_impl!{A, B} tuple_impl!{A, B}
@@ -216,7 +216,7 @@ tuple_impl!{A, B, C, D, E, F, G, H, I, J}
impl<T:Rand> Rand for Option<T> { impl<T:Rand> Rand for Option<T> {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> Option<T> { fn rand<R: Rng>(rng: &mut R) -> Option<T> {
if rng.gen() { if rng.gen() {
Some(rng.gen()) Some(rng.gen())
} else { } else {
@@ -227,12 +227,12 @@ impl<T:Rand> Rand for Option<T> {
impl<T: Rand> Rand for ~T { impl<T: Rand> Rand for ~T {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> ~T { ~rng.gen() } fn rand<R: Rng>(rng: &mut R) -> ~T { ~rng.gen() }
} }
impl<T: Rand> Rand for @T { impl<T: Rand> Rand for @T {
#[inline] #[inline]
fn rand<R: Rng>(rng: &R) -> @T { @rng.gen() } fn rand<R: Rng>(rng: &mut R) -> @T { @rng.gen() }
} }
#[abi = "cdecl"] #[abi = "cdecl"]
@@ -248,7 +248,7 @@ pub mod rustrt {
/// A random number generator /// A random number generator
pub trait Rng { pub trait Rng {
/// Return the next random integer /// Return the next random integer
pub fn next(&self) -> u32; pub fn next(&mut self) -> u32;
} }
/// A value with a particular weight compared to other values /// A value with a particular weight compared to other values
@@ -259,21 +259,21 @@ pub struct Weighted<T> {
pub trait RngUtil { pub trait RngUtil {
/// Return a random value of a Rand type /// Return a random value of a Rand type
fn gen<T:Rand>(&self) -> T; fn gen<T:Rand>(&mut self) -> T;
/** /**
* Return a int randomly chosen from the range [start, end), * Return a int randomly chosen from the range [start, end),
* failing if start >= end * failing if start >= end
*/ */
fn gen_int_range(&self, start: int, end: int) -> int; fn gen_int_range(&mut self, start: int, end: int) -> int;
/** /**
* Return a uint randomly chosen from the range [start, end), * Return a uint randomly chosen from the range [start, end),
* failing if start >= end * failing if start >= end
*/ */
fn gen_uint_range(&self, start: uint, end: uint) -> uint; fn gen_uint_range(&mut self, start: uint, end: uint) -> uint;
/** /**
* Return a char randomly chosen from chars, failing if chars is empty * Return a char randomly chosen from chars, failing if chars is empty
*/ */
fn gen_char_from(&self, chars: &str) -> char; fn gen_char_from(&mut self, chars: &str) -> char;
/** /**
* Return a bool with a 1 in n chance of true * Return a bool with a 1 in n chance of true
* *
@@ -289,7 +289,7 @@ pub trait RngUtil {
* } * }
* ~~~ * ~~~
*/ */
fn gen_weighted_bool(&self, n: uint) -> bool; fn gen_weighted_bool(&mut self, n: uint) -> bool;
/** /**
* Return a random string of the specified length composed of A-Z,a-z,0-9 * Return a random string of the specified length composed of A-Z,a-z,0-9
* *
@@ -305,7 +305,7 @@ pub trait RngUtil {
* } * }
* ~~~ * ~~~
*/ */
fn gen_str(&self, len: uint) -> ~str; fn gen_str(&mut self, len: uint) -> ~str;
/** /**
* Return a random byte string of the specified length * Return a random byte string of the specified length
* *
@@ -321,7 +321,7 @@ pub trait RngUtil {
* } * }
* ~~~ * ~~~
*/ */
fn gen_bytes(&self, len: uint) -> ~[u8]; fn gen_bytes(&mut self, len: uint) -> ~[u8];
/** /**
* Choose an item randomly, failing if values is empty * Choose an item randomly, failing if values is empty
* *
@@ -337,9 +337,9 @@ pub trait RngUtil {
* } * }
* ~~~ * ~~~
*/ */
fn choose<T:Copy>(&self, values: &[T]) -> T; fn choose<T:Copy>(&mut self, values: &[T]) -> T;
/// Choose Some(item) randomly, returning None if values is empty /// Choose Some(item) randomly, returning None if values is empty
fn choose_option<T:Copy>(&self, values: &[T]) -> Option<T>; fn choose_option<T:Copy>(&mut self, values: &[T]) -> Option<T>;
/** /**
* Choose an item respecting the relative weights, failing if the sum of * Choose an item respecting the relative weights, failing if the sum of
* the weights is 0 * the weights is 0
@@ -359,7 +359,7 @@ pub trait RngUtil {
* } * }
* ~~~ * ~~~
*/ */
fn choose_weighted<T:Copy>(&self, v : &[Weighted<T>]) -> T; fn choose_weighted<T:Copy>(&mut self, v : &[Weighted<T>]) -> T;
/** /**
* Choose Some(item) respecting the relative weights, returning none if * Choose Some(item) respecting the relative weights, returning none if
* the sum of the weights is 0 * the sum of the weights is 0
@@ -379,7 +379,8 @@ pub trait RngUtil {
* } * }
* ~~~ * ~~~
*/ */
fn choose_weighted_option<T:Copy>(&self, v: &[Weighted<T>]) -> Option<T>; fn choose_weighted_option<T:Copy>(&mut self, v: &[Weighted<T>])
-> Option<T>;
/** /**
* Return a vec containing copies of the items, in order, where * Return a vec containing copies of the items, in order, where
* the weight of the item determines how many copies there are * the weight of the item determines how many copies there are
@@ -399,7 +400,7 @@ pub trait RngUtil {
* } * }
* ~~~ * ~~~
*/ */
fn weighted_vec<T:Copy>(&self, v: &[Weighted<T>]) -> ~[T]; fn weighted_vec<T:Copy>(&mut self, v: &[Weighted<T>]) -> ~[T];
/** /**
* Shuffle a vec * Shuffle a vec
* *
@@ -415,7 +416,7 @@ pub trait RngUtil {
* } * }
* ~~~ * ~~~
*/ */
fn shuffle<T:Copy>(&self, values: &[T]) -> ~[T]; fn shuffle<T:Copy>(&mut self, values: &[T]) -> ~[T];
/** /**
* Shuffle a mutable vec in place * Shuffle a mutable vec in place
* *
@@ -435,14 +436,14 @@ pub trait RngUtil {
* } * }
* ~~~ * ~~~
*/ */
fn shuffle_mut<T>(&self, values: &mut [T]); fn shuffle_mut<T>(&mut self, values: &mut [T]);
} }
/// Extension methods for random number generators /// Extension methods for random number generators
impl<R: Rng> RngUtil for R { impl<R: Rng> RngUtil for R {
/// Return a random value for a Rand type /// Return a random value for a Rand type
#[inline(always)] #[inline(always)]
fn gen<T: Rand>(&self) -> T { fn gen<T: Rand>(&mut self) -> T {
Rand::rand(self) Rand::rand(self)
} }
@@ -450,7 +451,7 @@ impl<R: Rng> RngUtil for R {
* Return an int randomly chosen from the range [start, end), * Return an int randomly chosen from the range [start, end),
* failing if start >= end * failing if start >= end
*/ */
fn gen_int_range(&self, start: int, end: int) -> int { fn gen_int_range(&mut self, start: int, end: int) -> int {
assert!(start < end); assert!(start < end);
start + int::abs(self.gen::<int>() % (end - start)) start + int::abs(self.gen::<int>() % (end - start))
} }
@@ -459,7 +460,7 @@ impl<R: Rng> RngUtil for R {
* Return a uint randomly chosen from the range [start, end), * Return a uint randomly chosen from the range [start, end),
* failing if start >= end * failing if start >= end
*/ */
fn gen_uint_range(&self, start: uint, end: uint) -> uint { fn gen_uint_range(&mut self, start: uint, end: uint) -> uint {
assert!(start < end); assert!(start < end);
start + (self.gen::<uint>() % (end - start)) start + (self.gen::<uint>() % (end - start))
} }
@@ -467,7 +468,7 @@ impl<R: Rng> RngUtil for R {
/** /**
* Return a char randomly chosen from chars, failing if chars is empty * Return a char randomly chosen from chars, failing if chars is empty
*/ */
fn gen_char_from(&self, chars: &str) -> char { fn gen_char_from(&mut self, chars: &str) -> char {
assert!(!chars.is_empty()); assert!(!chars.is_empty());
let mut cs = ~[]; let mut cs = ~[];
for str::each_char(chars) |c| { cs.push(c) } for str::each_char(chars) |c| { cs.push(c) }
@@ -475,7 +476,7 @@ impl<R: Rng> RngUtil for R {
} }
/// Return a bool with a 1-in-n chance of true /// Return a bool with a 1-in-n chance of true
fn gen_weighted_bool(&self, n: uint) -> bool { fn gen_weighted_bool(&mut self, n: uint) -> bool {
if n == 0u { if n == 0u {
true true
} else { } else {
@@ -486,7 +487,7 @@ impl<R: Rng> RngUtil for R {
/** /**
* Return a random string of the specified length composed of A-Z,a-z,0-9 * Return a random string of the specified length composed of A-Z,a-z,0-9
*/ */
fn gen_str(&self, len: uint) -> ~str { fn gen_str(&mut self, len: uint) -> ~str {
let charset = ~"ABCDEFGHIJKLMNOPQRSTUVWXYZ\ let charset = ~"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz\ abcdefghijklmnopqrstuvwxyz\
0123456789"; 0123456789";
@@ -500,19 +501,19 @@ impl<R: Rng> RngUtil for R {
} }
/// Return a random byte string of the specified length /// Return a random byte string of the specified length
fn gen_bytes(&self, len: uint) -> ~[u8] { fn gen_bytes(&mut self, len: uint) -> ~[u8] {
do vec::from_fn(len) |_i| { do vec::from_fn(len) |_i| {
self.gen() self.gen()
} }
} }
/// Choose an item randomly, failing if values is empty /// Choose an item randomly, failing if values is empty
fn choose<T:Copy>(&self, values: &[T]) -> T { fn choose<T:Copy>(&mut self, values: &[T]) -> T {
self.choose_option(values).get() self.choose_option(values).get()
} }
/// Choose Some(item) randomly, returning None if values is empty /// Choose Some(item) randomly, returning None if values is empty
fn choose_option<T:Copy>(&self, values: &[T]) -> Option<T> { fn choose_option<T:Copy>(&mut self, values: &[T]) -> Option<T> {
if values.is_empty() { if values.is_empty() {
None None
} else { } else {
@@ -523,7 +524,7 @@ impl<R: Rng> RngUtil for R {
* Choose an item respecting the relative weights, failing if the sum of * Choose an item respecting the relative weights, failing if the sum of
* the weights is 0 * the weights is 0
*/ */
fn choose_weighted<T:Copy>(&self, v : &[Weighted<T>]) -> T { fn choose_weighted<T:Copy>(&mut self, v: &[Weighted<T>]) -> T {
self.choose_weighted_option(v).get() self.choose_weighted_option(v).get()
} }
@@ -531,7 +532,8 @@ impl<R: Rng> RngUtil for R {
* Choose Some(item) respecting the relative weights, returning none if * Choose Some(item) respecting the relative weights, returning none if
* the sum of the weights is 0 * the sum of the weights is 0
*/ */
fn choose_weighted_option<T:Copy>(&self, v: &[Weighted<T>]) -> Option<T> { fn choose_weighted_option<T:Copy>(&mut self, v: &[Weighted<T>])
-> Option<T> {
let mut total = 0u; let mut total = 0u;
for v.each |item| { for v.each |item| {
total += item.weight; total += item.weight;
@@ -554,7 +556,7 @@ impl<R: Rng> RngUtil for R {
* Return a vec containing copies of the items, in order, where * Return a vec containing copies of the items, in order, where
* the weight of the item determines how many copies there are * the weight of the item determines how many copies there are
*/ */
fn weighted_vec<T:Copy>(&self, v: &[Weighted<T>]) -> ~[T] { fn weighted_vec<T:Copy>(&mut self, v: &[Weighted<T>]) -> ~[T] {
let mut r = ~[]; let mut r = ~[];
for v.each |item| { for v.each |item| {
for uint::range(0u, item.weight) |_i| { for uint::range(0u, item.weight) |_i| {
@@ -565,14 +567,14 @@ impl<R: Rng> RngUtil for R {
} }
/// Shuffle a vec /// Shuffle a vec
fn shuffle<T:Copy>(&self, values: &[T]) -> ~[T] { fn shuffle<T:Copy>(&mut self, values: &[T]) -> ~[T] {
let mut m = vec::from_slice(values); let mut m = vec::from_slice(values);
self.shuffle_mut(m); self.shuffle_mut(m);
m m
} }
/// Shuffle a mutable vec in place /// Shuffle a mutable vec in place
fn shuffle_mut<T>(&self, values: &mut [T]) { fn shuffle_mut<T>(&mut self, values: &mut [T]) {
let mut i = values.len(); let mut i = values.len();
while i >= 2u { while i >= 2u {
// invariant: elements with index >= i have been locked in place. // invariant: elements with index >= i have been locked in place.
@@ -594,12 +596,12 @@ static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
/// A random number generator that uses the [ISAAC /// A random number generator that uses the [ISAAC
/// algorithm](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29). /// algorithm](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29).
pub struct IsaacRng { pub struct IsaacRng {
priv mut cnt: u32, priv cnt: u32,
priv mut rsl: [u32, .. RAND_SIZE], priv rsl: [u32, .. RAND_SIZE],
priv mut mem: [u32, .. RAND_SIZE], priv mem: [u32, .. RAND_SIZE],
priv mut a: u32, priv a: u32,
priv mut b: u32, priv b: u32,
priv mut c: u32 priv c: u32
} }
pub impl IsaacRng { pub impl IsaacRng {
@@ -647,7 +649,7 @@ pub impl IsaacRng {
/// Initialises `self`. If `use_rsl` is true, then use the current value /// Initialises `self`. If `use_rsl` is true, then use the current value
/// of `rsl` as a seed, otherwise construct one algorithmically (not /// of `rsl` as a seed, otherwise construct one algorithmically (not
/// randomly). /// randomly).
priv fn init(&self, use_rsl: bool) { priv fn init(&mut self, use_rsl: bool) {
macro_rules! init_mut_many ( macro_rules! init_mut_many (
($( $var:ident ),* = $val:expr ) => { ($( $var:ident ),* = $val:expr ) => {
let mut $( $var = $val ),*; let mut $( $var = $val ),*;
@@ -705,16 +707,16 @@ pub impl IsaacRng {
/// Refills the output buffer (`self.rsl`) /// Refills the output buffer (`self.rsl`)
#[inline] #[inline]
priv fn isaac(&self) { priv fn isaac(&mut self) {
self.c += 1; self.c += 1;
// abbreviations // abbreviations
let mut a = self.a, b = self.b + self.c; let mut a = self.a, b = self.b + self.c;
let mem = &mut self.mem;
let rsl = &mut self.rsl;
static midpoint: uint = RAND_SIZE as uint / 2; static midpoint: uint = RAND_SIZE as uint / 2;
macro_rules! ind (($x:expr) => { mem[($x >> 2) & (RAND_SIZE - 1)] }); macro_rules! ind (($x:expr) => {
self.mem[($x >> 2) & (RAND_SIZE - 1)]
});
macro_rules! rngstep( macro_rules! rngstep(
($j:expr, $shift:expr) => {{ ($j:expr, $shift:expr) => {{
let base = base + $j; let base = base + $j;
@@ -724,13 +726,13 @@ pub impl IsaacRng {
a << $shift as uint a << $shift as uint
}; };
let x = mem[base + mr_offset]; let x = self.mem[base + mr_offset];
a = (a ^ mix) + mem[base + m2_offset]; a = (a ^ mix) + self.mem[base + m2_offset];
let y = ind!(x) + a + b; let y = ind!(x) + a + b;
mem[base + mr_offset] = y; self.mem[base + mr_offset] = y;
b = ind!(y >> RAND_SIZE_LEN) + x; b = ind!(y >> RAND_SIZE_LEN) + x;
rsl[base + mr_offset] = b; self.rsl[base + mr_offset] = b;
}} }}
); );
@@ -751,7 +753,7 @@ pub impl IsaacRng {
impl Rng for IsaacRng { impl Rng for IsaacRng {
#[inline(always)] #[inline(always)]
fn next(&self) -> u32 { fn next(&mut self) -> u32 {
if self.cnt == 0 { if self.cnt == 0 {
// make some more numbers // make some more numbers
self.isaac(); self.isaac();
@@ -765,15 +767,15 @@ impl Rng for IsaacRng {
/// generator](http://en.wikipedia.org/wiki/Xorshift). Not suitable for /// generator](http://en.wikipedia.org/wiki/Xorshift). Not suitable for
/// cryptographic purposes. /// cryptographic purposes.
pub struct XorShiftRng { pub struct XorShiftRng {
priv mut x: u32, priv x: u32,
priv mut y: u32, priv y: u32,
priv mut z: u32, priv z: u32,
priv mut w: u32, priv w: u32,
} }
impl Rng for XorShiftRng { impl Rng for XorShiftRng {
#[inline] #[inline]
pub fn next(&self) -> u32 { pub fn next(&mut self) -> u32 {
let x = self.x; let x = self.x;
let t = x ^ (x << 11); let t = x ^ (x << 11);
self.x = self.y; self.x = self.y;
@@ -789,7 +791,10 @@ pub impl XorShiftRng {
/// Create an xor shift random number generator with a default seed. /// Create an xor shift random number generator with a default seed.
fn new() -> XorShiftRng { fn new() -> XorShiftRng {
// constants taken from http://en.wikipedia.org/wiki/Xorshift // constants taken from http://en.wikipedia.org/wiki/Xorshift
XorShiftRng::new_seeded(123456789u32, 362436069u32, 521288629u32, 88675123u32) XorShiftRng::new_seeded(123456789u32,
362436069u32,
521288629u32,
88675123u32)
} }
/** /**
@@ -798,7 +803,12 @@ pub impl XorShiftRng {
* all other generators constructed with the same seed. * all other generators constructed with the same seed.
*/ */
fn new_seeded(x: u32, y: u32, z: u32, w: u32) -> XorShiftRng { fn new_seeded(x: u32, y: u32, z: u32, w: u32) -> XorShiftRng {
XorShiftRng { x: x, y: y, z: z, w: w } XorShiftRng {
x: x,
y: y,
z: z,
w: w,
}
} }
} }
@@ -815,7 +825,7 @@ pub fn seed() -> ~[u8] {
} }
// used to make space in TLS for a random number generator // used to make space in TLS for a random number generator
fn tls_rng_state(_v: @IsaacRng) {} fn tls_rng_state(_v: @@mut IsaacRng) {}
/** /**
* Gives back a lazily initialized task-local random number generator, * Gives back a lazily initialized task-local random number generator,
@@ -823,15 +833,15 @@ fn tls_rng_state(_v: @IsaacRng) {}
* `task_rng().gen::<int>()`. * `task_rng().gen::<int>()`.
*/ */
#[inline] #[inline]
pub fn task_rng() -> @IsaacRng { pub fn task_rng() -> @@mut IsaacRng {
let r : Option<@IsaacRng>; let r : Option<@@mut IsaacRng>;
unsafe { unsafe {
r = task::local_data::local_data_get(tls_rng_state); r = task::local_data::local_data_get(tls_rng_state);
} }
match r { match r {
None => { None => {
unsafe { unsafe {
let rng = @IsaacRng::new_seeded(seed()); let rng = @@mut IsaacRng::new_seeded(seed());
task::local_data::local_data_set(tls_rng_state, rng); task::local_data::local_data_set(tls_rng_state, rng);
rng rng
} }
@@ -841,9 +851,13 @@ pub fn task_rng() -> @IsaacRng {
} }
// Allow direct chaining with `task_rng` // Allow direct chaining with `task_rng`
impl<R: Rng> Rng for @R { impl<R: Rng> Rng for @@mut R {
#[inline(always)] #[inline(always)]
fn next(&self) -> u32 { (**self).next() } fn next(&mut self) -> u32 {
match *self {
@@ref mut r => r.next()
}
}
} }
/** /**
@@ -852,7 +866,9 @@ impl<R: Rng> Rng for @R {
*/ */
#[inline] #[inline]
pub fn random<T: Rand>() -> T { pub fn random<T: Rand>() -> T {
(*task_rng()).gen() match *task_rng() {
@ref mut r => r.gen()
}
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -27,13 +27,13 @@ mod ziggurat_tables;
// inlining should mean there is no performance penalty for this // inlining should mean there is no performance penalty for this
#[inline(always)] #[inline(always)]
fn ziggurat<R:Rng>(rng: &R, fn ziggurat<R:Rng>(rng: &mut R,
center_u: bool, center_u: bool,
X: ziggurat_tables::ZigTable, X: ziggurat_tables::ZigTable,
F: ziggurat_tables::ZigTable, F: ziggurat_tables::ZigTable,
F_DIFF: ziggurat_tables::ZigTable, F_DIFF: ziggurat_tables::ZigTable,
pdf: &'static fn(f64) -> f64, // probability density function pdf: &'static fn(f64) -> f64, // probability density function
zero_case: &'static fn(&R, f64) -> f64) -> f64 { zero_case: &'static fn(&mut R, f64) -> f64) -> f64 {
loop { loop {
let u = if center_u {2.0 * rng.gen() - 1.0} else {rng.gen()}; let u = if center_u {2.0 * rng.gen() - 1.0} else {rng.gen()};
let i: uint = rng.gen::<uint>() & 0xff; let i: uint = rng.gen::<uint>() & 0xff;
@@ -76,13 +76,13 @@ fn ziggurat<R:Rng>(rng: &R,
pub struct StandardNormal(f64); pub struct StandardNormal(f64);
impl Rand for StandardNormal { impl Rand for StandardNormal {
fn rand<R:Rng>(rng: &R) -> StandardNormal { fn rand<R:Rng>(rng: &mut R) -> StandardNormal {
#[inline(always)] #[inline(always)]
fn pdf(x: f64) -> f64 { fn pdf(x: f64) -> f64 {
f64::exp((-x*x/2.0) as f64) as f64 f64::exp((-x*x/2.0) as f64) as f64
} }
#[inline(always)] #[inline(always)]
fn zero_case<R:Rng>(rng: &R, u: f64) -> f64 { fn zero_case<R:Rng>(rng: &mut R, u: f64) -> f64 {
// compute a random number in the tail by hand // compute a random number in the tail by hand
// strange initial conditions, because the loop is not // strange initial conditions, because the loop is not
@@ -130,13 +130,13 @@ pub struct Exp1(f64);
// This could be done via `-f64::ln(rng.gen::<f64>())` but that is slower. // This could be done via `-f64::ln(rng.gen::<f64>())` but that is slower.
impl Rand for Exp1 { impl Rand for Exp1 {
#[inline] #[inline]
fn rand<R:Rng>(rng: &R) -> Exp1 { fn rand<R:Rng>(rng: &mut R) -> Exp1 {
#[inline(always)] #[inline(always)]
fn pdf(x: f64) -> f64 { fn pdf(x: f64) -> f64 {
f64::exp(-x) f64::exp(-x)
} }
#[inline(always)] #[inline(always)]
fn zero_case<R:Rng>(rng: &R, _u: f64) -> f64 { fn zero_case<R:Rng>(rng: &mut R, _u: f64) -> f64 {
ziggurat_tables::ZIG_EXP_R - f64::ln(rng.gen()) ziggurat_tables::ZIG_EXP_R - f64::ln(rng.gen())
} }

View File

@@ -62,7 +62,8 @@ fn exit_runner(exit_fns: *ExitFunctions) {
// give us ownership of the array of functions // give us ownership of the array of functions
let mut exit_fns_vec = unsafe { vec::from_buf(start, count as uint) }; let mut exit_fns_vec = unsafe { vec::from_buf(start, count as uint) };
// Let's not make any promises about execution order // Let's not make any promises about execution order
rand::rng().shuffle_mut(exit_fns_vec); let mut rng = rand::rng();
rng.shuffle_mut(exit_fns_vec);
debug!("running %u exit functions", exit_fns_vec.len()); debug!("running %u exit functions", exit_fns_vec.len());

View File

@@ -13,7 +13,7 @@
use core::rand::RngUtil; use core::rand::RngUtil;
pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option<Path> { pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option<Path> {
let r = rand::rng(); let mut r = rand::rng();
for 1000.times { for 1000.times {
let p = tmpdir.push(r.gen_str(16) + suffix); let p = tmpdir.push(r.gen_str(16) + suffix);
if os::make_dir(&p, 0x1c0) { // 700 if os::make_dir(&p, 0x1c0) { // 700

View File

@@ -688,7 +688,7 @@ pub mod bench {
// not met, it may run as long as the Go algorithm. // not met, it may run as long as the Go algorithm.
pub fn auto_bench(&mut self, f: &fn(&mut BenchHarness)) -> ~[f64] { pub fn auto_bench(&mut self, f: &fn(&mut BenchHarness)) -> ~[f64] {
let rng = rand::rng(); let mut rng = rand::rng();
let mut magnitude = 10; let mut magnitude = 10;
let mut prev_madp = 0.0; let mut prev_madp = 0.0;