diff --git a/src/libcore/core.rs b/src/libcore/core.rs index 8681f7d2a1ca..4b07e2b29b7b 100644 --- a/src/libcore/core.rs +++ b/src/libcore/core.rs @@ -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; diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs index a2e985ba0088..30ec17990921 100644 --- a/src/libcore/rand.rs +++ b/src/libcore/rand.rs @@ -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; } }