diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index b764fccf64c..8e0a185248e 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -56,7 +56,7 @@ fn resize_at(capacity: uint) -> uint { pub fn linear_map_with_capacity( initial_capacity: uint) -> HashMap { - let r = rand::task_rng(); + let mut r = rand::task_rng(); linear_map_with_capacity_and_keys(r.gen(), r.gen(), initial_capacity) } diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs index 80f69f067eb..cb212efa363 100644 --- a/src/libcore/rand.rs +++ b/src/libcore/rand.rs @@ -55,12 +55,12 @@ pub mod distributions; /// A type that can be randomly generated using an Rng pub trait Rand { - fn rand(rng: &R) -> Self; + fn rand(rng: &mut R) -> Self; } impl Rand for int { #[inline] - fn rand(rng: &R) -> int { + fn rand(rng: &mut R) -> int { if int::bits == 32 { rng.next() as int } else { @@ -71,35 +71,35 @@ impl Rand for int { impl Rand for i8 { #[inline] - fn rand(rng: &R) -> i8 { + fn rand(rng: &mut R) -> i8 { rng.next() as i8 } } impl Rand for i16 { #[inline] - fn rand(rng: &R) -> i16 { + fn rand(rng: &mut R) -> i16 { rng.next() as i16 } } impl Rand for i32 { #[inline] - fn rand(rng: &R) -> i32 { + fn rand(rng: &mut R) -> i32 { rng.next() as i32 } } impl Rand for i64 { #[inline] - fn rand(rng: &R) -> i64 { + fn rand(rng: &mut R) -> i64 { (rng.next() as i64 << 32) | rng.next() as i64 } } impl Rand for uint { #[inline] - fn rand(rng: &R) -> uint { + fn rand(rng: &mut R) -> uint { if uint::bits == 32 { rng.next() as uint } else { @@ -110,42 +110,42 @@ impl Rand for uint { impl Rand for u8 { #[inline] - fn rand(rng: &R) -> u8 { + fn rand(rng: &mut R) -> u8 { rng.next() as u8 } } impl Rand for u16 { #[inline] - fn rand(rng: &R) -> u16 { + fn rand(rng: &mut R) -> u16 { rng.next() as u16 } } impl Rand for u32 { #[inline] - fn rand(rng: &R) -> u32 { + fn rand(rng: &mut R) -> u32 { rng.next() } } impl Rand for u64 { #[inline] - fn rand(rng: &R) -> u64 { + fn rand(rng: &mut R) -> u64 { (rng.next() as u64 << 32) | rng.next() as u64 } } impl Rand for float { #[inline] - fn rand(rng: &R) -> float { + fn rand(rng: &mut R) -> float { rng.gen::() as float } } impl Rand for f32 { #[inline] - fn rand(rng: &R) -> f32 { + fn rand(rng: &mut R) -> f32 { rng.gen::() as f32 } } @@ -153,7 +153,7 @@ impl Rand for f32 { static scale : f64 = (u32::max_value as f64) + 1.0f64; impl Rand for f64 { #[inline] - fn rand(rng: &R) -> f64 { + fn rand(rng: &mut R) -> f64 { let u1 = rng.next() as f64; let u2 = rng.next() as f64; let u3 = rng.next() as f64; @@ -164,14 +164,14 @@ impl Rand for f64 { impl Rand for char { #[inline] - fn rand(rng: &R) -> char { + fn rand(rng: &mut R) -> char { rng.next() as char } } impl Rand for bool { #[inline] - fn rand(rng: &R) -> bool { + fn rand(rng: &mut R) -> bool { rng.next() & 1u32 == 1u32 } } @@ -185,7 +185,7 @@ macro_rules! tuple_impl { > Rand for ( $( $tyvar ),* , ) { #[inline] - fn rand(_rng: &R) -> ( $( $tyvar ),* , ) { + fn rand(_rng: &mut R) -> ( $( $tyvar ),* , ) { ( // use the $tyvar's to get the appropriate number of // repeats (they're not actually needed) @@ -201,7 +201,7 @@ macro_rules! tuple_impl { impl Rand for () { #[inline] - fn rand(_: &R) -> () { () } + fn rand(_: &mut R) -> () { () } } tuple_impl!{A} tuple_impl!{A, B} @@ -216,7 +216,7 @@ tuple_impl!{A, B, C, D, E, F, G, H, I, J} impl Rand for Option { #[inline] - fn rand(rng: &R) -> Option { + fn rand(rng: &mut R) -> Option { if rng.gen() { Some(rng.gen()) } else { @@ -227,12 +227,12 @@ impl Rand for Option { impl Rand for ~T { #[inline] - fn rand(rng: &R) -> ~T { ~rng.gen() } + fn rand(rng: &mut R) -> ~T { ~rng.gen() } } impl Rand for @T { #[inline] - fn rand(rng: &R) -> @T { @rng.gen() } + fn rand(rng: &mut R) -> @T { @rng.gen() } } #[abi = "cdecl"] @@ -248,7 +248,7 @@ pub mod rustrt { /// A random number generator pub trait Rng { /// 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 @@ -259,21 +259,21 @@ pub struct Weighted { pub trait RngUtil { /// Return a random value of a Rand type - fn gen(&self) -> T; + fn gen(&mut self) -> T; /** * Return a int randomly chosen from the range [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), * 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 */ - 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 * @@ -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 * @@ -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 * @@ -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 * @@ -337,9 +337,9 @@ pub trait RngUtil { * } * ~~~ */ - fn choose(&self, values: &[T]) -> T; + fn choose(&mut self, values: &[T]) -> T; /// Choose Some(item) randomly, returning None if values is empty - fn choose_option(&self, values: &[T]) -> Option; + fn choose_option(&mut self, values: &[T]) -> Option; /** * Choose an item respecting the relative weights, failing if the sum of * the weights is 0 @@ -359,7 +359,7 @@ pub trait RngUtil { * } * ~~~ */ - fn choose_weighted(&self, v : &[Weighted]) -> T; + fn choose_weighted(&mut self, v : &[Weighted]) -> T; /** * Choose Some(item) respecting the relative weights, returning none if * the sum of the weights is 0 @@ -379,7 +379,8 @@ pub trait RngUtil { * } * ~~~ */ - fn choose_weighted_option(&self, v: &[Weighted]) -> Option; + fn choose_weighted_option(&mut self, v: &[Weighted]) + -> Option; /** * Return a vec containing copies of the items, in order, where * the weight of the item determines how many copies there are @@ -399,7 +400,7 @@ pub trait RngUtil { * } * ~~~ */ - fn weighted_vec(&self, v: &[Weighted]) -> ~[T]; + fn weighted_vec(&mut self, v: &[Weighted]) -> ~[T]; /** * Shuffle a vec * @@ -415,7 +416,7 @@ pub trait RngUtil { * } * ~~~ */ - fn shuffle(&self, values: &[T]) -> ~[T]; + fn shuffle(&mut self, values: &[T]) -> ~[T]; /** * Shuffle a mutable vec in place * @@ -435,14 +436,14 @@ pub trait RngUtil { * } * ~~~ */ - fn shuffle_mut(&self, values: &mut [T]); + fn shuffle_mut(&mut self, values: &mut [T]); } /// Extension methods for random number generators impl RngUtil for R { /// Return a random value for a Rand type #[inline(always)] - fn gen(&self) -> T { + fn gen(&mut self) -> T { Rand::rand(self) } @@ -450,7 +451,7 @@ impl RngUtil for R { * Return an int randomly chosen from the range [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); start + int::abs(self.gen::() % (end - start)) } @@ -459,7 +460,7 @@ impl RngUtil for R { * Return a uint randomly chosen from the range [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); start + (self.gen::() % (end - start)) } @@ -467,7 +468,7 @@ impl RngUtil for R { /** * 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()); let mut cs = ~[]; for str::each_char(chars) |c| { cs.push(c) } @@ -475,7 +476,7 @@ impl RngUtil for R { } /// 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 { true } else { @@ -486,7 +487,7 @@ impl RngUtil for R { /** * 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\ abcdefghijklmnopqrstuvwxyz\ 0123456789"; @@ -500,19 +501,19 @@ impl RngUtil for R { } /// 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| { self.gen() } } /// Choose an item randomly, failing if values is empty - fn choose(&self, values: &[T]) -> T { + fn choose(&mut self, values: &[T]) -> T { self.choose_option(values).get() } /// Choose Some(item) randomly, returning None if values is empty - fn choose_option(&self, values: &[T]) -> Option { + fn choose_option(&mut self, values: &[T]) -> Option { if values.is_empty() { None } else { @@ -523,7 +524,7 @@ impl RngUtil for R { * Choose an item respecting the relative weights, failing if the sum of * the weights is 0 */ - fn choose_weighted(&self, v : &[Weighted]) -> T { + fn choose_weighted(&mut self, v: &[Weighted]) -> T { self.choose_weighted_option(v).get() } @@ -531,7 +532,8 @@ impl RngUtil for R { * Choose Some(item) respecting the relative weights, returning none if * the sum of the weights is 0 */ - fn choose_weighted_option(&self, v: &[Weighted]) -> Option { + fn choose_weighted_option(&mut self, v: &[Weighted]) + -> Option { let mut total = 0u; for v.each |item| { total += item.weight; @@ -554,7 +556,7 @@ impl RngUtil for R { * Return a vec containing copies of the items, in order, where * the weight of the item determines how many copies there are */ - fn weighted_vec(&self, v: &[Weighted]) -> ~[T] { + fn weighted_vec(&mut self, v: &[Weighted]) -> ~[T] { let mut r = ~[]; for v.each |item| { for uint::range(0u, item.weight) |_i| { @@ -565,14 +567,14 @@ impl RngUtil for R { } /// Shuffle a vec - fn shuffle(&self, values: &[T]) -> ~[T] { + fn shuffle(&mut self, values: &[T]) -> ~[T] { let mut m = vec::from_slice(values); self.shuffle_mut(m); m } /// Shuffle a mutable vec in place - fn shuffle_mut(&self, values: &mut [T]) { + fn shuffle_mut(&mut self, values: &mut [T]) { let mut i = values.len(); while i >= 2u { // 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 /// algorithm](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29). pub struct IsaacRng { - priv mut cnt: u32, - priv mut rsl: [u32, .. RAND_SIZE], - priv mut mem: [u32, .. RAND_SIZE], - priv mut a: u32, - priv mut b: u32, - priv mut c: u32 + priv cnt: u32, + priv rsl: [u32, .. RAND_SIZE], + priv mem: [u32, .. RAND_SIZE], + priv a: u32, + priv b: u32, + priv c: u32 } pub impl IsaacRng { @@ -647,7 +649,7 @@ pub impl IsaacRng { /// Initialises `self`. If `use_rsl` is true, then use the current value /// of `rsl` as a seed, otherwise construct one algorithmically (not /// randomly). - priv fn init(&self, use_rsl: bool) { + priv fn init(&mut self, use_rsl: bool) { macro_rules! init_mut_many ( ($( $var:ident ),* = $val:expr ) => { let mut $( $var = $val ),*; @@ -705,16 +707,16 @@ pub impl IsaacRng { /// Refills the output buffer (`self.rsl`) #[inline] - priv fn isaac(&self) { + priv fn isaac(&mut self) { self.c += 1; // abbreviations 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; - 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( ($j:expr, $shift:expr) => {{ let base = base + $j; @@ -724,13 +726,13 @@ pub impl IsaacRng { a << $shift as uint }; - let x = mem[base + mr_offset]; - a = (a ^ mix) + mem[base + m2_offset]; + let x = self.mem[base + mr_offset]; + a = (a ^ mix) + self.mem[base + m2_offset]; let y = ind!(x) + a + b; - mem[base + mr_offset] = y; + self.mem[base + mr_offset] = y; 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 { #[inline(always)] - fn next(&self) -> u32 { + fn next(&mut self) -> u32 { if self.cnt == 0 { // make some more numbers self.isaac(); @@ -765,15 +767,15 @@ impl Rng for IsaacRng { /// generator](http://en.wikipedia.org/wiki/Xorshift). Not suitable for /// cryptographic purposes. pub struct XorShiftRng { - priv mut x: u32, - priv mut y: u32, - priv mut z: u32, - priv mut w: u32, + priv x: u32, + priv y: u32, + priv z: u32, + priv w: u32, } impl Rng for XorShiftRng { #[inline] - pub fn next(&self) -> u32 { + pub fn next(&mut self) -> u32 { let x = self.x; let t = x ^ (x << 11); self.x = self.y; @@ -789,7 +791,10 @@ pub impl XorShiftRng { /// Create an xor shift random number generator with a default seed. fn new() -> XorShiftRng { // 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. */ 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 -fn tls_rng_state(_v: @IsaacRng) {} +fn tls_rng_state(_v: @@mut IsaacRng) {} /** * Gives back a lazily initialized task-local random number generator, @@ -823,15 +833,15 @@ fn tls_rng_state(_v: @IsaacRng) {} * `task_rng().gen::()`. */ #[inline] -pub fn task_rng() -> @IsaacRng { - let r : Option<@IsaacRng>; +pub fn task_rng() -> @@mut IsaacRng { + let r : Option<@@mut IsaacRng>; unsafe { r = task::local_data::local_data_get(tls_rng_state); } match r { None => { unsafe { - let rng = @IsaacRng::new_seeded(seed()); + let rng = @@mut IsaacRng::new_seeded(seed()); task::local_data::local_data_set(tls_rng_state, rng); rng } @@ -841,9 +851,13 @@ pub fn task_rng() -> @IsaacRng { } // Allow direct chaining with `task_rng` -impl Rng for @R { +impl Rng for @@mut R { #[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 Rng for @R { */ #[inline] pub fn random() -> T { - (*task_rng()).gen() + match *task_rng() { + @ref mut r => r.gen() + } } #[cfg(test)] diff --git a/src/libcore/rand/distributions.rs b/src/libcore/rand/distributions.rs index a644f60db69..72cff5111e7 100644 --- a/src/libcore/rand/distributions.rs +++ b/src/libcore/rand/distributions.rs @@ -27,13 +27,13 @@ mod ziggurat_tables; // inlining should mean there is no performance penalty for this #[inline(always)] -fn ziggurat(rng: &R, +fn ziggurat(rng: &mut R, center_u: bool, X: ziggurat_tables::ZigTable, F: ziggurat_tables::ZigTable, F_DIFF: ziggurat_tables::ZigTable, 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 { let u = if center_u {2.0 * rng.gen() - 1.0} else {rng.gen()}; let i: uint = rng.gen::() & 0xff; @@ -76,13 +76,13 @@ fn ziggurat(rng: &R, pub struct StandardNormal(f64); impl Rand for StandardNormal { - fn rand(rng: &R) -> StandardNormal { + fn rand(rng: &mut R) -> StandardNormal { #[inline(always)] fn pdf(x: f64) -> f64 { f64::exp((-x*x/2.0) as f64) as f64 } #[inline(always)] - fn zero_case(rng: &R, u: f64) -> f64 { + fn zero_case(rng: &mut R, u: f64) -> f64 { // compute a random number in the tail by hand // 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::())` but that is slower. impl Rand for Exp1 { #[inline] - fn rand(rng: &R) -> Exp1 { + fn rand(rng: &mut R) -> Exp1 { #[inline(always)] fn pdf(x: f64) -> f64 { f64::exp(-x) } #[inline(always)] - fn zero_case(rng: &R, _u: f64) -> f64 { + fn zero_case(rng: &mut R, _u: f64) -> f64 { ziggurat_tables::ZIG_EXP_R - f64::ln(rng.gen()) } diff --git a/src/libcore/unstable/at_exit.rs b/src/libcore/unstable/at_exit.rs index bc4ec620aa8..c9cd2f61e5c 100644 --- a/src/libcore/unstable/at_exit.rs +++ b/src/libcore/unstable/at_exit.rs @@ -62,7 +62,8 @@ fn exit_runner(exit_fns: *ExitFunctions) { // give us ownership of the array of functions let mut exit_fns_vec = unsafe { vec::from_buf(start, count as uint) }; // 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()); diff --git a/src/libstd/tempfile.rs b/src/libstd/tempfile.rs index 10645e947e2..e02a7a33733 100644 --- a/src/libstd/tempfile.rs +++ b/src/libstd/tempfile.rs @@ -13,7 +13,7 @@ use core::rand::RngUtil; pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option { - let r = rand::rng(); + let mut r = rand::rng(); for 1000.times { let p = tmpdir.push(r.gen_str(16) + suffix); if os::make_dir(&p, 0x1c0) { // 700 diff --git a/src/libstd/test.rs b/src/libstd/test.rs index 65fb0c7426a..7c0673a280b 100644 --- a/src/libstd/test.rs +++ b/src/libstd/test.rs @@ -688,7 +688,7 @@ pub mod bench { // not met, it may run as long as the Go algorithm. 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 prev_madp = 0.0;