separate the rand::rng gen_* methods out into an iface-less-impl so that the gen_* methods can be reused with different rng implementations (for https://github.com/mozilla/rust/issues/2379)
This commit is contained in:
committed by
Brian Anderson
parent
b4da0364f9
commit
11e81951bb
@@ -11,6 +11,7 @@ import vec_iter::extensions;
|
||||
import option::extensions;
|
||||
import option_iter::extensions;
|
||||
import ptr::extensions;
|
||||
import rand::extensions;
|
||||
|
||||
export path, option, some, none, unreachable;
|
||||
export extensions;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#[doc = "Random number generation"];
|
||||
|
||||
export rng;
|
||||
export rng, extensions;
|
||||
|
||||
enum rctx {}
|
||||
|
||||
@@ -15,55 +15,56 @@ native mod rustrt {
|
||||
iface rng {
|
||||
#[doc = "Return the next random integer"]
|
||||
fn next() -> u32;
|
||||
|
||||
#[doc = "Return the next random float"]
|
||||
fn next_float() -> float;
|
||||
|
||||
#[doc = "Return a random string composed of A-Z, a-z, 0-9."]
|
||||
fn gen_str(len: uint) -> str;
|
||||
|
||||
#[doc = "Return a random byte string."]
|
||||
fn gen_bytes(len: uint) -> [u8];
|
||||
}
|
||||
|
||||
resource rand_res(c: *rctx) { rustrt::rand_free(c); }
|
||||
#[doc = "Extension methods for random number generators"]
|
||||
impl extensions for rng {
|
||||
|
||||
#[doc = "Return a random float"]
|
||||
fn gen_float() -> float {
|
||||
let u1 = self.next() as float;
|
||||
let u2 = self.next() as float;
|
||||
let u3 = self.next() as float;
|
||||
let scale = u32::max_value as float;
|
||||
ret ((u1 / scale + u2) / scale + u3) / scale;
|
||||
}
|
||||
|
||||
#[doc = "Return a random string composed of A-Z, a-z, 0-9."]
|
||||
fn gen_str(len: uint) -> str {
|
||||
let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
|
||||
"abcdefghijklmnopqrstuvwxyz" +
|
||||
"0123456789";
|
||||
let mut s = "";
|
||||
let mut i = 0u;
|
||||
while (i < len) {
|
||||
let n = self.next() as uint % charset.len();
|
||||
s = s + str::from_char(str::char_at(charset, n));
|
||||
i += 1u;
|
||||
}
|
||||
s
|
||||
}
|
||||
|
||||
#[doc = "Return a random byte string."]
|
||||
fn gen_bytes(len: uint) -> [u8] {
|
||||
let mut v = [];
|
||||
let mut i = 0u;
|
||||
while i < len {
|
||||
let n = self.next() as uint;
|
||||
v += [(n % (u8::max_value as uint)) as u8];
|
||||
i += 1u;
|
||||
}
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Create a random number generator"]
|
||||
fn rng() -> rng {
|
||||
resource rand_res(c: *rctx) { rustrt::rand_free(c); }
|
||||
|
||||
impl of rng for @rand_res {
|
||||
fn next() -> u32 { ret rustrt::rand_next(**self); }
|
||||
fn next_float() -> float {
|
||||
let u1 = rustrt::rand_next(**self) as float;
|
||||
let u2 = rustrt::rand_next(**self) as float;
|
||||
let u3 = rustrt::rand_next(**self) as float;
|
||||
let scale = u32::max_value as float;
|
||||
ret ((u1 / scale + u2) / scale + u3) / scale;
|
||||
}
|
||||
fn gen_str(len: uint) -> str {
|
||||
let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
|
||||
"abcdefghijklmnopqrstuvwxyz" +
|
||||
"0123456789";
|
||||
let mut s = "";
|
||||
let mut i = 0u;
|
||||
while (i < len) {
|
||||
let n = rustrt::rand_next(**self) as uint %
|
||||
str::len(charset);
|
||||
s = s + str::from_char(str::char_at(charset, n));
|
||||
i += 1u;
|
||||
}
|
||||
s
|
||||
}
|
||||
fn gen_bytes(len: uint) -> [u8] {
|
||||
let mut v = [];
|
||||
let mut i = 0u;
|
||||
while i < len {
|
||||
let n = rustrt::rand_next(**self) as uint;
|
||||
v += [(n % (u8::max_value as uint)) as u8];
|
||||
i += 1u;
|
||||
}
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
@rand_res(rustrt::rand_new()) as rng
|
||||
}
|
||||
|
||||
@@ -72,7 +73,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let r1: rand::rng = rand::rng();
|
||||
let r1 = rand::rng();
|
||||
log(debug, r1.next());
|
||||
log(debug, r1.next());
|
||||
{
|
||||
@@ -95,13 +96,30 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn genstr() {
|
||||
let r: rand::rng = rand::rng();
|
||||
fn gen_float() {
|
||||
let r = rand::rng();
|
||||
let a = r.gen_float();
|
||||
let b = r.gen_float();
|
||||
log(debug, (a, b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gen_str() {
|
||||
let r = rand::rng();
|
||||
log(debug, r.gen_str(10u));
|
||||
log(debug, r.gen_str(10u));
|
||||
log(debug, r.gen_str(10u));
|
||||
assert(str::len(r.gen_str(10u)) == 10u);
|
||||
assert(str::len(r.gen_str(16u)) == 16u);
|
||||
assert r.gen_str(0u).len() == 0u;
|
||||
assert r.gen_str(10u).len() == 10u;
|
||||
assert r.gen_str(16u).len() == 16u;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gen_bytes() {
|
||||
let r = rand::rng();
|
||||
assert r.gen_bytes(0u).len() == 0u;
|
||||
assert r.gen_bytes(10u).len() == 10u;
|
||||
assert r.gen_bytes(16u).len() == 16u;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user