]> git.lizzy.rs Git - rust.git/commitdiff
std: Move rand to librand.
authorHuon Wilson <dbau.pp+github@gmail.com>
Sun, 2 Mar 2014 00:23:04 +0000 (11:23 +1100)
committerHuon Wilson <dbau.pp+github@gmail.com>
Wed, 12 Mar 2014 00:31:05 +0000 (11:31 +1100)
This functionality is not super-core and so doesn't need to be included
in std. It's possible that std may need rand (it does a little bit now,
for io::test) in which case the functionality required could be moved to
a secret hidden module and reexposed by librand.

Unfortunately, using #[deprecated] here is hard: there's too much to
mock to make it feasible, since we have to ensure that programs still
typecheck to reach the linting phase.

30 files changed:
mk/crates.mk
src/etc/ziggurat_tables.py
src/librand/distributions/exponential.rs [new file with mode: 0644]
src/librand/distributions/gamma.rs [new file with mode: 0644]
src/librand/distributions/mod.rs [new file with mode: 0644]
src/librand/distributions/normal.rs [new file with mode: 0644]
src/librand/distributions/range.rs [new file with mode: 0644]
src/librand/distributions/ziggurat_tables.rs [new file with mode: 0644]
src/librand/isaac.rs [new file with mode: 0644]
src/librand/lib.rs [new file with mode: 0644]
src/librand/os.rs [new file with mode: 0644]
src/librand/rand_impls.rs [new file with mode: 0644]
src/librand/reader.rs [new file with mode: 0644]
src/librand/reseeding.rs [new file with mode: 0644]
src/libstd/lib.rs
src/libstd/rand/distributions/exponential.rs [deleted file]
src/libstd/rand/distributions/gamma.rs [deleted file]
src/libstd/rand/distributions/mod.rs [deleted file]
src/libstd/rand/distributions/normal.rs [deleted file]
src/libstd/rand/distributions/range.rs [deleted file]
src/libstd/rand/distributions/ziggurat_tables.rs [deleted file]
src/libstd/rand/isaac.rs [deleted file]
src/libstd/rand/mod.rs [deleted file]
src/libstd/rand/os.rs [deleted file]
src/libstd/rand/rand_impls.rs [deleted file]
src/libstd/rand/reader.rs [deleted file]
src/libstd/rand/reseeding.rs [deleted file]
src/libsyntax/ext/deriving/rand.rs
src/rt/rust_builtin.c
src/test/compile-fail/task-rng-isnt-sendable.rs

index 67bd967a974a51f6f2f1e651776ba25000c39452..e4b56696b39e686514958d3e396265c68a1b7704 100644 (file)
 ################################################################################
 
 TARGET_CRATES := std extra green rustuv native flate arena glob term semver \
-                 uuid serialize sync getopts collections num test time
+                 uuid serialize sync getopts collections num test time rand
 HOST_CRATES := syntax rustc rustdoc fourcc hexfloat
 CRATES := $(TARGET_CRATES) $(HOST_CRATES)
 TOOLS := compiletest rustdoc rustc
 
 DEPS_std := native:rustrt native:compiler-rt
-DEPS_extra := std term sync serialize getopts collections time
-DEPS_green := std native:context_switch
+DEPS_extra := std term sync serialize getopts collections time rand
+DEPS_green := std rand native:context_switch
 DEPS_rustuv := std native:uv native:uv_support
 DEPS_native := std
 DEPS_syntax := std term serialize collections
@@ -71,15 +71,16 @@ DEPS_glob := std
 DEPS_serialize := std collections
 DEPS_term := std collections
 DEPS_semver := std
-DEPS_uuid := std serialize
+DEPS_uuid := std serialize rand
 DEPS_sync := std
 DEPS_getopts := std
-DEPS_collections := std
+DEPS_collections := std rand
 DEPS_fourcc := syntax std
 DEPS_hexfloat := syntax std
-DEPS_num := std
+DEPS_num := std rand
 DEPS_test := std extra collections getopts serialize term
 DEPS_time := std serialize
+DEPS_rand := std
 
 TOOL_DEPS_compiletest := test green rustuv getopts
 TOOL_DEPS_rustdoc := rustdoc native
index d1980cec2ed3aa9bbb3dd82e7403da64faa7d0a2..762f9565b7802e41a93ca3e693d96ea825fb03c2 100755 (executable)
@@ -11,7 +11,7 @@
 # except according to those terms.
 
 # This creates the tables used for distributions implemented using the
-# ziggurat algorithm in `std::rand::distributions;`. They are
+# ziggurat algorithm in `rand::distributions;`. They are
 # (basically) the tables as used in the ZIGNOR variant (Doornik 2005).
 # They are changed rarely, so the generated file should be checked in
 # to git.
diff --git a/src/librand/distributions/exponential.rs b/src/librand/distributions/exponential.rs
new file mode 100644 (file)
index 0000000..369828d
--- /dev/null
@@ -0,0 +1,139 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The exponential distribution.
+
+use std::num::Float;
+use {Rng, Rand};
+use distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample};
+
+/// A wrapper around an `f64` to generate Exp(1) random numbers.
+///
+/// See `Exp` for the general exponential distribution.Note that this
+ // has to be unwrapped before use as an `f64` (using either
+/// `*` or `cast::transmute` is safe).
+///
+/// Implemented via the ZIGNOR variant[1] of the Ziggurat method. The
+/// exact description in the paper was adjusted to use tables for the
+/// exponential distribution rather than normal.
+///
+/// [1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
+/// Generate Normal Random
+/// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
+/// College, Oxford
+pub struct Exp1(f64);
+
+// This could be done via `-rng.gen::<f64>().ln()` but that is slower.
+impl Rand for Exp1 {
+    #[inline]
+    fn rand<R:Rng>(rng: &mut R) -> Exp1 {
+        #[inline]
+        fn pdf(x: f64) -> f64 {
+            (-x).exp()
+        }
+        #[inline]
+        fn zero_case<R:Rng>(rng: &mut R, _u: f64) -> f64 {
+            ziggurat_tables::ZIG_EXP_R - rng.gen::<f64>().ln()
+        }
+
+        Exp1(ziggurat(rng, false,
+                      &ziggurat_tables::ZIG_EXP_X,
+                      &ziggurat_tables::ZIG_EXP_F,
+                      pdf, zero_case))
+    }
+}
+
+/// The exponential distribution `Exp(lambda)`.
+///
+/// This distribution has density function: `f(x) = lambda *
+/// exp(-lambda * x)` for `x > 0`.
+///
+/// # Example
+///
+/// ```rust
+/// use rand::distributions::{Exp, IndependentSample};
+///
+/// let exp = Exp::new(2.0);
+/// let v = exp.ind_sample(&mut rand::task_rng());
+/// println!("{} is from a Exp(2) distribution", v);
+/// ```
+pub struct Exp {
+    /// `lambda` stored as `1/lambda`, since this is what we scale by.
+    priv lambda_inverse: f64
+}
+
+impl Exp {
+    /// Construct a new `Exp` with the given shape parameter
+    /// `lambda`. Fails if `lambda <= 0`.
+    pub fn new(lambda: f64) -> Exp {
+        assert!(lambda > 0.0, "Exp::new called with `lambda` <= 0");
+        Exp { lambda_inverse: 1.0 / lambda }
+    }
+}
+
+impl Sample<f64> for Exp {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
+}
+impl IndependentSample<f64> for Exp {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
+        let Exp1(n) = rng.gen::<Exp1>();
+        n * self.lambda_inverse
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use distributions::{Sample, IndependentSample};
+    use {Rng, task_rng};
+    use super::Exp;
+
+    #[test]
+    fn test_exp() {
+        let mut exp = Exp::new(10.0);
+        let mut rng = task_rng();
+        for _ in range(0, 1000) {
+            assert!(exp.sample(&mut rng) >= 0.0);
+            assert!(exp.ind_sample(&mut rng) >= 0.0);
+        }
+    }
+    #[test]
+    #[should_fail]
+    fn test_exp_invalid_lambda_zero() {
+        Exp::new(0.0);
+    }
+    #[test]
+    #[should_fail]
+    fn test_exp_invalid_lambda_neg() {
+        Exp::new(-10.0);
+    }
+}
+
+#[cfg(test)]
+mod bench {
+    extern crate test;
+    use self::test::BenchHarness;
+    use std::mem::size_of;
+    use {XorShiftRng, RAND_BENCH_N};
+    use super::Exp;
+    use distributions::Sample;
+
+    #[bench]
+    fn rand_exp(bh: &mut BenchHarness) {
+        let mut rng = XorShiftRng::new();
+        let mut exp = Exp::new(2.71828 * 3.14159);
+
+        bh.iter(|| {
+            for _ in range(0, RAND_BENCH_N) {
+                exp.sample(&mut rng);
+            }
+        });
+        bh.bytes = size_of::<f64>() as u64 * RAND_BENCH_N;
+    }
+}
diff --git a/src/librand/distributions/gamma.rs b/src/librand/distributions/gamma.rs
new file mode 100644 (file)
index 0000000..029333c
--- /dev/null
@@ -0,0 +1,402 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The Gamma and derived distributions.
+
+use std::num::Float;
+use std::num;
+use {Rng, Open01};
+use super::normal::StandardNormal;
+use super::{IndependentSample, Sample, Exp};
+
+/// The Gamma distribution `Gamma(shape, scale)` distribution.
+///
+/// The density function of this distribution is
+///
+/// ```notrust
+/// f(x) =  x^(k - 1) * exp(-x / θ) / (Γ(k) * θ^k)
+/// ```
+///
+/// where `Γ` is the Gamma function, `k` is the shape and `θ` is the
+/// scale and both `k` and `θ` are strictly positive.
+///
+/// The algorithm used is that described by Marsaglia & Tsang 2000[1],
+/// falling back to directly sampling from an Exponential for `shape
+/// == 1`, and using the boosting technique described in [1] for
+/// `shape < 1`.
+///
+/// # Example
+///
+/// ```rust
+/// use rand::distributions::{IndependentSample, Gamma};
+///
+/// let gamma = Gamma::new(2.0, 5.0);
+/// let v = gamma.ind_sample(&mut rand::task_rng());
+/// println!("{} is from a Gamma(2, 5) distribution", v);
+/// ```
+///
+/// [1]: George Marsaglia and Wai Wan Tsang. 2000. "A Simple Method
+/// for Generating Gamma Variables" *ACM Trans. Math. Softw.* 26, 3
+/// (September 2000),
+/// 363-372. DOI:[10.1145/358407.358414](http://doi.acm.org/10.1145/358407.358414)
+pub enum Gamma {
+    priv Large(GammaLargeShape),
+    priv One(Exp),
+    priv Small(GammaSmallShape)
+}
+
+// These two helpers could be made public, but saving the
+// match-on-Gamma-enum branch from using them directly (e.g. if one
+// knows that the shape is always > 1) doesn't appear to be much
+// faster.
+
+/// Gamma distribution where the shape parameter is less than 1.
+///
+/// Note, samples from this require a compulsory floating-point `pow`
+/// call, which makes it significantly slower than sampling from a
+/// gamma distribution where the shape parameter is greater than or
+/// equal to 1.
+///
+/// See `Gamma` for sampling from a Gamma distribution with general
+/// shape parameters.
+struct GammaSmallShape {
+    inv_shape: f64,
+    large_shape: GammaLargeShape
+}
+
+/// Gamma distribution where the shape parameter is larger than 1.
+///
+/// See `Gamma` for sampling from a Gamma distribution with general
+/// shape parameters.
+struct GammaLargeShape {
+    shape: f64,
+    scale: f64,
+    c: f64,
+    d: f64
+}
+
+impl Gamma {
+    /// Construct an object representing the `Gamma(shape, scale)`
+    /// distribution.
+    ///
+    /// Fails if `shape <= 0` or `scale <= 0`.
+    pub fn new(shape: f64, scale: f64) -> Gamma {
+        assert!(shape > 0.0, "Gamma::new called with shape <= 0");
+        assert!(scale > 0.0, "Gamma::new called with scale <= 0");
+
+        match shape {
+            1.0        => One(Exp::new(1.0 / scale)),
+            0.0 .. 1.0 => Small(GammaSmallShape::new_raw(shape, scale)),
+            _          => Large(GammaLargeShape::new_raw(shape, scale))
+        }
+    }
+}
+
+impl GammaSmallShape {
+    fn new_raw(shape: f64, scale: f64) -> GammaSmallShape {
+        GammaSmallShape {
+            inv_shape: 1. / shape,
+            large_shape: GammaLargeShape::new_raw(shape + 1.0, scale)
+        }
+    }
+}
+
+impl GammaLargeShape {
+    fn new_raw(shape: f64, scale: f64) -> GammaLargeShape {
+        let d = shape - 1. / 3.;
+        GammaLargeShape {
+            shape: shape,
+            scale: scale,
+            c: 1. / num::sqrt(9. * d),
+            d: d
+        }
+    }
+}
+
+impl Sample<f64> for Gamma {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
+}
+impl Sample<f64> for GammaSmallShape {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
+}
+impl Sample<f64> for GammaLargeShape {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
+}
+
+impl IndependentSample<f64> for Gamma {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
+        match *self {
+            Small(ref g) => g.ind_sample(rng),
+            One(ref g) => g.ind_sample(rng),
+            Large(ref g) => g.ind_sample(rng),
+        }
+    }
+}
+impl IndependentSample<f64> for GammaSmallShape {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
+        let Open01(u) = rng.gen::<Open01<f64>>();
+
+        self.large_shape.ind_sample(rng) * num::powf(u, self.inv_shape)
+    }
+}
+impl IndependentSample<f64> for GammaLargeShape {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
+        loop {
+            let StandardNormal(x) = rng.gen::<StandardNormal>();
+            let v_cbrt = 1.0 + self.c * x;
+            if v_cbrt <= 0.0 { // a^3 <= 0 iff a <= 0
+                continue
+            }
+
+            let v = v_cbrt * v_cbrt * v_cbrt;
+            let Open01(u) = rng.gen::<Open01<f64>>();
+
+            let x_sqr = x * x;
+            if u < 1.0 - 0.0331 * x_sqr * x_sqr ||
+                num::ln(u) < 0.5 * x_sqr + self.d * (1.0 - v + num::ln(v)) {
+                return self.d * v * self.scale
+            }
+        }
+    }
+}
+
+/// The chi-squared distribution `χ²(k)`, where `k` is the degrees of
+/// freedom.
+///
+/// For `k > 0` integral, this distribution is the sum of the squares
+/// of `k` independent standard normal random variables. For other
+/// `k`, this uses the equivalent characterisation `χ²(k) = Gamma(k/2,
+/// 2)`.
+///
+/// # Example
+///
+/// ```rust
+/// use rand::distributions::{ChiSquared, IndependentSample};
+///
+/// let chi = ChiSquared::new(11.0);
+/// let v = chi.ind_sample(&mut rand::task_rng());
+/// println!("{} is from a χ²(11) distribution", v)
+/// ```
+pub enum ChiSquared {
+    // k == 1, Gamma(alpha, ..) is particularly slow for alpha < 1,
+    // e.g. when alpha = 1/2 as it would be for this case, so special-
+    // casing and using the definition of N(0,1)^2 is faster.
+    priv DoFExactlyOne,
+    priv DoFAnythingElse(Gamma)
+}
+
+impl ChiSquared {
+    /// Create a new chi-squared distribution with degrees-of-freedom
+    /// `k`. Fails if `k < 0`.
+    pub fn new(k: f64) -> ChiSquared {
+        if k == 1.0 {
+            DoFExactlyOne
+        } else {
+            assert!(k > 0.0, "ChiSquared::new called with `k` < 0");
+            DoFAnythingElse(Gamma::new(0.5 * k, 2.0))
+        }
+    }
+}
+impl Sample<f64> for ChiSquared {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
+}
+impl IndependentSample<f64> for ChiSquared {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
+        match *self {
+            DoFExactlyOne => {
+                // k == 1 => N(0,1)^2
+                let StandardNormal(norm) = rng.gen::<StandardNormal>();
+                norm * norm
+            }
+            DoFAnythingElse(ref g) => g.ind_sample(rng)
+        }
+    }
+}
+
+/// The Fisher F distribution `F(m, n)`.
+///
+/// This distribution is equivalent to the ratio of two normalised
+/// chi-squared distributions, that is, `F(m,n) = (χ²(m)/m) /
+/// (χ²(n)/n)`.
+///
+/// # Example
+///
+/// ```rust
+/// use rand::distributions::{FisherF, IndependentSample};
+///
+/// let f = FisherF::new(2.0, 32.0);
+/// let v = f.ind_sample(&mut rand::task_rng());
+/// println!("{} is from an F(2, 32) distribution", v)
+/// ```
+pub struct FisherF {
+    priv numer: ChiSquared,
+    priv denom: ChiSquared,
+    // denom_dof / numer_dof so that this can just be a straight
+    // multiplication, rather than a division.
+    priv dof_ratio: f64,
+}
+
+impl FisherF {
+    /// Create a new `FisherF` distribution, with the given
+    /// parameter. Fails if either `m` or `n` are not positive.
+    pub fn new(m: f64, n: f64) -> FisherF {
+        assert!(m > 0.0, "FisherF::new called with `m < 0`");
+        assert!(n > 0.0, "FisherF::new called with `n < 0`");
+
+        FisherF {
+            numer: ChiSquared::new(m),
+            denom: ChiSquared::new(n),
+            dof_ratio: n / m
+        }
+    }
+}
+impl Sample<f64> for FisherF {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
+}
+impl IndependentSample<f64> for FisherF {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
+        self.numer.ind_sample(rng) / self.denom.ind_sample(rng) * self.dof_ratio
+    }
+}
+
+/// The Student t distribution, `t(nu)`, where `nu` is the degrees of
+/// freedom.
+///
+/// # Example
+///
+/// ```rust
+/// use rand::distributions::{StudentT, IndependentSample};
+///
+/// let t = StudentT::new(11.0);
+/// let v = t.ind_sample(&mut rand::task_rng());
+/// println!("{} is from a t(11) distribution", v)
+/// ```
+pub struct StudentT {
+    priv chi: ChiSquared,
+    priv dof: f64
+}
+
+impl StudentT {
+    /// Create a new Student t distribution with `n` degrees of
+    /// freedom. Fails if `n <= 0`.
+    pub fn new(n: f64) -> StudentT {
+        assert!(n > 0.0, "StudentT::new called with `n <= 0`");
+        StudentT {
+            chi: ChiSquared::new(n),
+            dof: n
+        }
+    }
+}
+impl Sample<f64> for StudentT {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
+}
+impl IndependentSample<f64> for StudentT {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
+        let StandardNormal(norm) = rng.gen::<StandardNormal>();
+        norm * (self.dof / self.chi.ind_sample(rng)).sqrt()
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use distributions::{Sample, IndependentSample};
+    use {Rng, task_rng};
+    use super::{ChiSquared, StudentT, FisherF};
+
+    #[test]
+    fn test_chi_squared_one() {
+        let mut chi = ChiSquared::new(1.0);
+        let mut rng = task_rng();
+        for _ in range(0, 1000) {
+            chi.sample(&mut rng);
+            chi.ind_sample(&mut rng);
+        }
+    }
+    #[test]
+    fn test_chi_squared_small() {
+        let mut chi = ChiSquared::new(0.5);
+        let mut rng = task_rng();
+        for _ in range(0, 1000) {
+            chi.sample(&mut rng);
+            chi.ind_sample(&mut rng);
+        }
+    }
+    #[test]
+    fn test_chi_squared_large() {
+        let mut chi = ChiSquared::new(30.0);
+        let mut rng = task_rng();
+        for _ in range(0, 1000) {
+            chi.sample(&mut rng);
+            chi.ind_sample(&mut rng);
+        }
+    }
+    #[test]
+    #[should_fail]
+    fn test_chi_squared_invalid_dof() {
+        ChiSquared::new(-1.0);
+    }
+
+    #[test]
+    fn test_f() {
+        let mut f = FisherF::new(2.0, 32.0);
+        let mut rng = task_rng();
+        for _ in range(0, 1000) {
+            f.sample(&mut rng);
+            f.ind_sample(&mut rng);
+        }
+    }
+
+    #[test]
+    fn test_t() {
+        let mut t = StudentT::new(11.0);
+        let mut rng = task_rng();
+        for _ in range(0, 1000) {
+            t.sample(&mut rng);
+            t.ind_sample(&mut rng);
+        }
+    }
+}
+
+#[cfg(test)]
+mod bench {
+    extern crate test;
+    use self::test::BenchHarness;
+    use std::mem::size_of;
+    use distributions::IndependentSample;
+    use {StdRng, RAND_BENCH_N};
+    use super::Gamma;
+
+
+    #[bench]
+    fn bench_gamma_large_shape(bh: &mut BenchHarness) {
+        let gamma = Gamma::new(10., 1.0);
+        let mut rng = StdRng::new();
+
+        bh.iter(|| {
+            for _ in range(0, RAND_BENCH_N) {
+                gamma.ind_sample(&mut rng);
+            }
+        });
+        bh.bytes = size_of::<f64>() as u64 * RAND_BENCH_N;
+    }
+
+    #[bench]
+    fn bench_gamma_small_shape(bh: &mut BenchHarness) {
+        let gamma = Gamma::new(0.1, 1.0);
+        let mut rng = StdRng::new();
+
+        bh.iter(|| {
+            for _ in range(0, RAND_BENCH_N) {
+                gamma.ind_sample(&mut rng);
+            }
+        });
+        bh.bytes = size_of::<f64>() as u64 * RAND_BENCH_N;
+    }
+}
diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs
new file mode 100644 (file)
index 0000000..22a09b1
--- /dev/null
@@ -0,0 +1,350 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+Sampling from random distributions.
+
+This is a generalization of `Rand` to allow parameters to control the
+exact properties of the generated values, e.g. the mean and standard
+deviation of a normal distribution. The `Sample` trait is the most
+general, and allows for generating values that change some state
+internally. The `IndependentSample` trait is for generating values
+that do not need to record state.
+
+*/
+
+use std::num;
+use std::num::CheckedAdd;
+use {Rng, Rand};
+
+pub use self::range::Range;
+pub use self::gamma::{Gamma, ChiSquared, FisherF, StudentT};
+pub use self::normal::{Normal, LogNormal};
+pub use self::exponential::Exp;
+
+pub mod range;
+pub mod gamma;
+pub mod normal;
+pub mod exponential;
+
+/// Types that can be used to create a random instance of `Support`.
+pub trait Sample<Support> {
+    /// Generate a random value of `Support`, using `rng` as the
+    /// source of randomness.
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> Support;
+}
+
+/// `Sample`s that do not require keeping track of state.
+///
+/// Since no state is recorded, each sample is (statistically)
+/// independent of all others, assuming the `Rng` used has this
+/// property.
+// FIXME maybe having this separate is overkill (the only reason is to
+// take &self rather than &mut self)? or maybe this should be the
+// trait called `Sample` and the other should be `DependentSample`.
+pub trait IndependentSample<Support>: Sample<Support> {
+    /// Generate a random value.
+    fn ind_sample<R: Rng>(&self, &mut R) -> Support;
+}
+
+/// A wrapper for generating types that implement `Rand` via the
+/// `Sample` & `IndependentSample` traits.
+pub struct RandSample<Sup>;
+
+impl<Sup: Rand> Sample<Sup> for RandSample<Sup> {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
+}
+
+impl<Sup: Rand> IndependentSample<Sup> for RandSample<Sup> {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> Sup {
+        rng.gen()
+    }
+}
+
+/// A value with a particular weight for use with `WeightedChoice`.
+pub struct Weighted<T> {
+    /// The numerical weight of this item
+    weight: uint,
+    /// The actual item which is being weighted
+    item: T,
+}
+
+/// A distribution that selects from a finite collection of weighted items.
+///
+/// Each item has an associated weight that influences how likely it
+/// is to be chosen: higher weight is more likely.
+///
+/// The `Clone` restriction is a limitation of the `Sample` and
+/// `IndependentSample` traits. Note that `&T` is (cheaply) `Clone` for
+/// all `T`, as is `uint`, so one can store references or indices into
+/// another vector.
+///
+/// # Example
+///
+/// ```rust
+/// use rand::distributions::{Weighted, WeightedChoice, IndependentSample};
+///
+/// let wc = WeightedChoice::new(~[Weighted { weight: 2, item: 'a' },
+///                                Weighted { weight: 4, item: 'b' },
+///                                Weighted { weight: 1, item: 'c' }]);
+/// let mut rng = rand::task_rng();
+/// for _ in range(0, 16) {
+///      // on average prints 'a' 4 times, 'b' 8 and 'c' twice.
+///      println!("{}", wc.ind_sample(&mut rng));
+/// }
+/// ```
+pub struct WeightedChoice<T> {
+    priv items: ~[Weighted<T>],
+    priv weight_range: Range<uint>
+}
+
+impl<T: Clone> WeightedChoice<T> {
+    /// Create a new `WeightedChoice`.
+    ///
+    /// Fails if:
+    /// - `v` is empty
+    /// - the total weight is 0
+    /// - the total weight is larger than a `uint` can contain.
+    pub fn new(mut items: ~[Weighted<T>]) -> WeightedChoice<T> {
+        // strictly speaking, this is subsumed by the total weight == 0 case
+        assert!(!items.is_empty(), "WeightedChoice::new called with no items");
+
+        let mut running_total = 0u;
+
+        // we convert the list from individual weights to cumulative
+        // weights so we can binary search. This *could* drop elements
+        // with weight == 0 as an optimisation.
+        for item in items.mut_iter() {
+            running_total = running_total.checked_add(&item.weight)
+                .expect("WeightedChoice::new called with a total weight larger \
+                        than a uint can contain");
+
+            item.weight = running_total;
+        }
+        assert!(running_total != 0, "WeightedChoice::new called with a total weight of 0");
+
+        WeightedChoice {
+            items: items,
+            // we're likely to be generating numbers in this range
+            // relatively often, so might as well cache it
+            weight_range: Range::new(0, running_total)
+        }
+    }
+}
+
+impl<T: Clone> Sample<T> for WeightedChoice<T> {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> T { self.ind_sample(rng) }
+}
+
+impl<T: Clone> IndependentSample<T> for WeightedChoice<T> {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> T {
+        // we want to find the first element that has cumulative
+        // weight > sample_weight, which we do by binary since the
+        // cumulative weights of self.items are sorted.
+
+        // choose a weight in [0, total_weight)
+        let sample_weight = self.weight_range.ind_sample(rng);
+
+        // short circuit when it's the first item
+        if sample_weight < self.items[0].weight {
+            return self.items[0].item.clone();
+        }
+
+        let mut idx = 0;
+        let mut modifier = self.items.len();
+
+        // now we know that every possibility has an element to the
+        // left, so we can just search for the last element that has
+        // cumulative weight <= sample_weight, then the next one will
+        // be "it". (Note that this greatest element will never be the
+        // last element of the vector, since sample_weight is chosen
+        // in [0, total_weight) and the cumulative weight of the last
+        // one is exactly the total weight.)
+        while modifier > 1 {
+            let i = idx + modifier / 2;
+            if self.items[i].weight <= sample_weight {
+                // we're small, so look to the right, but allow this
+                // exact element still.
+                idx = i;
+                // we need the `/ 2` to round up otherwise we'll drop
+                // the trailing elements when `modifier` is odd.
+                modifier += 1;
+            } else {
+                // otherwise we're too big, so go left. (i.e. do
+                // nothing)
+            }
+            modifier /= 2;
+        }
+        return self.items[idx + 1].item.clone();
+    }
+}
+
+mod ziggurat_tables;
+
+/// Sample a random number using the Ziggurat method (specifically the
+/// ZIGNOR variant from Doornik 2005). Most of the arguments are
+/// directly from the paper:
+///
+/// * `rng`: source of randomness
+/// * `symmetric`: whether this is a symmetric distribution, or one-sided with P(x < 0) = 0.
+/// * `X`: the $x_i$ abscissae.
+/// * `F`: precomputed values of the PDF at the $x_i$, (i.e. $f(x_i)$)
+/// * `F_DIFF`: precomputed values of $f(x_i) - f(x_{i+1})$
+/// * `pdf`: the probability density function
+/// * `zero_case`: manual sampling from the tail when we chose the
+///    bottom box (i.e. i == 0)
+
+// the perf improvement (25-50%) is definitely worth the extra code
+// size from force-inlining.
+#[inline(always)]
+fn ziggurat<R:Rng>(
+            rng: &mut R,
+            symmetric: bool,
+            x_tab: ziggurat_tables::ZigTable,
+            f_tab: ziggurat_tables::ZigTable,
+            pdf: 'static |f64| -> f64,
+            zero_case: 'static |&mut R, f64| -> f64)
+            -> f64 {
+    static SCALE: f64 = (1u64 << 53) as f64;
+    loop {
+        // reimplement the f64 generation as an optimisation suggested
+        // by the Doornik paper: we have a lot of precision-space
+        // (i.e. there are 11 bits of the 64 of a u64 to use after
+        // creating a f64), so we might as well reuse some to save
+        // generating a whole extra random number. (Seems to be 15%
+        // faster.)
+        let bits: u64 = rng.gen();
+        let i = (bits & 0xff) as uint;
+        let f = (bits >> 11) as f64 / SCALE;
+
+        // u is either U(-1, 1) or U(0, 1) depending on if this is a
+        // symmetric distribution or not.
+        let u = if symmetric {2.0 * f - 1.0} else {f};
+        let x = u * x_tab[i];
+
+        let test_x = if symmetric {num::abs(x)} else {x};
+
+        // algebraically equivalent to |u| < x_tab[i+1]/x_tab[i] (or u < x_tab[i+1]/x_tab[i])
+        if test_x < x_tab[i + 1] {
+            return x;
+        }
+        if i == 0 {
+            return zero_case(rng, u);
+        }
+        // algebraically equivalent to f1 + DRanU()*(f0 - f1) < 1
+        if f_tab[i + 1] + (f_tab[i] - f_tab[i + 1]) * rng.gen() < pdf(x) {
+            return x;
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use {task_rng, Rng, Rand};
+    use super::{RandSample, WeightedChoice, Weighted, Sample, IndependentSample};
+
+    #[deriving(Eq, Show)]
+    struct ConstRand(uint);
+    impl Rand for ConstRand {
+        fn rand<R: Rng>(_: &mut R) -> ConstRand {
+            ConstRand(0)
+        }
+    }
+
+    // 0, 1, 2, 3, ...
+    struct CountingRng { i: u32 }
+    impl Rng for CountingRng {
+        fn next_u32(&mut self) -> u32 {
+            self.i += 1;
+            self.i - 1
+        }
+        fn next_u64(&mut self) -> u64 {
+            self.next_u32() as u64
+        }
+    }
+
+    #[test]
+    fn test_rand_sample() {
+        let mut rand_sample = RandSample::<ConstRand>;
+
+        assert_eq!(rand_sample.sample(&mut task_rng()), ConstRand(0));
+        assert_eq!(rand_sample.ind_sample(&mut task_rng()), ConstRand(0));
+    }
+    #[test]
+    fn test_weighted_choice() {
+        // this makes assumptions about the internal implementation of
+        // WeightedChoice, specifically: it doesn't reorder the items,
+        // it doesn't do weird things to the RNG (so 0 maps to 0, 1 to
+        // 1, internally; modulo a modulo operation).
+
+        macro_rules! t (
+            ($items:expr, $expected:expr) => {{
+                let wc = WeightedChoice::new($items);
+                let expected = $expected;
+
+                let mut rng = CountingRng { i: 0 };
+
+                for &val in expected.iter() {
+                    assert_eq!(wc.ind_sample(&mut rng), val)
+                }
+            }}
+        );
+
+        t!(~[Weighted { weight: 1, item: 10}], ~[10]);
+
+        // skip some
+        t!(~[Weighted { weight: 0, item: 20},
+             Weighted { weight: 2, item: 21},
+             Weighted { weight: 0, item: 22},
+             Weighted { weight: 1, item: 23}],
+           ~[21,21, 23]);
+
+        // different weights
+        t!(~[Weighted { weight: 4, item: 30},
+             Weighted { weight: 3, item: 31}],
+           ~[30,30,30,30, 31,31,31]);
+
+        // check that we're binary searching
+        // correctly with some vectors of odd
+        // length.
+        t!(~[Weighted { weight: 1, item: 40},
+             Weighted { weight: 1, item: 41},
+             Weighted { weight: 1, item: 42},
+             Weighted { weight: 1, item: 43},
+             Weighted { weight: 1, item: 44}],
+           ~[40, 41, 42, 43, 44]);
+        t!(~[Weighted { weight: 1, item: 50},
+             Weighted { weight: 1, item: 51},
+             Weighted { weight: 1, item: 52},
+             Weighted { weight: 1, item: 53},
+             Weighted { weight: 1, item: 54},
+             Weighted { weight: 1, item: 55},
+             Weighted { weight: 1, item: 56}],
+           ~[50, 51, 52, 53, 54, 55, 56]);
+    }
+
+    #[test] #[should_fail]
+    fn test_weighted_choice_no_items() {
+        WeightedChoice::<int>::new(~[]);
+    }
+    #[test] #[should_fail]
+    fn test_weighted_choice_zero_weight() {
+        WeightedChoice::new(~[Weighted { weight: 0, item: 0},
+                              Weighted { weight: 0, item: 1}]);
+    }
+    #[test] #[should_fail]
+    fn test_weighted_choice_weight_overflows() {
+        let x = (-1) as uint / 2; // x + x + 2 is the overflow
+        WeightedChoice::new(~[Weighted { weight: x, item: 0 },
+                              Weighted { weight: 1, item: 1 },
+                              Weighted { weight: x, item: 2 },
+                              Weighted { weight: 1, item: 3 }]);
+    }
+}
diff --git a/src/librand/distributions/normal.rs b/src/librand/distributions/normal.rs
new file mode 100644 (file)
index 0000000..4c9567e
--- /dev/null
@@ -0,0 +1,206 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The normal and derived distributions.
+
+use std::num::Float;
+use {Rng, Rand, Open01};
+use distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample};
+
+/// A wrapper around an `f64` to generate N(0, 1) random numbers
+/// (a.k.a.  a standard normal, or Gaussian).
+///
+/// See `Normal` for the general normal distribution. That this has to
+/// be unwrapped before use as an `f64` (using either `*` or
+/// `cast::transmute` is safe).
+///
+/// Implemented via the ZIGNOR variant[1] of the Ziggurat method.
+///
+/// [1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
+/// Generate Normal Random
+/// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
+/// College, Oxford
+pub struct StandardNormal(f64);
+
+impl Rand for StandardNormal {
+    fn rand<R:Rng>(rng: &mut R) -> StandardNormal {
+        #[inline]
+        fn pdf(x: f64) -> f64 {
+            (-x*x/2.0).exp()
+        }
+        #[inline]
+        fn zero_case<R:Rng>(rng: &mut R, u: f64) -> f64 {
+            // compute a random number in the tail by hand
+
+            // strange initial conditions, because the loop is not
+            // do-while, so the condition should be true on the first
+            // run, they get overwritten anyway (0 < 1, so these are
+            // good).
+            let mut x = 1.0f64;
+            let mut y = 0.0f64;
+
+            while -2.0 * y < x * x {
+                let Open01(x_) = rng.gen::<Open01<f64>>();
+                let Open01(y_) = rng.gen::<Open01<f64>>();
+
+                x = x_.ln() / ziggurat_tables::ZIG_NORM_R;
+                y = y_.ln();
+            }
+
+            if u < 0.0 { x - ziggurat_tables::ZIG_NORM_R } else { ziggurat_tables::ZIG_NORM_R - x }
+        }
+
+        StandardNormal(ziggurat(
+            rng,
+            true, // this is symmetric
+            &ziggurat_tables::ZIG_NORM_X,
+            &ziggurat_tables::ZIG_NORM_F,
+            pdf, zero_case))
+    }
+}
+
+/// The normal distribution `N(mean, std_dev**2)`.
+///
+/// This uses the ZIGNOR variant of the Ziggurat method, see
+/// `StandardNormal` for more details.
+///
+/// # Example
+///
+/// ```rust
+/// use rand::distributions::{Normal, IndependentSample};
+///
+/// // mean 2, standard deviation 3
+/// let normal = Normal::new(2.0, 3.0);
+/// let v = normal.ind_sample(&mut rand::task_rng());
+/// println!("{} is from a N(2, 9) distribution", v)
+/// ```
+pub struct Normal {
+    priv mean: f64,
+    priv std_dev: f64
+}
+
+impl Normal {
+    /// Construct a new `Normal` distribution with the given mean and
+    /// standard deviation. Fails if `std_dev < 0`.
+    pub fn new(mean: f64, std_dev: f64) -> Normal {
+        assert!(std_dev >= 0.0, "Normal::new called with `std_dev` < 0");
+        Normal {
+            mean: mean,
+            std_dev: std_dev
+        }
+    }
+}
+impl Sample<f64> for Normal {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
+}
+impl IndependentSample<f64> for Normal {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
+        let StandardNormal(n) = rng.gen::<StandardNormal>();
+        self.mean + self.std_dev * n
+    }
+}
+
+
+/// The log-normal distribution `ln N(mean, std_dev**2)`.
+///
+/// If `X` is log-normal distributed, then `ln(X)` is `N(mean,
+/// std_dev**2)` distributed.
+///
+/// # Example
+///
+/// ```rust
+/// use rand::distributions::{LogNormal, IndependentSample};
+///
+/// // mean 2, standard deviation 3
+/// let log_normal = LogNormal::new(2.0, 3.0);
+/// let v = log_normal.ind_sample(&mut rand::task_rng());
+/// println!("{} is from an ln N(2, 9) distribution", v)
+/// ```
+pub struct LogNormal {
+    priv norm: Normal
+}
+
+impl LogNormal {
+    /// Construct a new `LogNormal` distribution with the given mean
+    /// and standard deviation. Fails if `std_dev < 0`.
+    pub fn new(mean: f64, std_dev: f64) -> LogNormal {
+        assert!(std_dev >= 0.0, "LogNormal::new called with `std_dev` < 0");
+        LogNormal { norm: Normal::new(mean, std_dev) }
+    }
+}
+impl Sample<f64> for LogNormal {
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
+}
+impl IndependentSample<f64> for LogNormal {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
+        self.norm.ind_sample(rng).exp()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use distributions::{Sample, IndependentSample};
+    use {Rng, task_rng};
+    use super::{Normal, LogNormal};
+
+    #[test]
+    fn test_normal() {
+        let mut norm = Normal::new(10.0, 10.0);
+        let mut rng = task_rng();
+        for _ in range(0, 1000) {
+            norm.sample(&mut rng);
+            norm.ind_sample(&mut rng);
+        }
+    }
+    #[test]
+    #[should_fail]
+    fn test_normal_invalid_sd() {
+        Normal::new(10.0, -1.0);
+    }
+
+
+    #[test]
+    fn test_log_normal() {
+        let mut lnorm = LogNormal::new(10.0, 10.0);
+        let mut rng = task_rng();
+        for _ in range(0, 1000) {
+            lnorm.sample(&mut rng);
+            lnorm.ind_sample(&mut rng);
+        }
+    }
+    #[test]
+    #[should_fail]
+    fn test_log_normal_invalid_sd() {
+        LogNormal::new(10.0, -1.0);
+    }
+}
+
+#[cfg(test)]
+mod bench {
+    extern crate test;
+    use self::test::BenchHarness;
+    use std::mem::size_of;
+    use {XorShiftRng, RAND_BENCH_N};
+    use distributions::{Sample};
+    use super::Normal;
+
+    #[bench]
+    fn rand_normal(bh: &mut BenchHarness) {
+        let mut rng = XorShiftRng::new();
+        let mut normal = Normal::new(-2.71828, 3.14159);
+
+        bh.iter(|| {
+            for _ in range(0, RAND_BENCH_N) {
+                normal.sample(&mut rng);
+            }
+        });
+        bh.bytes = size_of::<f64>() as u64 * RAND_BENCH_N;
+    }
+}
diff --git a/src/librand/distributions/range.rs b/src/librand/distributions/range.rs
new file mode 100644 (file)
index 0000000..8256a37
--- /dev/null
@@ -0,0 +1,231 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Generating numbers between two others.
+
+// this is surprisingly complicated to be both generic & correct
+
+use std::num::Bounded;
+use Rng;
+use distributions::{Sample, IndependentSample};
+
+/// Sample values uniformly between two bounds.
+///
+/// This gives a uniform distribution (assuming the RNG used to sample
+/// it is itself uniform & the `SampleRange` implementation for the
+/// given type is correct), even for edge cases like `low = 0u8`,
+/// `high = 170u8`, for which a naive modulo operation would return
+/// numbers less than 85 with double the probability to those greater
+/// than 85.
+///
+/// Types should attempt to sample in `[low, high)`, i.e., not
+/// including `high`, but this may be very difficult. All the
+/// primitive integer types satisfy this property, and the float types
+/// normally satisfy it, but rounding may mean `high` can occur.
+///
+/// # Example
+///
+/// ```rust
+/// use rand::distributions::{IndependentSample, Range};
+///
+/// fn main() {
+///     let between = Range::new(10u, 10000u);
+///     let mut rng = rand::task_rng();
+///     let mut sum = 0;
+///     for _ in range(0, 1000) {
+///         sum += between.ind_sample(&mut rng);
+///     }
+///     println!("{}", sum);
+/// }
+/// ```
+pub struct Range<X> {
+    priv low: X,
+    priv range: X,
+    priv accept_zone: X
+}
+
+impl<X: SampleRange + Ord> Range<X> {
+    /// Create a new `Range` instance that samples uniformly from
+    /// `[low, high)`. Fails if `low >= high`.
+    pub fn new(low: X, high: X) -> Range<X> {
+        assert!(low < high, "Range::new called with `low >= high`");
+        SampleRange::construct_range(low, high)
+    }
+}
+
+impl<Sup: SampleRange> Sample<Sup> for Range<Sup> {
+    #[inline]
+    fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
+}
+impl<Sup: SampleRange> IndependentSample<Sup> for Range<Sup> {
+    fn ind_sample<R: Rng>(&self, rng: &mut R) -> Sup {
+        SampleRange::sample_range(self, rng)
+    }
+}
+
+/// The helper trait for types that have a sensible way to sample
+/// uniformly between two values. This should not be used directly,
+/// and is only to facilitate `Range`.
+pub trait SampleRange {
+    /// Construct the `Range` object that `sample_range`
+    /// requires. This should not ever be called directly, only via
+    /// `Range::new`, which will check that `low < high`, so this
+    /// function doesn't have to repeat the check.
+    fn construct_range(low: Self, high: Self) -> Range<Self>;
+
+    /// Sample a value from the given `Range` with the given `Rng` as
+    /// a source of randomness.
+    fn sample_range<R: Rng>(r: &Range<Self>, rng: &mut R) -> Self;
+}
+
+macro_rules! integer_impl {
+    ($ty:ty, $unsigned:ty) => {
+        impl SampleRange for $ty {
+            // we play free and fast with unsigned vs signed here
+            // (when $ty is signed), but that's fine, since the
+            // contract of this macro is for $ty and $unsigned to be
+            // "bit-equal", so casting between them is a no-op & a
+            // bijection.
+
+            fn construct_range(low: $ty, high: $ty) -> Range<$ty> {
+                let range = high as $unsigned - low as $unsigned;
+                let unsigned_max: $unsigned = Bounded::max_value();
+
+                // this is the largest number that fits into $unsigned
+                // that `range` divides evenly, so, if we've sampled
+                // `n` uniformly from this region, then `n % range` is
+                // uniform in [0, range)
+                let zone = unsigned_max - unsigned_max % range;
+
+                Range {
+                    low: low,
+                    range: range as $ty,
+                    accept_zone: zone as $ty
+                }
+            }
+            #[inline]
+            fn sample_range<R: Rng>(r: &Range<$ty>, rng: &mut R) -> $ty {
+                loop {
+                    // rejection sample
+                    let v = rng.gen::<$unsigned>();
+                    // until we find something that fits into the
+                    // region which r.range evenly divides (this will
+                    // be uniformly distributed)
+                    if v < r.accept_zone as $unsigned {
+                        // and return it, with some adjustments
+                        return r.low + (v % r.range as $unsigned) as $ty;
+                    }
+                }
+            }
+        }
+    }
+}
+
+integer_impl! { i8, u8 }
+integer_impl! { i16, u16 }
+integer_impl! { i32, u32 }
+integer_impl! { i64, u64 }
+integer_impl! { int, uint }
+integer_impl! { u8, u8 }
+integer_impl! { u16, u16 }
+integer_impl! { u32, u32 }
+integer_impl! { u64, u64 }
+integer_impl! { uint, uint }
+
+macro_rules! float_impl {
+    ($ty:ty) => {
+        impl SampleRange for $ty {
+            fn construct_range(low: $ty, high: $ty) -> Range<$ty> {
+                Range {
+                    low: low,
+                    range: high - low,
+                    accept_zone: 0.0 // unused
+                }
+            }
+            fn sample_range<R: Rng>(r: &Range<$ty>, rng: &mut R) -> $ty {
+                r.low + r.range * rng.gen()
+            }
+        }
+    }
+}
+
+float_impl! { f32 }
+float_impl! { f64 }
+
+#[cfg(test)]
+mod tests {
+    use distributions::{Sample, IndependentSample};
+    use {Rng, task_rng};
+    use super::Range;
+    use std::num::Bounded;
+
+    #[should_fail]
+    #[test]
+    fn test_range_bad_limits_equal() {
+        Range::new(10, 10);
+    }
+    #[should_fail]
+    #[test]
+    fn test_range_bad_limits_flipped() {
+        Range::new(10, 5);
+    }
+
+    #[test]
+    fn test_integers() {
+        let mut rng = task_rng();
+        macro_rules! t (
+            ($($ty:ty),*) => {{
+                $(
+                   let v: &[($ty, $ty)] = [(0, 10),
+                                           (10, 127),
+                                           (Bounded::min_value(), Bounded::max_value())];
+                   for &(low, high) in v.iter() {
+                        let mut sampler: Range<$ty> = Range::new(low, high);
+                        for _ in range(0, 1000) {
+                            let v = sampler.sample(&mut rng);
+                            assert!(low <= v && v < high);
+                            let v = sampler.ind_sample(&mut rng);
+                            assert!(low <= v && v < high);
+                        }
+                    }
+                 )*
+            }}
+        );
+        t!(i8, i16, i32, i64, int,
+           u8, u16, u32, u64, uint)
+    }
+
+    #[test]
+    fn test_floats() {
+        let mut rng = task_rng();
+        macro_rules! t (
+            ($($ty:ty),*) => {{
+                $(
+                   let v: &[($ty, $ty)] = [(0.0, 100.0),
+                                           (-1e35, -1e25),
+                                           (1e-35, 1e-25),
+                                           (-1e35, 1e35)];
+                   for &(low, high) in v.iter() {
+                        let mut sampler: Range<$ty> = Range::new(low, high);
+                        for _ in range(0, 1000) {
+                            let v = sampler.sample(&mut rng);
+                            assert!(low <= v && v < high);
+                            let v = sampler.ind_sample(&mut rng);
+                            assert!(low <= v && v < high);
+                        }
+                    }
+                 )*
+            }}
+        );
+
+        t!(f32, f64)
+    }
+
+}
diff --git a/src/librand/distributions/ziggurat_tables.rs b/src/librand/distributions/ziggurat_tables.rs
new file mode 100644 (file)
index 0000000..049ef3d
--- /dev/null
@@ -0,0 +1,280 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tables for distributions which are sampled using the ziggurat
+// algorithm. Autogenerated by `ziggurat_tables.py`.
+
+pub type ZigTable = &'static [f64, .. 257];
+pub static ZIG_NORM_R: f64 = 3.654152885361008796;
+pub static ZIG_NORM_X: [f64, .. 257] =
+    [3.910757959537090045, 3.654152885361008796, 3.449278298560964462, 3.320244733839166074,
+     3.224575052047029100, 3.147889289517149969, 3.083526132001233044, 3.027837791768635434,
+     2.978603279880844834, 2.934366867207854224, 2.894121053612348060, 2.857138730872132548,
+     2.822877396825325125, 2.790921174000785765, 2.760944005278822555, 2.732685359042827056,
+     2.705933656121858100, 2.680514643284522158, 2.656283037575502437, 2.633116393630324570,
+     2.610910518487548515, 2.589575986706995181, 2.569035452680536569, 2.549221550323460761,
+     2.530075232158516929, 2.511544441625342294, 2.493583041269680667, 2.476149939669143318,
+     2.459208374333311298, 2.442725318198956774, 2.426670984935725972, 2.411018413899685520,
+     2.395743119780480601, 2.380822795170626005, 2.366237056715818632, 2.351967227377659952,
+     2.337996148795031370, 2.324308018869623016, 2.310888250599850036, 2.297723348901329565,
+     2.284800802722946056, 2.272108990226823888, 2.259637095172217780, 2.247375032945807760,
+     2.235313384928327984, 2.223443340090905718, 2.211756642882544366, 2.200245546609647995,
+     2.188902771624720689, 2.177721467738641614, 2.166695180352645966, 2.155817819875063268,
+     2.145083634046203613, 2.134487182844320152, 2.124023315687815661, 2.113687150684933957,
+     2.103474055713146829, 2.093379631137050279, 2.083399693996551783, 2.073530263516978778,
+     2.063767547809956415, 2.054107931648864849, 2.044547965215732788, 2.035084353727808715,
+     2.025713947862032960, 2.016433734904371722, 2.007240830558684852, 1.998132471356564244,
+     1.989106007615571325, 1.980158896898598364, 1.971288697931769640, 1.962493064942461896,
+     1.953769742382734043, 1.945116560006753925, 1.936531428273758904, 1.928012334050718257,
+     1.919557336591228847, 1.911164563769282232, 1.902832208548446369, 1.894558525668710081,
+     1.886341828534776388, 1.878180486290977669, 1.870072921069236838, 1.862017605397632281,
+     1.854013059758148119, 1.846057850283119750, 1.838150586580728607, 1.830289919680666566,
+     1.822474540091783224, 1.814703175964167636, 1.806974591348693426, 1.799287584547580199,
+     1.791640986550010028, 1.784033659547276329, 1.776464495522344977, 1.768932414909077933,
+     1.761436365316706665, 1.753975320315455111, 1.746548278279492994, 1.739154261283669012,
+     1.731792314050707216, 1.724461502945775715, 1.717160915015540690, 1.709889657069006086,
+     1.702646854797613907, 1.695431651932238548, 1.688243209434858727, 1.681080704722823338,
+     1.673943330923760353, 1.666830296159286684, 1.659740822855789499, 1.652674147080648526,
+     1.645629517902360339, 1.638606196773111146, 1.631603456932422036, 1.624620582830568427,
+     1.617656869570534228, 1.610711622367333673, 1.603784156023583041, 1.596873794420261339,
+     1.589979870021648534, 1.583101723393471438, 1.576238702733332886, 1.569390163412534456,
+     1.562555467528439657, 1.555733983466554893, 1.548925085471535512, 1.542128153226347553,
+     1.535342571438843118, 1.528567729435024614, 1.521803020758293101, 1.515047842773992404,
+     1.508301596278571965, 1.501563685112706548, 1.494833515777718391, 1.488110497054654369,
+     1.481394039625375747, 1.474683555695025516, 1.467978458615230908, 1.461278162507407830,
+     1.454582081885523293, 1.447889631277669675, 1.441200224845798017, 1.434513276002946425,
+     1.427828197027290358, 1.421144398672323117, 1.414461289772464658, 1.407778276843371534,
+     1.401094763676202559, 1.394410150925071257, 1.387723835686884621, 1.381035211072741964,
+     1.374343665770030531, 1.367648583594317957, 1.360949343030101844, 1.354245316759430606,
+     1.347535871177359290, 1.340820365893152122, 1.334098153216083604, 1.327368577624624679,
+     1.320630975217730096, 1.313884673146868964, 1.307128989027353860, 1.300363230327433728,
+     1.293586693733517645, 1.286798664489786415, 1.279998415710333237, 1.273185207661843732,
+     1.266358287014688333, 1.259516886060144225, 1.252660221891297887, 1.245787495544997903,
+     1.238897891102027415, 1.231990574742445110, 1.225064693752808020, 1.218119375481726552,
+     1.211153726239911244, 1.204166830140560140, 1.197157747875585931, 1.190125515422801650,
+     1.183069142678760732, 1.175987612011489825, 1.168879876726833800, 1.161744859441574240,
+     1.154581450355851802, 1.147388505416733873, 1.140164844363995789, 1.132909248648336975,
+     1.125620459211294389, 1.118297174115062909, 1.110938046009249502, 1.103541679420268151,
+     1.096106627847603487, 1.088631390649514197, 1.081114409698889389, 1.073554065787871714,
+     1.065948674757506653, 1.058296483326006454, 1.050595664586207123, 1.042844313139370538,
+     1.035040439828605274, 1.027181966030751292, 1.019266717460529215, 1.011292417434978441,
+     1.003256679539591412, 0.995156999629943084, 0.986990747093846266, 0.978755155288937750,
+     0.970447311058864615, 0.962064143217605250, 0.953602409875572654, 0.945058684462571130,
+     0.936429340280896860, 0.927710533396234771, 0.918898183643734989, 0.909987953490768997,
+     0.900975224455174528, 0.891855070726792376, 0.882622229578910122, 0.873271068082494550,
+     0.863795545546826915, 0.854189171001560554, 0.844444954902423661, 0.834555354079518752,
+     0.824512208745288633, 0.814306670128064347, 0.803929116982664893, 0.793369058833152785,
+     0.782615023299588763, 0.771654424216739354, 0.760473406422083165, 0.749056662009581653,
+     0.737387211425838629, 0.725446140901303549, 0.713212285182022732, 0.700661841097584448,
+     0.687767892786257717, 0.674499822827436479, 0.660822574234205984, 0.646695714884388928,
+     0.632072236375024632, 0.616896989996235545, 0.601104617743940417, 0.584616766093722262,
+     0.567338257040473026, 0.549151702313026790, 0.529909720646495108, 0.509423329585933393,
+     0.487443966121754335, 0.463634336771763245, 0.437518402186662658, 0.408389134588000746,
+     0.375121332850465727, 0.335737519180459465, 0.286174591747260509, 0.215241895913273806,
+     0.000000000000000000];
+pub static ZIG_NORM_F: [f64, .. 257] =
+    [0.000477467764586655, 0.001260285930498598, 0.002609072746106363, 0.004037972593371872,
+     0.005522403299264754, 0.007050875471392110, 0.008616582769422917, 0.010214971439731100,
+     0.011842757857943104, 0.013497450601780807, 0.015177088307982072, 0.016880083152595839,
+     0.018605121275783350, 0.020351096230109354, 0.022117062707379922, 0.023902203305873237,
+     0.025705804008632656, 0.027527235669693315, 0.029365939758230111, 0.031221417192023690,
+     0.033093219458688698, 0.034980941461833073, 0.036884215688691151, 0.038802707404656918,
+     0.040736110656078753, 0.042684144916619378, 0.044646552251446536, 0.046623094902089664,
+     0.048613553216035145, 0.050617723861121788, 0.052635418276973649, 0.054666461325077916,
+     0.056710690106399467, 0.058767952921137984, 0.060838108349751806, 0.062921024437977854,
+     0.065016577971470438, 0.067124653828023989, 0.069245144397250269, 0.071377949059141965,
+     0.073522973714240991, 0.075680130359194964, 0.077849336702372207, 0.080030515814947509,
+     0.082223595813495684, 0.084428509570654661, 0.086645194450867782, 0.088873592068594229,
+     0.091113648066700734, 0.093365311913026619, 0.095628536713353335, 0.097903279039215627,
+     0.100189498769172020, 0.102487158942306270, 0.104796225622867056, 0.107116667775072880,
+     0.109448457147210021, 0.111791568164245583, 0.114145977828255210, 0.116511665626037014,
+     0.118888613443345698, 0.121276805485235437, 0.123676228202051403, 0.126086870220650349,
+     0.128508722280473636, 0.130941777174128166, 0.133386029692162844, 0.135841476571757352,
+     0.138308116449064322, 0.140785949814968309, 0.143274978974047118, 0.145775208006537926,
+     0.148286642733128721, 0.150809290682410169, 0.153343161060837674, 0.155888264725064563,
+     0.158444614156520225, 0.161012223438117663, 0.163591108232982951, 0.166181285765110071,
+     0.168782774801850333, 0.171395595638155623, 0.174019770082499359, 0.176655321444406654,
+     0.179302274523530397, 0.181960655600216487, 0.184630492427504539, 0.187311814224516926,
+     0.190004651671193070, 0.192709036904328807, 0.195425003514885592, 0.198152586546538112,
+     0.200891822495431333, 0.203642749311121501, 0.206405406398679298, 0.209179834621935651,
+     0.211966076307852941, 0.214764175252008499, 0.217574176725178370, 0.220396127481011589,
+     0.223230075764789593, 0.226076071323264877, 0.228934165415577484, 0.231804410825248525,
+     0.234686861873252689, 0.237581574432173676, 0.240488605941449107, 0.243408015423711988,
+     0.246339863502238771, 0.249284212419516704, 0.252241126056943765, 0.255210669955677150,
+     0.258192911338648023, 0.261187919133763713, 0.264195763998317568, 0.267216518344631837,
+     0.270250256366959984, 0.273297054069675804, 0.276356989296781264, 0.279430141762765316,
+     0.282516593084849388, 0.285616426816658109, 0.288729728483353931, 0.291856585618280984,
+     0.294997087801162572, 0.298151326697901342, 0.301319396102034120, 0.304501391977896274,
+     0.307697412505553769, 0.310907558127563710, 0.314131931597630143, 0.317370638031222396,
+     0.320623784958230129, 0.323891482377732021, 0.327173842814958593, 0.330470981380537099,
+     0.333783015832108509, 0.337110066638412809, 0.340452257045945450, 0.343809713148291340,
+     0.347182563958251478, 0.350570941482881204, 0.353974980801569250, 0.357394820147290515,
+     0.360830600991175754, 0.364282468130549597, 0.367750569780596226, 0.371235057669821344,
+     0.374736087139491414, 0.378253817247238111, 0.381788410875031348, 0.385340034841733958,
+     0.388908860020464597, 0.392495061461010764, 0.396098818517547080, 0.399720314981931668,
+     0.403359739222868885, 0.407017284331247953, 0.410693148271983222, 0.414387534042706784,
+     0.418100649839684591, 0.421832709231353298, 0.425583931339900579, 0.429354541031341519,
+     0.433144769114574058, 0.436954852549929273, 0.440785034667769915, 0.444635565397727750,
+     0.448506701509214067, 0.452398706863882505, 0.456311852680773566, 0.460246417814923481,
+     0.464202689050278838, 0.468180961407822172, 0.472181538469883255, 0.476204732721683788,
+     0.480250865911249714, 0.484320269428911598, 0.488413284707712059, 0.492530263646148658,
+     0.496671569054796314, 0.500837575128482149, 0.505028667945828791, 0.509245245998136142,
+     0.513487720749743026, 0.517756517232200619, 0.522052074674794864, 0.526374847174186700,
+     0.530725304406193921, 0.535103932383019565, 0.539511234259544614, 0.543947731192649941,
+     0.548413963257921133, 0.552910490428519918, 0.557437893621486324, 0.561996775817277916,
+     0.566587763258951771, 0.571211506738074970, 0.575868682975210544, 0.580559996103683473,
+     0.585286179266300333, 0.590047996335791969, 0.594846243770991268, 0.599681752622167719,
+     0.604555390700549533, 0.609468064928895381, 0.614420723892076803, 0.619414360609039205,
+     0.624450015550274240, 0.629528779928128279, 0.634651799290960050, 0.639820277456438991,
+     0.645035480824251883, 0.650298743114294586, 0.655611470583224665, 0.660975147780241357,
+     0.666391343912380640, 0.671861719900766374, 0.677388036222513090, 0.682972161648791376,
+     0.688616083008527058, 0.694321916130032579, 0.700091918140490099, 0.705928501336797409,
+     0.711834248882358467, 0.717811932634901395, 0.723864533472881599, 0.729995264565802437,
+     0.736207598131266683, 0.742505296344636245, 0.748892447223726720, 0.755373506511754500,
+     0.761953346841546475, 0.768637315803334831, 0.775431304986138326, 0.782341832659861902,
+     0.789376143571198563, 0.796542330428254619, 0.803849483176389490, 0.811307874318219935,
+     0.818929191609414797, 0.826726833952094231, 0.834716292992930375, 0.842915653118441077,
+     0.851346258465123684, 0.860033621203008636, 0.869008688043793165, 0.878309655816146839,
+     0.887984660763399880, 0.898095921906304051, 0.908726440060562912, 0.919991505048360247,
+     0.932060075968990209, 0.945198953453078028, 0.959879091812415930, 0.977101701282731328,
+     1.000000000000000000];
+pub static ZIG_EXP_R: f64 = 7.697117470131050077;
+pub static ZIG_EXP_X: [f64, .. 257] =
+    [8.697117470131052741, 7.697117470131050077, 6.941033629377212577, 6.478378493832569696,
+     6.144164665772472667, 5.882144315795399869, 5.666410167454033697, 5.482890627526062488,
+     5.323090505754398016, 5.181487281301500047, 5.054288489981304089, 4.938777085901250530,
+     4.832939741025112035, 4.735242996601741083, 4.644491885420085175, 4.559737061707351380,
+     4.480211746528421912, 4.405287693473573185, 4.334443680317273007, 4.267242480277365857,
+     4.203313713735184365, 4.142340865664051464, 4.084051310408297830, 4.028208544647936762,
+     3.974606066673788796, 3.923062500135489739, 3.873417670399509127, 3.825529418522336744,
+     3.779270992411667862, 3.734528894039797375, 3.691201090237418825, 3.649195515760853770,
+     3.608428813128909507, 3.568825265648337020, 3.530315889129343354, 3.492837654774059608,
+     3.456332821132760191, 3.420748357251119920, 3.386035442460300970, 3.352149030900109405,
+     3.319047470970748037, 3.286692171599068679, 3.255047308570449882, 3.224079565286264160,
+     3.193757903212240290, 3.164053358025972873, 3.134938858084440394, 3.106389062339824481,
+     3.078380215254090224, 3.050890016615455114, 3.023897504455676621, 2.997382949516130601,
+     2.971327759921089662, 2.945714394895045718, 2.920526286512740821, 2.895747768600141825,
+     2.871364012015536371, 2.847360965635188812, 2.823725302450035279, 2.800444370250737780,
+     2.777506146439756574, 2.754899196562344610, 2.732612636194700073, 2.710636095867928752,
+     2.688959688741803689, 2.667573980773266573, 2.646469963151809157, 2.625639026797788489,
+     2.605072938740835564, 2.584763820214140750, 2.564704126316905253, 2.544886627111869970,
+     2.525304390037828028, 2.505950763528594027, 2.486819361740209455, 2.467904050297364815,
+     2.449198932978249754, 2.430698339264419694, 2.412396812688870629, 2.394289099921457886,
+     2.376370140536140596, 2.358635057409337321, 2.341079147703034380, 2.323697874390196372,
+     2.306486858283579799, 2.289441870532269441, 2.272558825553154804, 2.255833774367219213,
+     2.239262898312909034, 2.222842503111036816, 2.206569013257663858, 2.190438966723220027,
+     2.174449009937774679, 2.158595893043885994, 2.142876465399842001, 2.127287671317368289,
+     2.111826546019042183, 2.096490211801715020, 2.081275874393225145, 2.066180819490575526,
+     2.051202409468584786, 2.036338080248769611, 2.021585338318926173, 2.006941757894518563,
+     1.992404978213576650, 1.977972700957360441, 1.963642687789548313, 1.949412758007184943,
+     1.935280786297051359, 1.921244700591528076, 1.907302480018387536, 1.893452152939308242,
+     1.879691795072211180, 1.866019527692827973, 1.852433515911175554, 1.838931967018879954,
+     1.825513128903519799, 1.812175288526390649, 1.798916770460290859, 1.785735935484126014,
+     1.772631179231305643, 1.759600930889074766, 1.746643651946074405, 1.733757834985571566,
+     1.720942002521935299, 1.708194705878057773, 1.695514524101537912, 1.682900062917553896,
+     1.670349953716452118, 1.657862852574172763, 1.645437439303723659, 1.633072416535991334,
+     1.620766508828257901, 1.608518461798858379, 1.596327041286483395, 1.584191032532688892,
+     1.572109239386229707, 1.560080483527888084, 1.548103603714513499, 1.536177455041032092,
+     1.524300908219226258, 1.512472848872117082, 1.500692176842816750, 1.488957805516746058,
+     1.477268661156133867, 1.465623682245745352, 1.454021818848793446, 1.442462031972012504,
+     1.430943292938879674, 1.419464582769983219, 1.408024891569535697, 1.396623217917042137,
+     1.385258568263121992, 1.373929956328490576, 1.362636402505086775, 1.351376933258335189,
+     1.340150580529504643, 1.328956381137116560, 1.317793376176324749, 1.306660610415174117,
+     1.295557131686601027, 1.284481990275012642, 1.273434238296241139, 1.262412929069615330,
+     1.251417116480852521, 1.240445854334406572, 1.229498195693849105, 1.218573192208790124,
+     1.207669893426761121, 1.196787346088403092, 1.185924593404202199, 1.175080674310911677,
+     1.164254622705678921, 1.153445466655774743, 1.142652227581672841, 1.131873919411078511,
+     1.121109547701330200, 1.110358108727411031, 1.099618588532597308, 1.088889961938546813,
+     1.078171191511372307, 1.067461226479967662, 1.056759001602551429, 1.046063435977044209,
+     1.035373431790528542, 1.024687873002617211, 1.014005623957096480, 1.003325527915696735,
+     0.992646405507275897, 0.981967053085062602, 0.971286240983903260, 0.960602711668666509,
+     0.949915177764075969, 0.939222319955262286, 0.928522784747210395, 0.917815182070044311,
+     0.907098082715690257, 0.896370015589889935, 0.885629464761751528, 0.874874866291025066,
+     0.864104604811004484, 0.853317009842373353, 0.842510351810368485, 0.831682837734273206,
+     0.820832606554411814, 0.809957724057418282, 0.799056177355487174, 0.788125868869492430,
+     0.777164609759129710, 0.766170112735434672, 0.755139984181982249, 0.744071715500508102,
+     0.732962673584365398, 0.721810090308756203, 0.710611050909655040, 0.699362481103231959,
+     0.688061132773747808, 0.676703568029522584, 0.665286141392677943, 0.653804979847664947,
+     0.642255960424536365, 0.630634684933490286, 0.618936451394876075, 0.607156221620300030,
+     0.595288584291502887, 0.583327712748769489, 0.571267316532588332, 0.559100585511540626,
+     0.546820125163310577, 0.534417881237165604, 0.521885051592135052, 0.509211982443654398,
+     0.496388045518671162, 0.483401491653461857, 0.470239275082169006, 0.456886840931420235,
+     0.443327866073552401, 0.429543940225410703, 0.415514169600356364, 0.401214678896277765,
+     0.386617977941119573, 0.371692145329917234, 0.356399760258393816, 0.340696481064849122,
+     0.324529117016909452, 0.307832954674932158, 0.290527955491230394, 0.272513185478464703,
+     0.253658363385912022, 0.233790483059674731, 0.212671510630966620, 0.189958689622431842,
+     0.165127622564187282, 0.137304980940012589, 0.104838507565818778, 0.063852163815001570,
+     0.000000000000000000];
+pub static ZIG_EXP_F: [f64, .. 257] =
+    [0.000167066692307963, 0.000454134353841497, 0.000967269282327174, 0.001536299780301573,
+     0.002145967743718907, 0.002788798793574076, 0.003460264777836904, 0.004157295120833797,
+     0.004877655983542396, 0.005619642207205489, 0.006381905937319183, 0.007163353183634991,
+     0.007963077438017043, 0.008780314985808977, 0.009614413642502212, 0.010464810181029981,
+     0.011331013597834600, 0.012212592426255378, 0.013109164931254991, 0.014020391403181943,
+     0.014945968011691148, 0.015885621839973156, 0.016839106826039941, 0.017806200410911355,
+     0.018786700744696024, 0.019780424338009740, 0.020787204072578114, 0.021806887504283581,
+     0.022839335406385240, 0.023884420511558174, 0.024942026419731787, 0.026012046645134221,
+     0.027094383780955803, 0.028188948763978646, 0.029295660224637411, 0.030414443910466622,
+     0.031545232172893622, 0.032687963508959555, 0.033842582150874358, 0.035009037697397431,
+     0.036187284781931443, 0.037377282772959382, 0.038578995503074871, 0.039792391023374139,
+     0.041017441380414840, 0.042254122413316254, 0.043502413568888197, 0.044762297732943289,
+     0.046033761076175184, 0.047316792913181561, 0.048611385573379504, 0.049917534282706379,
+     0.051235237055126281, 0.052564494593071685, 0.053905310196046080, 0.055257689676697030,
+     0.056621641283742870, 0.057997175631200659, 0.059384305633420280, 0.060783046445479660,
+     0.062193415408541036, 0.063615431999807376, 0.065049117786753805, 0.066494496385339816,
+     0.067951593421936643, 0.069420436498728783, 0.070901055162371843, 0.072393480875708752,
+     0.073897746992364746, 0.075413888734058410, 0.076941943170480517, 0.078481949201606435,
+     0.080033947542319905, 0.081597980709237419, 0.083174093009632397, 0.084762330532368146,
+     0.086362741140756927, 0.087975374467270231, 0.089600281910032886, 0.091237516631040197,
+     0.092887133556043569, 0.094549189376055873, 0.096223742550432825, 0.097910853311492213,
+     0.099610583670637132, 0.101322997425953631, 0.103048160171257702, 0.104786139306570145,
+     0.106537004050001632, 0.108300825451033755, 0.110077676405185357, 0.111867631670056283,
+     0.113670767882744286, 0.115487163578633506, 0.117316899211555525, 0.119160057175327641,
+     0.121016721826674792, 0.122886979509545108, 0.124770918580830933, 0.126668629437510671,
+     0.128580204545228199, 0.130505738468330773, 0.132445327901387494, 0.134399071702213602,
+     0.136367070926428829, 0.138349428863580176, 0.140346251074862399, 0.142357645432472146,
+     0.144383722160634720, 0.146424593878344889, 0.148480375643866735, 0.150551185001039839,
+     0.152637142027442801, 0.154738369384468027, 0.156854992369365148, 0.158987138969314129,
+     0.161134939917591952, 0.163298528751901734, 0.165478041874935922, 0.167673618617250081,
+     0.169885401302527550, 0.172113535315319977, 0.174358169171353411, 0.176619454590494829,
+     0.178897546572478278, 0.181192603475496261, 0.183504787097767436, 0.185834262762197083,
+     0.188181199404254262, 0.190545769663195363, 0.192928149976771296, 0.195328520679563189,
+     0.197747066105098818, 0.200183974691911210, 0.202639439093708962, 0.205113656293837654,
+     0.207606827724221982, 0.210119159388988230, 0.212650861992978224, 0.215202151075378628,
+     0.217773247148700472, 0.220364375843359439, 0.222975768058120111, 0.225607660116683956,
+     0.228260293930716618, 0.230933917169627356, 0.233628783437433291, 0.236345152457059560,
+     0.239083290262449094, 0.241843469398877131, 0.244625969131892024, 0.247431075665327543,
+     0.250259082368862240, 0.253110290015629402, 0.255985007030415324, 0.258883549749016173,
+     0.261806242689362922, 0.264753418835062149, 0.267725419932044739, 0.270722596799059967,
+     0.273745309652802915, 0.276793928448517301, 0.279868833236972869, 0.282970414538780746,
+     0.286099073737076826, 0.289255223489677693, 0.292439288161892630, 0.295651704281261252,
+     0.298892921015581847, 0.302163400675693528, 0.305463619244590256, 0.308794066934560185,
+     0.312155248774179606, 0.315547685227128949, 0.318971912844957239, 0.322428484956089223,
+     0.325917972393556354, 0.329440964264136438, 0.332998068761809096, 0.336589914028677717,
+     0.340217149066780189, 0.343880444704502575, 0.347580494621637148, 0.351318016437483449,
+     0.355093752866787626, 0.358908472948750001, 0.362762973354817997, 0.366658079781514379,
+     0.370594648435146223, 0.374573567615902381, 0.378595759409581067, 0.382662181496010056,
+     0.386773829084137932, 0.390931736984797384, 0.395136981833290435, 0.399390684475231350,
+     0.403694012530530555, 0.408048183152032673, 0.412454465997161457, 0.416914186433003209,
+     0.421428728997616908, 0.425999541143034677, 0.430628137288459167, 0.435316103215636907,
+     0.440065100842354173, 0.444876873414548846, 0.449753251162755330, 0.454696157474615836,
+     0.459707615642138023, 0.464789756250426511, 0.469944825283960310, 0.475175193037377708,
+     0.480483363930454543, 0.485871987341885248, 0.491343869594032867, 0.496901987241549881,
+     0.502549501841348056, 0.508289776410643213, 0.514126393814748894, 0.520063177368233931,
+     0.526104213983620062, 0.532253880263043655, 0.538516872002862246, 0.544898237672440056,
+     0.551403416540641733, 0.558038282262587892, 0.564809192912400615, 0.571723048664826150,
+     0.578787358602845359, 0.586010318477268366, 0.593400901691733762, 0.600968966365232560,
+     0.608725382079622346, 0.616682180915207878, 0.624852738703666200, 0.633251994214366398,
+     0.641896716427266423, 0.650805833414571433, 0.660000841079000145, 0.669506316731925177,
+     0.679350572264765806, 0.689566496117078431, 0.700192655082788606, 0.711274760805076456,
+     0.722867659593572465, 0.735038092431424039, 0.747868621985195658, 0.761463388849896838,
+     0.775956852040116218, 0.791527636972496285, 0.808421651523009044, 0.826993296643051101,
+     0.847785500623990496, 0.871704332381204705, 0.900469929925747703, 0.938143680862176477,
+     1.000000000000000000];
diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs
new file mode 100644 (file)
index 0000000..b3226d6
--- /dev/null
@@ -0,0 +1,533 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The ISAAC random number generator.
+
+use {Rng, SeedableRng, OSRng};
+use std::iter::{range_step, Repeat};
+use std::vec::raw;
+use std::mem;
+
+static RAND_SIZE_LEN: u32 = 8;
+static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
+
+/// A random number generator that uses the ISAAC algorithm[1].
+///
+/// The ISAAC algorithm is generally accepted as suitable for
+/// cryptographic purposes, but this implementation has not be
+/// verified as such. Prefer a generator like `OSRng` that defers to
+/// the operating system for cases that need high security.
+///
+/// [1]: Bob Jenkins, [*ISAAC: A fast cryptographic random number
+/// generator*](http://www.burtleburtle.net/bob/rand/isaacafa.html)
+pub struct IsaacRng {
+    priv cnt: u32,
+    priv rsl: [u32, .. RAND_SIZE],
+    priv mem: [u32, .. RAND_SIZE],
+    priv a: u32,
+    priv b: u32,
+    priv c: u32
+}
+static EMPTY: IsaacRng = IsaacRng {
+    cnt: 0,
+    rsl: [0, .. RAND_SIZE],
+    mem: [0, .. RAND_SIZE],
+    a: 0, b: 0, c: 0
+};
+
+impl IsaacRng {
+    /// Create an ISAAC random number generator with a random seed.
+    pub fn new() -> IsaacRng {
+        let mut rng = EMPTY;
+
+        unsafe {
+            let ptr = rng.rsl.as_mut_ptr();
+
+            raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl), |slice| {
+                OSRng::new().fill_bytes(slice);
+            })
+        }
+
+        rng.init(true);
+        rng
+    }
+
+    /// Create an ISAAC random number generator using the default
+    /// fixed seed.
+    pub fn new_unseeded() -> IsaacRng {
+        let mut rng = EMPTY;
+        rng.init(false);
+        rng
+    }
+
+    /// Initialises `self`. If `use_rsl` is true, then use the current value
+    /// of `rsl` as a seed, otherwise construct one algorithmically (not
+    /// randomly).
+    fn init(&mut self, use_rsl: bool) {
+        let mut a = 0x9e3779b9;
+        let mut b = a;
+        let mut c = a;
+        let mut d = a;
+        let mut e = a;
+        let mut f = a;
+        let mut g = a;
+        let mut h = a;
+
+        macro_rules! mix(
+            () => {{
+                a^=b<<11; d+=a; b+=c;
+                b^=c>>2;  e+=b; c+=d;
+                c^=d<<8;  f+=c; d+=e;
+                d^=e>>16; g+=d; e+=f;
+                e^=f<<10; h+=e; f+=g;
+                f^=g>>4;  a+=f; g+=h;
+                g^=h<<8;  b+=g; h+=a;
+                h^=a>>9;  c+=h; a+=b;
+            }}
+        );
+
+        for _ in range(0, 4) { mix!(); }
+
+        if use_rsl {
+            macro_rules! memloop (
+                ($arr:expr) => {{
+                    for i in range_step(0u32, RAND_SIZE, 8) {
+                        a+=$arr[i  ]; b+=$arr[i+1];
+                        c+=$arr[i+2]; d+=$arr[i+3];
+                        e+=$arr[i+4]; f+=$arr[i+5];
+                        g+=$arr[i+6]; h+=$arr[i+7];
+                        mix!();
+                        self.mem[i  ]=a; self.mem[i+1]=b;
+                        self.mem[i+2]=c; self.mem[i+3]=d;
+                        self.mem[i+4]=e; self.mem[i+5]=f;
+                        self.mem[i+6]=g; self.mem[i+7]=h;
+                    }
+                }}
+            );
+
+            memloop!(self.rsl);
+            memloop!(self.mem);
+        } else {
+            for i in range_step(0u32, RAND_SIZE, 8) {
+                mix!();
+                self.mem[i  ]=a; self.mem[i+1]=b;
+                self.mem[i+2]=c; self.mem[i+3]=d;
+                self.mem[i+4]=e; self.mem[i+5]=f;
+                self.mem[i+6]=g; self.mem[i+7]=h;
+            }
+        }
+
+        self.isaac();
+    }
+
+    /// Refills the output buffer (`self.rsl`)
+    #[inline]
+    fn isaac(&mut self) {
+        self.c += 1;
+        // abbreviations
+        let mut a = self.a;
+        let mut b = self.b + self.c;
+
+        static MIDPOINT: uint = RAND_SIZE as uint / 2;
+
+        macro_rules! ind (($x:expr) => {
+            self.mem[($x >> 2) & (RAND_SIZE - 1)]
+        });
+        macro_rules! rngstep(
+            ($j:expr, $shift:expr) => {{
+                let base = $j;
+                let mix = if $shift < 0 {
+                    a >> -$shift as uint
+                } else {
+                    a << $shift as uint
+                };
+
+                let x = self.mem[base  + mr_offset];
+                a = (a ^ mix) + self.mem[base + m2_offset];
+                let y = ind!(x) + a + b;
+                self.mem[base + mr_offset] = y;
+
+                b = ind!(y >> RAND_SIZE_LEN) + x;
+                self.rsl[base + mr_offset] = b;
+            }}
+        );
+
+        let r = [(0, MIDPOINT), (MIDPOINT, 0)];
+        for &(mr_offset, m2_offset) in r.iter() {
+            for i in range_step(0u, MIDPOINT, 4) {
+                rngstep!(i + 0, 13);
+                rngstep!(i + 1, -6);
+                rngstep!(i + 2, 2);
+                rngstep!(i + 3, -16);
+            }
+        }
+
+        self.a = a;
+        self.b = b;
+        self.cnt = RAND_SIZE;
+    }
+}
+
+impl Rng for IsaacRng {
+    #[inline]
+    fn next_u32(&mut self) -> u32 {
+        if self.cnt == 0 {
+            // make some more numbers
+            self.isaac();
+        }
+        self.cnt -= 1;
+        self.rsl[self.cnt]
+    }
+}
+
+impl<'a> SeedableRng<&'a [u32]> for IsaacRng {
+    fn reseed(&mut self, seed: &'a [u32]) {
+        // make the seed into [seed[0], seed[1], ..., seed[seed.len()
+        // - 1], 0, 0, ...], to fill rng.rsl.
+        let seed_iter = seed.iter().map(|&x| x).chain(Repeat::new(0u32));
+
+        for (rsl_elem, seed_elem) in self.rsl.mut_iter().zip(seed_iter) {
+            *rsl_elem = seed_elem;
+        }
+        self.cnt = 0;
+        self.a = 0;
+        self.b = 0;
+        self.c = 0;
+
+        self.init(true);
+    }
+
+    /// Create an ISAAC random number generator with a seed. This can
+    /// be any length, although the maximum number of elements used is
+    /// 256 and any more will be silently ignored. A generator
+    /// constructed with a given seed will generate the same sequence
+    /// of values as all other generators constructed with that seed.
+    fn from_seed(seed: &'a [u32]) -> IsaacRng {
+        let mut rng = EMPTY;
+        rng.reseed(seed);
+        rng
+    }
+}
+
+
+static RAND_SIZE_64_LEN: uint = 8;
+static RAND_SIZE_64: uint = 1 << RAND_SIZE_64_LEN;
+
+/// A random number generator that uses ISAAC-64[1], the 64-bit
+/// variant of the ISAAC algorithm.
+///
+/// The ISAAC algorithm is generally accepted as suitable for
+/// cryptographic purposes, but this implementation has not be
+/// verified as such. Prefer a generator like `OSRng` that defers to
+/// the operating system for cases that need high security.
+///
+/// [1]: Bob Jenkins, [*ISAAC: A fast cryptographic random number
+/// generator*](http://www.burtleburtle.net/bob/rand/isaacafa.html)
+pub struct Isaac64Rng {
+    priv cnt: uint,
+    priv rsl: [u64, .. RAND_SIZE_64],
+    priv mem: [u64, .. RAND_SIZE_64],
+    priv a: u64,
+    priv b: u64,
+    priv c: u64,
+}
+
+static EMPTY_64: Isaac64Rng = Isaac64Rng {
+    cnt: 0,
+    rsl: [0, .. RAND_SIZE_64],
+    mem: [0, .. RAND_SIZE_64],
+    a: 0, b: 0, c: 0,
+};
+
+impl Isaac64Rng {
+    /// Create a 64-bit ISAAC random number generator with a random
+    /// seed.
+    pub fn new() -> Isaac64Rng {
+        let mut rng = EMPTY_64;
+
+        unsafe {
+            let ptr = rng.rsl.as_mut_ptr();
+
+            raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl), |slice| {
+                OSRng::new().fill_bytes(slice);
+            })
+        }
+
+        rng.init(true);
+        rng
+    }
+
+    /// Create a 64-bit ISAAC random number generator using the
+    /// default fixed seed.
+    pub fn new_unseeded() -> Isaac64Rng {
+        let mut rng = EMPTY_64;
+        rng.init(false);
+        rng
+    }
+
+    /// Initialises `self`. If `use_rsl` is true, then use the current value
+    /// of `rsl` as a seed, otherwise construct one algorithmically (not
+    /// randomly).
+    fn init(&mut self, use_rsl: bool) {
+        macro_rules! init (
+            ($var:ident) => (
+                let mut $var = 0x9e3779b97f4a7c13;
+            )
+        );
+        init!(a); init!(b); init!(c); init!(d);
+        init!(e); init!(f); init!(g); init!(h);
+
+        macro_rules! mix(
+            () => {{
+                a-=e; f^=h>>9;  h+=a;
+                b-=f; g^=a<<9;  a+=b;
+                c-=g; h^=b>>23; b+=c;
+                d-=h; a^=c<<15; c+=d;
+                e-=a; b^=d>>14; d+=e;
+                f-=b; c^=e<<20; e+=f;
+                g-=c; d^=f>>17; f+=g;
+                h-=d; e^=g<<14; g+=h;
+            }}
+        );
+
+        for _ in range(0, 4) { mix!(); }
+        if use_rsl {
+            macro_rules! memloop (
+                ($arr:expr) => {{
+                    for i in range(0, RAND_SIZE_64 / 8).map(|i| i * 8) {
+                        a+=$arr[i  ]; b+=$arr[i+1];
+                        c+=$arr[i+2]; d+=$arr[i+3];
+                        e+=$arr[i+4]; f+=$arr[i+5];
+                        g+=$arr[i+6]; h+=$arr[i+7];
+                        mix!();
+                        self.mem[i  ]=a; self.mem[i+1]=b;
+                        self.mem[i+2]=c; self.mem[i+3]=d;
+                        self.mem[i+4]=e; self.mem[i+5]=f;
+                        self.mem[i+6]=g; self.mem[i+7]=h;
+                    }
+                }}
+            );
+
+            memloop!(self.rsl);
+            memloop!(self.mem);
+        } else {
+            for i in range(0, RAND_SIZE_64 / 8).map(|i| i * 8) {
+                mix!();
+                self.mem[i  ]=a; self.mem[i+1]=b;
+                self.mem[i+2]=c; self.mem[i+3]=d;
+                self.mem[i+4]=e; self.mem[i+5]=f;
+                self.mem[i+6]=g; self.mem[i+7]=h;
+            }
+        }
+
+        self.isaac64();
+    }
+
+    /// Refills the output buffer (`self.rsl`)
+    fn isaac64(&mut self) {
+        self.c += 1;
+        // abbreviations
+        let mut a = self.a;
+        let mut b = self.b + self.c;
+        static MIDPOINT: uint =  RAND_SIZE_64 / 2;
+        static MP_VEC: [(uint, uint), .. 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
+        macro_rules! ind (
+            ($x:expr) => {
+                *self.mem.unsafe_ref(($x as uint >> 3) & (RAND_SIZE_64 - 1))
+            }
+        );
+        macro_rules! rngstep(
+            ($j:expr, $shift:expr) => {{
+                let base = base + $j;
+                let mix = a ^ (if $shift < 0 {
+                    a >> -$shift as uint
+                } else {
+                    a << $shift as uint
+                });
+                let mix = if $j == 0 {!mix} else {mix};
+
+                unsafe {
+                    let x = *self.mem.unsafe_ref(base + mr_offset);
+                    a = mix + *self.mem.unsafe_ref(base + m2_offset);
+                    let y = ind!(x) + a + b;
+                    self.mem.unsafe_set(base + mr_offset, y);
+
+                    b = ind!(y >> RAND_SIZE_64_LEN) + x;
+                    self.rsl.unsafe_set(base + mr_offset, b);
+                }
+            }}
+        );
+
+        for &(mr_offset, m2_offset) in MP_VEC.iter() {
+            for base in range(0, MIDPOINT / 4).map(|i| i * 4) {
+                rngstep!(0, 21);
+                rngstep!(1, -5);
+                rngstep!(2, 12);
+                rngstep!(3, -33);
+            }
+        }
+
+        self.a = a;
+        self.b = b;
+        self.cnt = RAND_SIZE_64;
+    }
+}
+
+impl Rng for Isaac64Rng {
+    // FIXME #7771: having next_u32 like this should be unnecessary
+    #[inline]
+    fn next_u32(&mut self) -> u32 {
+        self.next_u64() as u32
+    }
+
+    #[inline]
+    fn next_u64(&mut self) -> u64 {
+        if self.cnt == 0 {
+            // make some more numbers
+            self.isaac64();
+        }
+        self.cnt -= 1;
+        unsafe { *self.rsl.unsafe_ref(self.cnt) }
+    }
+}
+
+impl<'a> SeedableRng<&'a [u64]> for Isaac64Rng {
+    fn reseed(&mut self, seed: &'a [u64]) {
+        // make the seed into [seed[0], seed[1], ..., seed[seed.len()
+        // - 1], 0, 0, ...], to fill rng.rsl.
+        let seed_iter = seed.iter().map(|&x| x).chain(Repeat::new(0u64));
+
+        for (rsl_elem, seed_elem) in self.rsl.mut_iter().zip(seed_iter) {
+            *rsl_elem = seed_elem;
+        }
+        self.cnt = 0;
+        self.a = 0;
+        self.b = 0;
+        self.c = 0;
+
+        self.init(true);
+    }
+
+    /// Create an ISAAC random number generator with a seed. This can
+    /// be any length, although the maximum number of elements used is
+    /// 256 and any more will be silently ignored. A generator
+    /// constructed with a given seed will generate the same sequence
+    /// of values as all other generators constructed with that seed.
+    fn from_seed(seed: &'a [u64]) -> Isaac64Rng {
+        let mut rng = EMPTY_64;
+        rng.reseed(seed);
+        rng
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::{IsaacRng, Isaac64Rng};
+    use {Rng, SeedableRng, OSRng};
+    use std::vec;
+
+    #[test]
+    fn test_rng_32_rand_seeded() {
+        let s = OSRng::new().gen_vec::<u32>(256);
+        let mut ra: IsaacRng = SeedableRng::from_seed(s.as_slice());
+        let mut rb: IsaacRng = SeedableRng::from_seed(s.as_slice());
+        assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
+    }
+    #[test]
+    fn test_rng_64_rand_seeded() {
+        let s = OSRng::new().gen_vec::<u64>(256);
+        let mut ra: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
+        let mut rb: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
+        assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
+    }
+
+    #[test]
+    fn test_rng_32_seeded() {
+        let seed = &[1, 23, 456, 7890, 12345];
+        let mut ra: IsaacRng = SeedableRng::from_seed(seed);
+        let mut rb: IsaacRng = SeedableRng::from_seed(seed);
+        assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
+    }
+    #[test]
+    fn test_rng_64_seeded() {
+        let seed = &[1, 23, 456, 7890, 12345];
+        let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
+        let mut rb: Isaac64Rng = SeedableRng::from_seed(seed);
+        assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
+    }
+
+    #[test]
+    fn test_rng_32_reseed() {
+        let s = OSRng::new().gen_vec::<u32>(256);
+        let mut r: IsaacRng = SeedableRng::from_seed(s.as_slice());
+        let string1 = r.gen_ascii_str(100);
+
+        r.reseed(s);
+
+        let string2 = r.gen_ascii_str(100);
+        assert_eq!(string1, string2);
+    }
+    #[test]
+    fn test_rng_64_reseed() {
+        let s = OSRng::new().gen_vec::<u64>(256);
+        let mut r: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
+        let string1 = r.gen_ascii_str(100);
+
+        r.reseed(s);
+
+        let string2 = r.gen_ascii_str(100);
+        assert_eq!(string1, string2);
+    }
+
+    #[test]
+    fn test_rng_32_true_values() {
+        let seed = &[1, 23, 456, 7890, 12345];
+        let mut ra: IsaacRng = SeedableRng::from_seed(seed);
+        // Regression test that isaac is actually using the above vector
+        let v = vec::from_fn(10, |_| ra.next_u32());
+        assert_eq!(v,
+                   ~[2558573138, 873787463, 263499565, 2103644246, 3595684709,
+                     4203127393, 264982119, 2765226902, 2737944514, 3900253796]);
+
+        let seed = &[12345, 67890, 54321, 9876];
+        let mut rb: IsaacRng = SeedableRng::from_seed(seed);
+        // skip forward to the 10000th number
+        for _ in range(0, 10000) { rb.next_u32(); }
+
+        let v = vec::from_fn(10, |_| rb.next_u32());
+        assert_eq!(v,
+                   ~[3676831399, 3183332890, 2834741178, 3854698763, 2717568474,
+                     1576568959, 3507990155, 179069555, 141456972, 2478885421]);
+    }
+    #[test]
+    fn test_rng_64_true_values() {
+        let seed = &[1, 23, 456, 7890, 12345];
+        let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
+        // Regression test that isaac is actually using the above vector
+        let v = vec::from_fn(10, |_| ra.next_u64());
+        assert_eq!(v,
+                   ~[547121783600835980, 14377643087320773276, 17351601304698403469,
+                     1238879483818134882, 11952566807690396487, 13970131091560099343,
+                     4469761996653280935, 15552757044682284409, 6860251611068737823,
+                     13722198873481261842]);
+
+        let seed = &[12345, 67890, 54321, 9876];
+        let mut rb: Isaac64Rng = SeedableRng::from_seed(seed);
+        // skip forward to the 10000th number
+        for _ in range(0, 10000) { rb.next_u64(); }
+
+        let v = vec::from_fn(10, |_| rb.next_u64());
+        assert_eq!(v,
+                   ~[18143823860592706164, 8491801882678285927, 2699425367717515619,
+                     17196852593171130876, 2606123525235546165, 15790932315217671084,
+                     596345674630742204, 9947027391921273664, 11788097613744130851,
+                     10391409374914919106]);
+    }
+}
diff --git a/src/librand/lib.rs b/src/librand/lib.rs
new file mode 100644 (file)
index 0000000..4c5dd00
--- /dev/null
@@ -0,0 +1,907 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+Utilities for random number generation
+
+The key functions are `random()` and `Rng::gen()`. These are polymorphic
+and so can be used to generate any type that implements `Rand`. Type inference
+means that often a simple call to `rand::random()` or `rng.gen()` will
+suffice, but sometimes an annotation is required, e.g. `rand::random::<f64>()`.
+
+See the `distributions` submodule for sampling random numbers from
+distributions like normal and exponential.
+
+# Task-local RNG
+
+There is built-in support for a RNG associated with each task stored
+in task-local storage. This RNG can be accessed via `task_rng`, or
+used implicitly via `random`. This RNG is normally randomly seeded
+from an operating-system source of randomness, e.g. `/dev/urandom` on
+Unix systems, and will automatically reseed itself from this source
+after generating 32 KiB of random data.
+
+# Cryptographic security
+
+An application that requires random numbers for cryptographic purposes
+should prefer `OSRng`, which reads randomness from one of the source
+that the operating system provides (e.g. `/dev/urandom` on
+Unixes). The other random number generators provided by this module
+are either known to be insecure (`XorShiftRng`), or are not verified
+to be secure (`IsaacRng`, `Isaac64Rng` and `StdRng`).
+
+*Note*: on Linux, `/dev/random` is more secure than `/dev/urandom`,
+but it is a blocking RNG, and will wait until it has determined that
+it has collected enough entropy to fulfill a request for random
+data. It can be used with the `Rng` trait provided by this module by
+opening the file and passing it to `reader::ReaderRng`. Since it
+blocks, `/dev/random` should only be used to retrieve small amounts of
+randomness.
+
+# Examples
+
+```rust
+use rand::Rng;
+
+let mut rng = rand::rng();
+if rng.gen() { // bool
+    println!("int: {}, uint: {}", rng.gen::<int>(), rng.gen::<uint>())
+}
+```
+
+```rust
+let tuple_ptr = rand::random::<~(f64, char)>();
+println!("{:?}", tuple_ptr)
+```
+*/
+
+#[crate_id = "rand#0.10-pre"];
+#[license = "MIT/ASL2"];
+#[crate_type = "dylib"];
+#[crate_type = "rlib"];
+#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
+      html_favicon_url = "http://www.rust-lang.org/favicon.ico",
+      html_root_url = "http://static.rust-lang.org/doc/master")];
+
+#[feature(macro_rules, managed_boxes)];
+
+use std::cast;
+use std::kinds::marker;
+use std::local_data;
+use std::str;
+use std::vec;
+
+pub use isaac::{IsaacRng, Isaac64Rng};
+pub use os::OSRng;
+
+use distributions::{Range, IndependentSample};
+use distributions::range::SampleRange;
+
+pub mod distributions;
+pub mod isaac;
+pub mod os;
+pub mod reader;
+pub mod reseeding;
+mod rand_impls;
+
+/// A type that can be randomly generated using an `Rng`.
+pub trait Rand {
+    /// Generates a random instance of this type using the specified source of
+    /// randomness.
+    fn rand<R: Rng>(rng: &mut R) -> Self;
+}
+
+/// A random number generator.
+pub trait Rng {
+    /// Return the next random u32.
+    ///
+    /// This rarely needs to be called directly, prefer `r.gen()` to
+    /// `r.next_u32()`.
+    // FIXME #7771: Should be implemented in terms of next_u64
+    fn next_u32(&mut self) -> u32;
+
+    /// Return the next random u64.
+    ///
+    /// By default this is implemented in terms of `next_u32`. An
+    /// implementation of this trait must provide at least one of
+    /// these two methods. Similarly to `next_u32`, this rarely needs
+    /// to be called directly, prefer `r.gen()` to `r.next_u64()`.
+    fn next_u64(&mut self) -> u64 {
+        (self.next_u32() as u64 << 32) | (self.next_u32() as u64)
+    }
+
+    /// Fill `dest` with random data.
+    ///
+    /// This has a default implementation in terms of `next_u64` and
+    /// `next_u32`, but should be overridden by implementations that
+    /// offer a more efficient solution than just calling those
+    /// methods repeatedly.
+    ///
+    /// This method does *not* have a requirement to bear any fixed
+    /// relationship to the other methods, for example, it does *not*
+    /// have to result in the same output as progressively filling
+    /// `dest` with `self.gen::<u8>()`, and any such behaviour should
+    /// not be relied upon.
+    ///
+    /// This method should guarantee that `dest` is entirely filled
+    /// with new data, and may fail if this is impossible
+    /// (e.g. reading past the end of a file that is being used as the
+    /// source of randomness).
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use rand::{task_rng, Rng};
+    ///
+    /// let mut v = [0u8, .. 13579];
+    /// task_rng().fill_bytes(v);
+    /// println!("{:?}", v);
+    /// ```
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        // this could, in theory, be done by transmuting dest to a
+        // [u64], but this is (1) likely to be undefined behaviour for
+        // LLVM, (2) has to be very careful about alignment concerns,
+        // (3) adds more `unsafe` that needs to be checked, (4)
+        // probably doesn't give much performance gain if
+        // optimisations are on.
+        let mut count = 0;
+        let mut num = 0;
+        for byte in dest.mut_iter() {
+            if count == 0 {
+                // we could micro-optimise here by generating a u32 if
+                // we only need a few more bytes to fill the vector
+                // (i.e. at most 4).
+                num = self.next_u64();
+                count = 8;
+            }
+
+            *byte = (num & 0xff) as u8;
+            num >>= 8;
+            count -= 1;
+        }
+    }
+
+    /// Return a random value of a `Rand` type.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use rand::{task_rng, Rng};
+    ///
+    /// let mut rng = task_rng();
+    /// let x: uint = rng.gen();
+    /// println!("{}", x);
+    /// println!("{:?}", rng.gen::<(f64, bool)>());
+    /// ```
+    #[inline(always)]
+    fn gen<T: Rand>(&mut self) -> T {
+        Rand::rand(self)
+    }
+
+    /// Return a random vector of the specified length.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use rand::{task_rng, Rng};
+    ///
+    /// let mut rng = task_rng();
+    /// let x: ~[uint] = rng.gen_vec(10);
+    /// println!("{:?}", x);
+    /// println!("{:?}", rng.gen_vec::<(f64, bool)>(5));
+    /// ```
+    fn gen_vec<T: Rand>(&mut self, len: uint) -> ~[T] {
+        vec::from_fn(len, |_| self.gen())
+    }
+
+    /// Generate a random value in the range [`low`, `high`). Fails if
+    /// `low >= high`.
+    ///
+    /// This is a convenience wrapper around
+    /// `distributions::Range`. If this function will be called
+    /// repeatedly with the same arguments, one should use `Range`, as
+    /// that will amortize the computations that allow for perfect
+    /// uniformity, as they only happen on initialization.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use rand::{task_rng, Rng};
+    ///
+    /// let mut rng = task_rng();
+    /// let n: uint = rng.gen_range(0u, 10);
+    /// println!("{}", n);
+    /// let m: f64 = rng.gen_range(-40.0, 1.3e5);
+    /// println!("{}", m);
+    /// ```
+    fn gen_range<T: Ord + SampleRange>(&mut self, low: T, high: T) -> T {
+        assert!(low < high, "Rng.gen_range called with low >= high");
+        Range::new(low, high).ind_sample(self)
+    }
+
+    /// Return a bool with a 1 in n chance of true
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use rand::{task_rng, Rng};
+    ///
+    /// let mut rng = task_rng();
+    /// println!("{:b}", rng.gen_weighted_bool(3));
+    /// ```
+    fn gen_weighted_bool(&mut self, n: uint) -> bool {
+        n == 0 || self.gen_range(0, n) == 0
+    }
+
+    /// Return a random string of the specified length composed of
+    /// A-Z,a-z,0-9.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use rand::{task_rng, Rng};
+    ///
+    /// println!("{}", task_rng().gen_ascii_str(10));
+    /// ```
+    fn gen_ascii_str(&mut self, len: uint) -> ~str {
+        static GEN_ASCII_STR_CHARSET: &'static [u8] = bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+                                                             abcdefghijklmnopqrstuvwxyz\
+                                                             0123456789");
+        let mut s = str::with_capacity(len);
+        for _ in range(0, len) {
+            s.push_char(self.choose(GEN_ASCII_STR_CHARSET) as char)
+        }
+        s
+    }
+
+    /// Choose an item randomly, failing if `values` is empty.
+    fn choose<T: Clone>(&mut self, values: &[T]) -> T {
+        self.choose_option(values).expect("Rng.choose: `values` is empty").clone()
+    }
+
+    /// Choose `Some(&item)` randomly, returning `None` if values is
+    /// empty.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use rand::{task_rng, Rng};
+    ///
+    /// let choices = [1, 2, 4, 8, 16, 32];
+    /// let mut rng = task_rng();
+    /// println!("{:?}", rng.choose_option(choices));
+    /// println!("{:?}", rng.choose_option(choices.slice_to(0)));
+    /// ```
+    fn choose_option<'a, T>(&mut self, values: &'a [T]) -> Option<&'a T> {
+        if values.is_empty() {
+            None
+        } else {
+            Some(&values[self.gen_range(0u, values.len())])
+        }
+    }
+
+    /// Shuffle a vec
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use rand::{task_rng, Rng};
+    ///
+    /// println!("{:?}", task_rng().shuffle(~[1,2,3]));
+    /// ```
+    fn shuffle<T>(&mut self, values: ~[T]) -> ~[T] {
+        let mut v = values;
+        self.shuffle_mut(v);
+        v
+    }
+
+    /// Shuffle a mutable vector in place.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use rand::{task_rng, Rng};
+    ///
+    /// let mut rng = task_rng();
+    /// let mut y = [1,2,3];
+    /// rng.shuffle_mut(y);
+    /// println!("{:?}", y);
+    /// rng.shuffle_mut(y);
+    /// println!("{:?}", y);
+    /// ```
+    fn shuffle_mut<T>(&mut self, values: &mut [T]) {
+        let mut i = values.len();
+        while i >= 2u {
+            // invariant: elements with index >= i have been locked in place.
+            i -= 1u;
+            // lock element i in place.
+            values.swap(i, self.gen_range(0u, i + 1u));
+        }
+    }
+
+    /// Randomly sample up to `n` elements from an iterator.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use rand::{task_rng, Rng};
+    ///
+    /// let mut rng = task_rng();
+    /// let sample = rng.sample(range(1, 100), 5);
+    /// println!("{:?}", sample);
+    /// ```
+    fn sample<A, T: Iterator<A>>(&mut self, iter: T, n: uint) -> ~[A] {
+        let mut reservoir : ~[A] = vec::with_capacity(n);
+        for (i, elem) in iter.enumerate() {
+            if i < n {
+                reservoir.push(elem);
+                continue
+            }
+
+            let k = self.gen_range(0, i + 1);
+            if k < reservoir.len() {
+                reservoir[k] = elem
+            }
+        }
+        reservoir
+    }
+}
+
+/// A random number generator that can be explicitly seeded to produce
+/// the same stream of randomness multiple times.
+pub trait SeedableRng<Seed>: Rng {
+    /// Reseed an RNG with the given seed.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use rand::{Rng, SeedableRng, StdRng};
+    ///
+    /// let mut rng: StdRng = SeedableRng::from_seed(&[1, 2, 3, 4]);
+    /// println!("{}", rng.gen::<f64>());
+    /// rng.reseed([5, 6, 7, 8]);
+    /// println!("{}", rng.gen::<f64>());
+    /// ```
+    fn reseed(&mut self, Seed);
+
+    /// Create a new RNG with the given seed.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use rand::{Rng, SeedableRng, StdRng};
+    ///
+    /// let mut rng: StdRng = SeedableRng::from_seed(&[1, 2, 3, 4]);
+    /// println!("{}", rng.gen::<f64>());
+    /// ```
+    fn from_seed(seed: Seed) -> Self;
+}
+
+/// Create a random number generator with a default algorithm and seed.
+///
+/// It returns the strongest `Rng` algorithm currently implemented in
+/// pure Rust. If you require a specifically seeded `Rng` for
+/// consistency over time you should pick one algorithm and create the
+/// `Rng` yourself.
+///
+/// This is a very expensive operation as it has to read randomness
+/// from the operating system and use this in an expensive seeding
+/// operation. If one does not require high performance generation of
+/// random numbers, `task_rng` and/or `random` may be more
+/// appropriate.
+pub fn rng() -> StdRng {
+    StdRng::new()
+}
+
+/// The standard RNG. This is designed to be efficient on the current
+/// platform.
+#[cfg(not(target_word_size="64"))]
+pub struct StdRng { priv rng: IsaacRng }
+
+/// The standard RNG. This is designed to be efficient on the current
+/// platform.
+#[cfg(target_word_size="64")]
+pub struct StdRng { priv rng: Isaac64Rng }
+
+impl StdRng {
+    /// Create a randomly seeded instance of `StdRng`. This reads
+    /// randomness from the OS to seed the PRNG.
+    #[cfg(not(target_word_size="64"))]
+    pub fn new() -> StdRng {
+        StdRng { rng: IsaacRng::new() }
+    }
+    /// Create a randomly seeded instance of `StdRng`. This reads
+    /// randomness from the OS to seed the PRNG.
+    #[cfg(target_word_size="64")]
+    pub fn new() -> StdRng {
+        StdRng { rng: Isaac64Rng::new() }
+    }
+}
+
+impl Rng for StdRng {
+    #[inline]
+    fn next_u32(&mut self) -> u32 {
+        self.rng.next_u32()
+    }
+
+    #[inline]
+    fn next_u64(&mut self) -> u64 {
+        self.rng.next_u64()
+    }
+}
+
+impl<'a> SeedableRng<&'a [uint]> for StdRng {
+    fn reseed(&mut self, seed: &'a [uint]) {
+        // the internal RNG can just be seeded from the above
+        // randomness.
+        self.rng.reseed(unsafe {cast::transmute(seed)})
+    }
+
+    fn from_seed(seed: &'a [uint]) -> StdRng {
+        StdRng { rng: SeedableRng::from_seed(unsafe {cast::transmute(seed)}) }
+    }
+}
+
+/// Create a weak random number generator with a default algorithm and seed.
+///
+/// It returns the fastest `Rng` algorithm currently available in Rust without
+/// consideration for cryptography or security. If you require a specifically
+/// seeded `Rng` for consistency over time you should pick one algorithm and
+/// create the `Rng` yourself.
+///
+/// This will read randomness from the operating system to seed the
+/// generator.
+pub fn weak_rng() -> XorShiftRng {
+    XorShiftRng::new()
+}
+
+/// An Xorshift[1] random number
+/// generator.
+///
+/// The Xorshift algorithm is not suitable for cryptographic purposes
+/// but is very fast. If you do not know for sure that it fits your
+/// requirements, use a more secure one such as `IsaacRng` or `OSRng`.
+///
+/// [1]: Marsaglia, George (July 2003). ["Xorshift
+/// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
+/// Statistical Software*. Vol. 8 (Issue 14).
+pub struct XorShiftRng {
+    priv x: u32,
+    priv y: u32,
+    priv z: u32,
+    priv w: u32,
+}
+
+impl Rng for XorShiftRng {
+    #[inline]
+    fn next_u32(&mut self) -> u32 {
+        let x = self.x;
+        let t = x ^ (x << 11);
+        self.x = self.y;
+        self.y = self.z;
+        self.z = self.w;
+        let w = self.w;
+        self.w = w ^ (w >> 19) ^ (t ^ (t >> 8));
+        self.w
+    }
+}
+
+impl SeedableRng<[u32, .. 4]> for XorShiftRng {
+    /// Reseed an XorShiftRng. This will fail if `seed` is entirely 0.
+    fn reseed(&mut self, seed: [u32, .. 4]) {
+        assert!(!seed.iter().all(|&x| x == 0),
+                "XorShiftRng.reseed called with an all zero seed.");
+
+        self.x = seed[0];
+        self.y = seed[1];
+        self.z = seed[2];
+        self.w = seed[3];
+    }
+
+    /// Create a new XorShiftRng. This will fail if `seed` is entirely 0.
+    fn from_seed(seed: [u32, .. 4]) -> XorShiftRng {
+        assert!(!seed.iter().all(|&x| x == 0),
+                "XorShiftRng::from_seed called with an all zero seed.");
+
+        XorShiftRng {
+            x: seed[0],
+            y: seed[1],
+            z: seed[2],
+            w: seed[3]
+        }
+    }
+}
+
+impl XorShiftRng {
+    /// Create an xor shift random number generator with a random seed.
+    pub fn new() -> XorShiftRng {
+        let mut s = [0u8, ..16];
+        loop {
+            let mut r = OSRng::new();
+            r.fill_bytes(s);
+
+            if !s.iter().all(|x| *x == 0) {
+                break;
+            }
+        }
+        let s: [u32, ..4] = unsafe { cast::transmute(s) };
+        SeedableRng::from_seed(s)
+    }
+}
+
+/// Controls how the task-local RNG is reseeded.
+struct TaskRngReseeder;
+
+impl reseeding::Reseeder<StdRng> for TaskRngReseeder {
+    fn reseed(&mut self, rng: &mut StdRng) {
+        *rng = StdRng::new();
+    }
+}
+static TASK_RNG_RESEED_THRESHOLD: uint = 32_768;
+type TaskRngInner = reseeding::ReseedingRng<StdRng, TaskRngReseeder>;
+/// The task-local RNG.
+pub struct TaskRng {
+    // This points into TLS (specifically, it points to the endpoint
+    // of a ~ stored in TLS, to make it robust against TLS moving
+    // things internally) and so this struct cannot be legally
+    // transferred between tasks *and* it's unsafe to deallocate the
+    // RNG other than when a task is finished.
+    //
+    // The use of unsafe code here is OK if the invariants above are
+    // satisfied; and it allows us to avoid (unnecessarily) using a
+    // GC'd or RC'd pointer.
+    priv rng: *mut TaskRngInner,
+    priv marker: marker::NoSend,
+}
+
+// used to make space in TLS for a random number generator
+local_data_key!(TASK_RNG_KEY: ~TaskRngInner)
+
+/// Retrieve the lazily-initialized task-local random number
+/// generator, seeded by the system. Intended to be used in method
+/// chaining style, e.g. `task_rng().gen::<int>()`.
+///
+/// The RNG provided will reseed itself from the operating system
+/// after generating a certain amount of randomness.
+///
+/// The internal RNG used is platform and architecture dependent, even
+/// if the operating system random number generator is rigged to give
+/// the same sequence always. If absolute consistency is required,
+/// explicitly select an RNG, e.g. `IsaacRng` or `Isaac64Rng`.
+pub fn task_rng() -> TaskRng {
+    local_data::get_mut(TASK_RNG_KEY, |rng| match rng {
+        None => {
+            let mut rng = ~reseeding::ReseedingRng::new(StdRng::new(),
+                                                        TASK_RNG_RESEED_THRESHOLD,
+                                                        TaskRngReseeder);
+            let ptr = &mut *rng as *mut TaskRngInner;
+
+            local_data::set(TASK_RNG_KEY, rng);
+
+            TaskRng { rng: ptr, marker: marker::NoSend }
+        }
+        Some(rng) => TaskRng { rng: &mut **rng, marker: marker::NoSend }
+    })
+}
+
+impl Rng for TaskRng {
+    fn next_u32(&mut self) -> u32 {
+        unsafe { (*self.rng).next_u32() }
+    }
+
+    fn next_u64(&mut self) -> u64 {
+        unsafe { (*self.rng).next_u64() }
+    }
+
+    #[inline]
+    fn fill_bytes(&mut self, bytes: &mut [u8]) {
+        unsafe { (*self.rng).fill_bytes(bytes) }
+    }
+}
+
+/// Generate a random value using the task-local random number
+/// generator.
+///
+/// # Example
+///
+/// ```rust
+/// use rand::random;
+///
+/// if random() {
+///     let x = random();
+///     println!("{}", 2u * x);
+/// } else {
+///     println!("{}", random::<f64>());
+/// }
+/// ```
+#[inline]
+pub fn random<T: Rand>() -> T {
+    task_rng().gen()
+}
+
+/// A wrapper for generating floating point numbers uniformly in the
+/// open interval `(0,1)` (not including either endpoint).
+///
+/// Use `Closed01` for the closed interval `[0,1]`, and the default
+/// `Rand` implementation for `f32` and `f64` for the half-open
+/// `[0,1)`.
+///
+/// # Example
+/// ```rust
+/// use rand::{random, Open01};
+///
+/// let Open01(val) = random::<Open01<f32>>();
+/// println!("f32 from (0,1): {}", val);
+/// ```
+pub struct Open01<F>(F);
+
+/// A wrapper for generating floating point numbers uniformly in the
+/// closed interval `[0,1]` (including both endpoints).
+///
+/// Use `Open01` for the closed interval `(0,1)`, and the default
+/// `Rand` implementation of `f32` and `f64` for the half-open
+/// `[0,1)`.
+///
+/// # Example
+/// ```rust
+/// use rand::{random, Closed01};
+///
+/// let Closed01(val) = random::<Closed01<f32>>();
+/// println!("f32 from [0,1]: {}", val);
+/// ```
+pub struct Closed01<F>(F);
+
+#[cfg(test)]
+mod test {
+    use std::vec;
+    use super::{Rng, task_rng, random, OSRng, SeedableRng, StdRng};
+
+    struct ConstRng { i: u64 }
+    impl Rng for ConstRng {
+        fn next_u32(&mut self) -> u32 { self.i as u32 }
+        fn next_u64(&mut self) -> u64 { self.i }
+
+        // no fill_bytes on purpose
+    }
+
+    #[test]
+    fn test_fill_bytes_default() {
+        let mut r = ConstRng { i: 0x11_22_33_44_55_66_77_88 };
+
+        // check every remainder mod 8, both in small and big vectors.
+        let lengths = [0, 1, 2, 3, 4, 5, 6, 7,
+                       80, 81, 82, 83, 84, 85, 86, 87];
+        for &n in lengths.iter() {
+            let mut v = vec::from_elem(n, 0u8);
+            r.fill_bytes(v);
+
+            // use this to get nicer error messages.
+            for (i, &byte) in v.iter().enumerate() {
+                if byte == 0 {
+                    fail!("byte {} of {} is zero", i, n)
+                }
+            }
+        }
+    }
+
+    #[test]
+    fn test_gen_range() {
+        let mut r = task_rng();
+        for _ in range(0, 1000) {
+            let a = r.gen_range(-3i, 42);
+            assert!(a >= -3 && a < 42);
+            assert_eq!(r.gen_range(0, 1), 0);
+            assert_eq!(r.gen_range(-12, -11), -12);
+        }
+
+        for _ in range(0, 1000) {
+            let a = r.gen_range(10, 42);
+            assert!(a >= 10 && a < 42);
+            assert_eq!(r.gen_range(0, 1), 0);
+            assert_eq!(r.gen_range(3_000_000u, 3_000_001), 3_000_000);
+        }
+
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_gen_range_fail_int() {
+        let mut r = task_rng();
+        r.gen_range(5i, -2);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_gen_range_fail_uint() {
+        let mut r = task_rng();
+        r.gen_range(5u, 2u);
+    }
+
+    #[test]
+    fn test_gen_f64() {
+        let mut r = task_rng();
+        let a = r.gen::<f64>();
+        let b = r.gen::<f64>();
+        debug!("{:?}", (a, b));
+    }
+
+    #[test]
+    fn test_gen_weighted_bool() {
+        let mut r = task_rng();
+        assert_eq!(r.gen_weighted_bool(0u), true);
+        assert_eq!(r.gen_weighted_bool(1u), true);
+    }
+
+    #[test]
+    fn test_gen_ascii_str() {
+        let mut r = task_rng();
+        debug!("{}", r.gen_ascii_str(10u));
+        debug!("{}", r.gen_ascii_str(10u));
+        debug!("{}", r.gen_ascii_str(10u));
+        assert_eq!(r.gen_ascii_str(0u).len(), 0u);
+        assert_eq!(r.gen_ascii_str(10u).len(), 10u);
+        assert_eq!(r.gen_ascii_str(16u).len(), 16u);
+    }
+
+    #[test]
+    fn test_gen_vec() {
+        let mut r = task_rng();
+        assert_eq!(r.gen_vec::<u8>(0u).len(), 0u);
+        assert_eq!(r.gen_vec::<u8>(10u).len(), 10u);
+        assert_eq!(r.gen_vec::<f64>(16u).len(), 16u);
+    }
+
+    #[test]
+    fn test_choose() {
+        let mut r = task_rng();
+        assert_eq!(r.choose([1, 1, 1]), 1);
+    }
+
+    #[test]
+    fn test_choose_option() {
+        let mut r = task_rng();
+        let v: &[int] = &[];
+        assert!(r.choose_option(v).is_none());
+
+        let i = 1;
+        let v = [1,1,1];
+        assert_eq!(r.choose_option(v), Some(&i));
+    }
+
+    #[test]
+    fn test_shuffle() {
+        let mut r = task_rng();
+        let empty: ~[int] = ~[];
+        assert_eq!(r.shuffle(~[]), empty);
+        assert_eq!(r.shuffle(~[1, 1, 1]), ~[1, 1, 1]);
+    }
+
+    #[test]
+    fn test_task_rng() {
+        let mut r = task_rng();
+        r.gen::<int>();
+        assert_eq!(r.shuffle(~[1, 1, 1]), ~[1, 1, 1]);
+        assert_eq!(r.gen_range(0u, 1u), 0u);
+    }
+
+    #[test]
+    fn test_random() {
+        // not sure how to test this aside from just getting some values
+        let _n : uint = random();
+        let _f : f32 = random();
+        let _o : Option<Option<i8>> = random();
+        let _many : ((),
+                     (~uint, @int, ~Option<~(@u32, ~(@bool,))>),
+                     (u8, i8, u16, i16, u32, i32, u64, i64),
+                     (f32, (f64, (f64,)))) = random();
+    }
+
+    #[test]
+    fn test_sample() {
+        let min_val = 1;
+        let max_val = 100;
+
+        let mut r = task_rng();
+        let vals = range(min_val, max_val).to_owned_vec();
+        let small_sample = r.sample(vals.iter(), 5);
+        let large_sample = r.sample(vals.iter(), vals.len() + 5);
+
+        assert_eq!(small_sample.len(), 5);
+        assert_eq!(large_sample.len(), vals.len());
+
+        assert!(small_sample.iter().all(|e| {
+            **e >= min_val && **e <= max_val
+        }));
+    }
+
+    #[test]
+    fn test_std_rng_seeded() {
+        let s = OSRng::new().gen_vec::<uint>(256);
+        let mut ra: StdRng = SeedableRng::from_seed(s.as_slice());
+        let mut rb: StdRng = SeedableRng::from_seed(s.as_slice());
+        assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
+    }
+
+    #[test]
+    fn test_std_rng_reseed() {
+        let s = OSRng::new().gen_vec::<uint>(256);
+        let mut r: StdRng = SeedableRng::from_seed(s.as_slice());
+        let string1 = r.gen_ascii_str(100);
+
+        r.reseed(s);
+
+        let string2 = r.gen_ascii_str(100);
+        assert_eq!(string1, string2);
+    }
+}
+
+#[cfg(test)]
+static RAND_BENCH_N: u64 = 100;
+
+#[cfg(test)]
+mod bench {
+    extern crate test;
+    use self::test::BenchHarness;
+    use {XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng, RAND_BENCH_N};
+    use std::mem::size_of;
+
+    #[bench]
+    fn rand_xorshift(bh: &mut BenchHarness) {
+        let mut rng = XorShiftRng::new();
+        bh.iter(|| {
+            for _ in range(0, RAND_BENCH_N) {
+                rng.gen::<uint>();
+            }
+        });
+        bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
+    }
+
+    #[bench]
+    fn rand_isaac(bh: &mut BenchHarness) {
+        let mut rng = IsaacRng::new();
+        bh.iter(|| {
+            for _ in range(0, RAND_BENCH_N) {
+                rng.gen::<uint>();
+            }
+        });
+        bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
+    }
+
+    #[bench]
+    fn rand_isaac64(bh: &mut BenchHarness) {
+        let mut rng = Isaac64Rng::new();
+        bh.iter(|| {
+            for _ in range(0, RAND_BENCH_N) {
+                rng.gen::<uint>();
+            }
+        });
+        bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
+    }
+
+    #[bench]
+    fn rand_std(bh: &mut BenchHarness) {
+        let mut rng = StdRng::new();
+        bh.iter(|| {
+            for _ in range(0, RAND_BENCH_N) {
+                rng.gen::<uint>();
+            }
+        });
+        bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
+    }
+
+    #[bench]
+    fn rand_shuffle_100(bh: &mut BenchHarness) {
+        let mut rng = XorShiftRng::new();
+        let x : &mut[uint] = [1,..100];
+        bh.iter(|| {
+            rng.shuffle_mut(x);
+        })
+    }
+}
diff --git a/src/librand/os.rs b/src/librand/os.rs
new file mode 100644 (file)
index 0000000..826c164
--- /dev/null
@@ -0,0 +1,182 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Interfaces to the operating system provided random number
+//! generators.
+
+use Rng;
+
+#[cfg(unix)]
+use reader::ReaderRng;
+#[cfg(unix)]
+use std::io::File;
+
+#[cfg(windows)]
+use std::cast;
+#[cfg(windows)]
+use std::libc::{c_long, DWORD, BYTE};
+#[cfg(windows)]
+type HCRYPTPROV = c_long;
+// the extern functions imported from the runtime on Windows are
+// implemented so that they either succeed or abort(), so we can just
+// assume they work when we call them.
+
+/// A random number generator that retrieves randomness straight from
+/// the operating system. Platform sources:
+///
+/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
+///   `/dev/urandom`.
+/// - Windows: calls `CryptGenRandom`, using the default cryptographic
+///   service provider with the `PROV_RSA_FULL` type.
+///
+/// This does not block.
+#[cfg(unix)]
+pub struct OSRng {
+    priv inner: ReaderRng<File>
+}
+/// A random number generator that retrieves randomness straight from
+/// the operating system. Platform sources:
+///
+/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
+///   `/dev/urandom`.
+/// - Windows: calls `CryptGenRandom`, using the default cryptographic
+///   service provider with the `PROV_RSA_FULL` type.
+///
+/// This does not block.
+#[cfg(windows)]
+pub struct OSRng {
+    priv hcryptprov: HCRYPTPROV
+}
+
+impl OSRng {
+    /// Create a new `OSRng`.
+    #[cfg(unix)]
+    pub fn new() -> OSRng {
+        let reader = File::open(&Path::new("/dev/urandom"));
+        let reader = reader.ok().expect("Error opening /dev/urandom");
+        let reader_rng = ReaderRng::new(reader);
+
+        OSRng { inner: reader_rng }
+    }
+
+    /// Create a new `OSRng`.
+    #[cfg(windows)]
+    pub fn new() -> OSRng {
+        extern { fn rust_win32_rand_acquire(phProv: *mut HCRYPTPROV); }
+
+        let mut hcp = 0;
+        unsafe {rust_win32_rand_acquire(&mut hcp)};
+
+        OSRng { hcryptprov: hcp }
+    }
+}
+
+#[cfg(unix)]
+impl Rng for OSRng {
+    fn next_u32(&mut self) -> u32 {
+        self.inner.next_u32()
+    }
+    fn next_u64(&mut self) -> u64 {
+        self.inner.next_u64()
+    }
+    fn fill_bytes(&mut self, v: &mut [u8]) {
+        self.inner.fill_bytes(v)
+    }
+}
+
+#[cfg(windows)]
+impl Rng for OSRng {
+    fn next_u32(&mut self) -> u32 {
+        let mut v = [0u8, .. 4];
+        self.fill_bytes(v);
+        unsafe { cast::transmute(v) }
+    }
+    fn next_u64(&mut self) -> u64 {
+        let mut v = [0u8, .. 8];
+        self.fill_bytes(v);
+        unsafe { cast::transmute(v) }
+    }
+    fn fill_bytes(&mut self, v: &mut [u8]) {
+        extern {
+            fn rust_win32_rand_gen(hProv: HCRYPTPROV, dwLen: DWORD,
+                                   pbBuffer: *mut BYTE);
+        }
+
+        unsafe {rust_win32_rand_gen(self.hcryptprov, v.len() as DWORD, v.as_mut_ptr())}
+    }
+}
+
+impl Drop for OSRng {
+    #[cfg(unix)]
+    fn drop(&mut self) {
+        // ensure that OSRng is not implicitly copyable on all
+        // platforms, for consistency.
+    }
+
+    #[cfg(windows)]
+    fn drop(&mut self) {
+        extern { fn rust_win32_rand_release(hProv: HCRYPTPROV); }
+
+        unsafe {rust_win32_rand_release(self.hcryptprov)}
+    }
+}
+
+
+#[cfg(test)]
+mod test {
+    use super::OSRng;
+    use Rng;
+    use std::task;
+
+    #[test]
+    fn test_os_rng() {
+        let mut r = OSRng::new();
+
+        r.next_u32();
+        r.next_u64();
+
+        let mut v = [0u8, .. 1000];
+        r.fill_bytes(v);
+    }
+
+    #[test]
+    fn test_os_rng_tasks() {
+
+        let mut chans = ~[];
+        for _ in range(0, 20) {
+            let (p, c) = Chan::new();
+            chans.push(c);
+            task::spawn(proc() {
+                // wait until all the tasks are ready to go.
+                p.recv();
+
+                // deschedule to attempt to interleave things as much
+                // as possible (XXX: is this a good test?)
+                let mut r = OSRng::new();
+                task::deschedule();
+                let mut v = [0u8, .. 1000];
+
+                for _ in range(0, 100) {
+                    r.next_u32();
+                    task::deschedule();
+                    r.next_u64();
+                    task::deschedule();
+                    r.fill_bytes(v);
+                    task::deschedule();
+                }
+            })
+        }
+
+        // start all the tasks
+        for c in chans.iter() {
+            c.send(())
+        }
+    }
+}
diff --git a/src/librand/rand_impls.rs b/src/librand/rand_impls.rs
new file mode 100644 (file)
index 0000000..fbd1605
--- /dev/null
@@ -0,0 +1,277 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The implementations of `Rand` for the built-in types.
+
+use std::char;
+use std::int;
+use std::uint;
+
+use {Rand,Rng};
+
+impl Rand for int {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> int {
+        if int::BITS == 32 {
+            rng.gen::<i32>() as int
+        } else {
+            rng.gen::<i64>() as int
+        }
+    }
+}
+
+impl Rand for i8 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> i8 {
+        rng.next_u32() as i8
+    }
+}
+
+impl Rand for i16 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> i16 {
+        rng.next_u32() as i16
+    }
+}
+
+impl Rand for i32 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> i32 {
+        rng.next_u32() as i32
+    }
+}
+
+impl Rand for i64 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> i64 {
+        rng.next_u64() as i64
+    }
+}
+
+impl Rand for uint {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> uint {
+        if uint::BITS == 32 {
+            rng.gen::<u32>() as uint
+        } else {
+            rng.gen::<u64>() as uint
+        }
+    }
+}
+
+impl Rand for u8 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> u8 {
+        rng.next_u32() as u8
+    }
+}
+
+impl Rand for u16 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> u16 {
+        rng.next_u32() as u16
+    }
+}
+
+impl Rand for u32 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> u32 {
+        rng.next_u32()
+    }
+}
+
+impl Rand for u64 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> u64 {
+        rng.next_u64()
+    }
+}
+
+macro_rules! float_impls {
+    ($mod_name:ident, $ty:ty, $mantissa_bits:expr, $method_name:ident, $ignored_bits:expr) => {
+        mod $mod_name {
+            use {Rand, Rng, Open01, Closed01};
+
+            static SCALE: $ty = (1u64 << $mantissa_bits) as $ty;
+
+            impl Rand for $ty {
+                /// Generate a floating point number in the half-open
+                /// interval `[0,1)`.
+                ///
+                /// See `Closed01` for the closed interval `[0,1]`,
+                /// and `Open01` for the open interval `(0,1)`.
+                #[inline]
+                fn rand<R: Rng>(rng: &mut R) -> $ty {
+                    // using any more than `mantissa_bits` bits will
+                    // cause (e.g.) 0xffff_ffff to correspond to 1
+                    // exactly, so we need to drop some (8 for f32, 11
+                    // for f64) to guarantee the open end.
+                    (rng.$method_name() >> $ignored_bits) as $ty / SCALE
+                }
+            }
+            impl Rand for Open01<$ty> {
+                #[inline]
+                fn rand<R: Rng>(rng: &mut R) -> Open01<$ty> {
+                    // add a small amount (specifically 2 bits below
+                    // the precision of f64/f32 at 1.0), so that small
+                    // numbers are larger than 0, but large numbers
+                    // aren't pushed to/above 1.
+                    Open01(((rng.$method_name() >> $ignored_bits) as $ty + 0.25) / SCALE)
+                }
+            }
+            impl Rand for Closed01<$ty> {
+                #[inline]
+                fn rand<R: Rng>(rng: &mut R) -> Closed01<$ty> {
+                    // divide by the maximum value of the numerator to
+                    // get a non-zero probability of getting exactly
+                    // 1.0.
+                    Closed01((rng.$method_name() >> $ignored_bits) as $ty / (SCALE - 1.0))
+                }
+            }
+        }
+    }
+}
+float_impls! { f64_rand_impls, f64, 53, next_u64, 11 }
+float_impls! { f32_rand_impls, f32, 24, next_u32, 8 }
+
+impl Rand for char {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> char {
+        // a char is 21 bits
+        static CHAR_MASK: u32 = 0x001f_ffff;
+        loop {
+            // Rejection sampling. About 0.2% of numbers with at most
+            // 21-bits are invalid codepoints (surrogates), so this
+            // will succeed first go almost every time.
+            match char::from_u32(rng.next_u32() & CHAR_MASK) {
+                Some(c) => return c,
+                None => {}
+            }
+        }
+    }
+}
+
+impl Rand for bool {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> bool {
+        rng.gen::<u8>() & 1 == 1
+    }
+}
+
+macro_rules! tuple_impl {
+    // use variables to indicate the arity of the tuple
+    ($($tyvar:ident),* ) => {
+        // the trailing commas are for the 1 tuple
+        impl<
+            $( $tyvar : Rand ),*
+            > Rand for ( $( $tyvar ),* , ) {
+
+            #[inline]
+            fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) {
+                (
+                    // use the $tyvar's to get the appropriate number of
+                    // repeats (they're not actually needed)
+                    $(
+                        _rng.gen::<$tyvar>()
+                    ),*
+                    ,
+                )
+            }
+        }
+    }
+}
+
+impl Rand for () {
+    #[inline]
+    fn rand<R: Rng>(_: &mut R) -> () { () }
+}
+tuple_impl!{A}
+tuple_impl!{A, B}
+tuple_impl!{A, B, C}
+tuple_impl!{A, B, C, D}
+tuple_impl!{A, B, C, D, E}
+tuple_impl!{A, B, C, D, E, F}
+tuple_impl!{A, B, C, D, E, F, G}
+tuple_impl!{A, B, C, D, E, F, G, H}
+tuple_impl!{A, B, C, D, E, F, G, H, I}
+tuple_impl!{A, B, C, D, E, F, G, H, I, J}
+
+impl<T:Rand> Rand for Option<T> {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> Option<T> {
+        if rng.gen() {
+            Some(rng.gen())
+        } else {
+            None
+        }
+    }
+}
+
+impl<T: Rand> Rand for ~T {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> ~T { ~rng.gen() }
+}
+
+impl<T: Rand + 'static> Rand for @T {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> @T { @rng.gen() }
+}
+
+#[cfg(test)]
+mod tests {
+    use {Rng, task_rng, Open01, Closed01};
+
+    struct ConstantRng(u64);
+    impl Rng for ConstantRng {
+        fn next_u32(&mut self) -> u32 {
+            let ConstantRng(v) = *self;
+            v as u32
+        }
+        fn next_u64(&mut self) -> u64 {
+            let ConstantRng(v) = *self;
+            v
+        }
+    }
+
+    #[test]
+    fn floating_point_edge_cases() {
+        // the test for exact equality is correct here.
+        assert!(ConstantRng(0xffff_ffff).gen::<f32>() != 1.0)
+        assert!(ConstantRng(0xffff_ffff_ffff_ffff).gen::<f64>() != 1.0)
+    }
+
+    #[test]
+    fn rand_open() {
+        // this is unlikely to catch an incorrect implementation that
+        // generates exactly 0 or 1, but it keeps it sane.
+        let mut rng = task_rng();
+        for _ in range(0, 1_000) {
+            // strict inequalities
+            let Open01(f) = rng.gen::<Open01<f64>>();
+            assert!(0.0 < f && f < 1.0);
+
+            let Open01(f) = rng.gen::<Open01<f32>>();
+            assert!(0.0 < f && f < 1.0);
+        }
+    }
+
+    #[test]
+    fn rand_closed() {
+        let mut rng = task_rng();
+        for _ in range(0, 1_000) {
+            // strict inequalities
+            let Closed01(f) = rng.gen::<Closed01<f64>>();
+            assert!(0.0 <= f && f <= 1.0);
+
+            let Closed01(f) = rng.gen::<Closed01<f32>>();
+            assert!(0.0 <= f && f <= 1.0);
+        }
+    }
+}
diff --git a/src/librand/reader.rs b/src/librand/reader.rs
new file mode 100644 (file)
index 0000000..744930e
--- /dev/null
@@ -0,0 +1,119 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A wrapper around any Reader to treat it as an RNG.
+
+use Rng;
+
+/// An RNG that reads random bytes straight from a `Reader`. This will
+/// work best with an infinite reader, but this is not required.
+///
+/// It will fail if it there is insufficient data to fulfill a request.
+///
+/// # Example
+///
+/// ```rust
+/// use rand::{reader, Rng};
+/// use std::io::MemReader;
+///
+/// let mut rng = reader::ReaderRng::new(MemReader::new(~[1,2,3,4,5,6,7,8]));
+/// println!("{:x}", rng.gen::<uint>());
+/// ```
+pub struct ReaderRng<R> {
+    priv reader: R
+}
+
+impl<R: Reader> ReaderRng<R> {
+    /// Create a new `ReaderRng` from a `Reader`.
+    pub fn new(r: R) -> ReaderRng<R> {
+        ReaderRng {
+            reader: r
+        }
+    }
+}
+
+impl<R: Reader> Rng for ReaderRng<R> {
+    fn next_u32(&mut self) -> u32 {
+        // This is designed for speed: reading a LE integer on a LE
+        // platform just involves blitting the bytes into the memory
+        // of the u32, similarly for BE on BE; avoiding byteswapping.
+        if cfg!(target_endian="little") {
+            self.reader.read_le_u32().unwrap()
+        } else {
+            self.reader.read_be_u32().unwrap()
+        }
+    }
+    fn next_u64(&mut self) -> u64 {
+        // see above for explanation.
+        if cfg!(target_endian="little") {
+            self.reader.read_le_u64().unwrap()
+        } else {
+            self.reader.read_be_u64().unwrap()
+        }
+    }
+    fn fill_bytes(&mut self, v: &mut [u8]) {
+        if v.len() == 0 { return }
+        match self.reader.read(v) {
+            Ok(n) if n == v.len() => return,
+            Ok(n) => fail!("ReaderRng.fill_bytes could not fill buffer: \
+                            read {} out of {} bytes.", n, v.len()),
+            Err(e) => fail!("ReaderRng.fill_bytes error: {}", e)
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::ReaderRng;
+    use std::io::MemReader;
+    use std::cast;
+    use Rng;
+
+    #[test]
+    fn test_reader_rng_u64() {
+        // transmute from the target to avoid endianness concerns.
+        let v = ~[1u64, 2u64, 3u64];
+        let bytes: ~[u8] = unsafe {cast::transmute(v)};
+        let mut rng = ReaderRng::new(MemReader::new(bytes));
+
+        assert_eq!(rng.next_u64(), 1);
+        assert_eq!(rng.next_u64(), 2);
+        assert_eq!(rng.next_u64(), 3);
+    }
+    #[test]
+    fn test_reader_rng_u32() {
+        // transmute from the target to avoid endianness concerns.
+        let v = ~[1u32, 2u32, 3u32];
+        let bytes: ~[u8] = unsafe {cast::transmute(v)};
+        let mut rng = ReaderRng::new(MemReader::new(bytes));
+
+        assert_eq!(rng.next_u32(), 1);
+        assert_eq!(rng.next_u32(), 2);
+        assert_eq!(rng.next_u32(), 3);
+    }
+    #[test]
+    fn test_reader_rng_fill_bytes() {
+        let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
+        let mut w = [0u8, .. 8];
+
+        let mut rng = ReaderRng::new(MemReader::new(v.to_owned()));
+        rng.fill_bytes(w);
+
+        assert!(v == w);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_reader_rng_insufficient_bytes() {
+        let mut rng = ReaderRng::new(MemReader::new(~[]));
+        let mut v = [0u8, .. 3];
+        rng.fill_bytes(v);
+    }
+}
diff --git a/src/librand/reseeding.rs b/src/librand/reseeding.rs
new file mode 100644 (file)
index 0000000..a64124e
--- /dev/null
@@ -0,0 +1,221 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A wrapper around another RNG that reseeds it after it
+//! generates a certain number of random bytes.
+
+use std::default::Default;
+use {Rng, SeedableRng};
+
+/// How many bytes of entropy the underling RNG is allowed to generate
+/// before it is reseeded.
+static DEFAULT_GENERATION_THRESHOLD: uint = 32 * 1024;
+
+/// A wrapper around any RNG which reseeds the underlying RNG after it
+/// has generated a certain number of random bytes.
+pub struct ReseedingRng<R, Rsdr> {
+    priv rng: R,
+    priv generation_threshold: uint,
+    priv bytes_generated: uint,
+    /// Controls the behaviour when reseeding the RNG.
+    reseeder: Rsdr
+}
+
+impl<R: Rng, Rsdr: Reseeder<R>> ReseedingRng<R, Rsdr> {
+    /// Create a new `ReseedingRng` with the given parameters.
+    ///
+    /// # Arguments
+    ///
+    /// * `rng`: the random number generator to use.
+    /// * `generation_threshold`: the number of bytes of entropy at which to reseed the RNG.
+    /// * `reseeder`: the reseeding object to use.
+    pub fn new(rng: R, generation_threshold: uint, reseeder: Rsdr) -> ReseedingRng<R,Rsdr> {
+        ReseedingRng {
+            rng: rng,
+            generation_threshold: generation_threshold,
+            bytes_generated: 0,
+            reseeder: reseeder
+        }
+    }
+
+    /// Reseed the internal RNG if the number of bytes that have been
+    /// generated exceed the threshold.
+    pub fn reseed_if_necessary(&mut self) {
+        if self.bytes_generated >= self.generation_threshold {
+            self.reseeder.reseed(&mut self.rng);
+            self.bytes_generated = 0;
+        }
+    }
+}
+
+
+impl<R: Rng, Rsdr: Reseeder<R>> Rng for ReseedingRng<R, Rsdr> {
+    fn next_u32(&mut self) -> u32 {
+        self.reseed_if_necessary();
+        self.bytes_generated += 4;
+        self.rng.next_u32()
+    }
+
+    fn next_u64(&mut self) -> u64 {
+        self.reseed_if_necessary();
+        self.bytes_generated += 8;
+        self.rng.next_u64()
+    }
+
+    fn fill_bytes(&mut self, dest: &mut [u8]) {
+        self.reseed_if_necessary();
+        self.bytes_generated += dest.len();
+        self.rng.fill_bytes(dest)
+    }
+}
+
+impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R>>
+     SeedableRng<(Rsdr, S)> for ReseedingRng<R, Rsdr> {
+    fn reseed(&mut self, (rsdr, seed): (Rsdr, S)) {
+        self.rng.reseed(seed);
+        self.reseeder = rsdr;
+        self.bytes_generated = 0;
+    }
+    /// Create a new `ReseedingRng` from the given reseeder and
+    /// seed. This uses a default value for `generation_threshold`.
+    fn from_seed((rsdr, seed): (Rsdr, S)) -> ReseedingRng<R, Rsdr> {
+        ReseedingRng {
+            rng: SeedableRng::from_seed(seed),
+            generation_threshold: DEFAULT_GENERATION_THRESHOLD,
+            bytes_generated: 0,
+            reseeder: rsdr
+        }
+    }
+}
+
+/// Something that can be used to reseed an RNG via `ReseedingRng`.
+///
+/// # Example
+///
+/// ```rust
+/// use rand::{Rng, SeedableRng};
+/// use rand::reseeding::{Reseeder, ReseedingRng};
+///
+/// struct TickTockReseeder { tick: bool }
+/// impl Reseeder<rand::StdRng> for TickTockReseeder {
+///     fn reseed(&mut self, rng: &mut rand::StdRng) {
+///         let val = if self.tick {0} else {1};
+///         rng.reseed(&[val]);
+///         self.tick = !self.tick;
+///     }
+/// }
+/// fn main() {
+///     let rsdr = TickTockReseeder { tick: true };
+///     let mut rng = ReseedingRng::new(rand::StdRng::new(), 10, rsdr);
+///
+///     // this will repeat, because it gets reseeded very regularly.
+///     println!("{}", rng.gen_ascii_str(100));
+/// }
+///
+/// ```
+pub trait Reseeder<R> {
+    /// Reseed the given RNG.
+    fn reseed(&mut self, rng: &mut R);
+}
+
+/// Reseed an RNG using a `Default` instance. This reseeds by
+/// replacing the RNG with the result of a `Default::default` call.
+pub struct ReseedWithDefault;
+
+impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {
+    fn reseed(&mut self, rng: &mut R) {
+        *rng = Default::default();
+    }
+}
+impl Default for ReseedWithDefault {
+    fn default() -> ReseedWithDefault { ReseedWithDefault }
+}
+
+#[cfg(test)]
+mod test {
+    use super::{ReseedingRng, ReseedWithDefault};
+    use std::default::Default;
+    use {SeedableRng, Rng};
+
+    struct Counter {
+        i: u32
+    }
+
+    impl Rng for Counter {
+        fn next_u32(&mut self) -> u32 {
+            self.i += 1;
+            // very random
+            self.i - 1
+        }
+    }
+    impl Default for Counter {
+        fn default() -> Counter {
+            Counter { i: 0 }
+        }
+    }
+    impl SeedableRng<u32> for Counter {
+        fn reseed(&mut self, seed: u32) {
+            self.i = seed;
+        }
+        fn from_seed(seed: u32) -> Counter {
+            Counter { i: seed }
+        }
+    }
+    type MyRng = ReseedingRng<Counter, ReseedWithDefault>;
+
+    #[test]
+    fn test_reseeding() {
+        let mut rs = ReseedingRng::new(Counter {i:0}, 400, ReseedWithDefault);
+
+        let mut i = 0;
+        for _ in range(0, 1000) {
+            assert_eq!(rs.next_u32(), i % 100);
+            i += 1;
+        }
+    }
+
+    #[test]
+    fn test_rng_seeded() {
+        let mut ra: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2));
+        let mut rb: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2));
+        assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
+    }
+
+    #[test]
+    fn test_rng_reseed() {
+        let mut r: MyRng = SeedableRng::from_seed((ReseedWithDefault, 3));
+        let string1 = r.gen_ascii_str(100);
+
+        r.reseed((ReseedWithDefault, 3));
+
+        let string2 = r.gen_ascii_str(100);
+        assert_eq!(string1, string2);
+    }
+
+    static fill_bytes_v_len: uint = 13579;
+    #[test]
+    fn test_rng_fill_bytes() {
+        use task_rng;
+        let mut v = ~[0u8, .. fill_bytes_v_len];
+        task_rng().fill_bytes(v);
+
+        // Sanity test: if we've gotten here, `fill_bytes` has not infinitely
+        // recursed.
+        assert_eq!(v.len(), fill_bytes_v_len);
+
+        // To test that `fill_bytes` actually did something, check that the
+        // average of `v` is not 0.
+        let mut sum = 0.0;
+        for &x in v.iter() {
+            sum += x as f64;
+        }
+        assert!(sum / v.len() as f64 != 0.0);
+    }
+}
index 4d3d1641bd0c2f7bead882224ce09f01bdc13e51..a873eccfb038a756737a9af9a695c09287953b96 100644 (file)
@@ -73,7 +73,8 @@
 #[cfg(test)] extern crate native;
 #[cfg(test)] extern crate green;
 
-// Make extra accessible for benchmarking
+// Make extra and rand accessible for benchmarking/testcases
+#[cfg(test)] extern crate rand;
 #[cfg(test)] extern crate extra = "extra";
 
 // Make std testable by not duplicating lang items. See #2912
 pub mod os;
 pub mod io;
 pub mod path;
-pub mod rand;
 pub mod cast;
 pub mod fmt;
 pub mod cleanup;
diff --git a/src/libstd/rand/distributions/exponential.rs b/src/libstd/rand/distributions/exponential.rs
deleted file mode 100644 (file)
index 2fa9cf8..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The exponential distribution.
-
-use num::Float;
-use rand::{Rng, Rand};
-use rand::distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample};
-
-/// A wrapper around an `f64` to generate Exp(1) random numbers.
-///
-/// See `Exp` for the general exponential distribution.Note that this
- // has to be unwrapped before use as an `f64` (using either
-/// `*` or `cast::transmute` is safe).
-///
-/// Implemented via the ZIGNOR variant[1] of the Ziggurat method. The
-/// exact description in the paper was adjusted to use tables for the
-/// exponential distribution rather than normal.
-///
-/// [1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
-/// Generate Normal Random
-/// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
-/// College, Oxford
-pub struct Exp1(f64);
-
-// This could be done via `-rng.gen::<f64>().ln()` but that is slower.
-impl Rand for Exp1 {
-    #[inline]
-    fn rand<R:Rng>(rng: &mut R) -> Exp1 {
-        #[inline]
-        fn pdf(x: f64) -> f64 {
-            (-x).exp()
-        }
-        #[inline]
-        fn zero_case<R:Rng>(rng: &mut R, _u: f64) -> f64 {
-            ziggurat_tables::ZIG_EXP_R - rng.gen::<f64>().ln()
-        }
-
-        Exp1(ziggurat(rng, false,
-                      &ziggurat_tables::ZIG_EXP_X,
-                      &ziggurat_tables::ZIG_EXP_F,
-                      pdf, zero_case))
-    }
-}
-
-/// The exponential distribution `Exp(lambda)`.
-///
-/// This distribution has density function: `f(x) = lambda *
-/// exp(-lambda * x)` for `x > 0`.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand;
-/// use std::rand::distributions::{Exp, IndependentSample};
-///
-/// let exp = Exp::new(2.0);
-/// let v = exp.ind_sample(&mut rand::task_rng());
-/// println!("{} is from a Exp(2) distribution", v);
-/// ```
-pub struct Exp {
-    /// `lambda` stored as `1/lambda`, since this is what we scale by.
-    priv lambda_inverse: f64
-}
-
-impl Exp {
-    /// Construct a new `Exp` with the given shape parameter
-    /// `lambda`. Fails if `lambda <= 0`.
-    pub fn new(lambda: f64) -> Exp {
-        assert!(lambda > 0.0, "Exp::new called with `lambda` <= 0");
-        Exp { lambda_inverse: 1.0 / lambda }
-    }
-}
-
-impl Sample<f64> for Exp {
-    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
-}
-impl IndependentSample<f64> for Exp {
-    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
-        let Exp1(n) = rng.gen::<Exp1>();
-        n * self.lambda_inverse
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use rand::distributions::*;
-    use prelude::*;
-    use rand::*;
-    use super::*;
-
-    #[test]
-    fn test_exp() {
-        let mut exp = Exp::new(10.0);
-        let mut rng = task_rng();
-        for _ in range(0, 1000) {
-            assert!(exp.sample(&mut rng) >= 0.0);
-            assert!(exp.ind_sample(&mut rng) >= 0.0);
-        }
-    }
-    #[test]
-    #[should_fail]
-    fn test_exp_invalid_lambda_zero() {
-        Exp::new(0.0);
-    }
-    #[test]
-    #[should_fail]
-    fn test_exp_invalid_lambda_neg() {
-        Exp::new(-10.0);
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    extern crate test;
-    use self::test::BenchHarness;
-    use mem::size_of;
-    use prelude::*;
-    use rand::{XorShiftRng, RAND_BENCH_N};
-    use super::*;
-    use rand::distributions::*;
-
-    #[bench]
-    fn rand_exp(bh: &mut BenchHarness) {
-        let mut rng = XorShiftRng::new();
-        let mut exp = Exp::new(2.71828 * 3.14159);
-
-        bh.iter(|| {
-            for _ in range(0, RAND_BENCH_N) {
-                exp.sample(&mut rng);
-            }
-        });
-        bh.bytes = size_of::<f64>() as u64 * RAND_BENCH_N;
-    }
-}
diff --git a/src/libstd/rand/distributions/gamma.rs b/src/libstd/rand/distributions/gamma.rs
deleted file mode 100644 (file)
index b9702cc..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The Gamma and derived distributions.
-
-use num::Float;
-use num;
-use rand::{Rng, Open01};
-use super::normal::StandardNormal;
-use super::{IndependentSample, Sample, Exp};
-
-/// The Gamma distribution `Gamma(shape, scale)` distribution.
-///
-/// The density function of this distribution is
-///
-/// ```ignore
-/// f(x) =  x^(k - 1) * exp(-x / θ) / (Γ(k) * θ^k)
-/// ```
-///
-/// where `Γ` is the Gamma function, `k` is the shape and `θ` is the
-/// scale and both `k` and `θ` are strictly positive.
-///
-/// The algorithm used is that described by Marsaglia & Tsang 2000[1],
-/// falling back to directly sampling from an Exponential for `shape
-/// == 1`, and using the boosting technique described in [1] for
-/// `shape < 1`.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand;
-/// use std::rand::distributions::{IndependentSample, Gamma};
-///
-/// let gamma = Gamma::new(2.0, 5.0);
-/// let v = gamma.ind_sample(&mut rand::task_rng());
-/// println!("{} is from a Gamma(2, 5) distribution", v);
-/// ```
-///
-/// [1]: George Marsaglia and Wai Wan Tsang. 2000. "A Simple Method
-/// for Generating Gamma Variables" *ACM Trans. Math. Softw.* 26, 3
-/// (September 2000),
-/// 363-372. DOI:[10.1145/358407.358414](http://doi.acm.org/10.1145/358407.358414)
-pub enum Gamma {
-    priv Large(GammaLargeShape),
-    priv One(Exp),
-    priv Small(GammaSmallShape)
-}
-
-// These two helpers could be made public, but saving the
-// match-on-Gamma-enum branch from using them directly (e.g. if one
-// knows that the shape is always > 1) doesn't appear to be much
-// faster.
-
-/// Gamma distribution where the shape parameter is less than 1.
-///
-/// Note, samples from this require a compulsory floating-point `pow`
-/// call, which makes it significantly slower than sampling from a
-/// gamma distribution where the shape parameter is greater than or
-/// equal to 1.
-///
-/// See `Gamma` for sampling from a Gamma distribution with general
-/// shape parameters.
-struct GammaSmallShape {
-    inv_shape: f64,
-    large_shape: GammaLargeShape
-}
-
-/// Gamma distribution where the shape parameter is larger than 1.
-///
-/// See `Gamma` for sampling from a Gamma distribution with general
-/// shape parameters.
-struct GammaLargeShape {
-    shape: f64,
-    scale: f64,
-    c: f64,
-    d: f64
-}
-
-impl Gamma {
-    /// Construct an object representing the `Gamma(shape, scale)`
-    /// distribution.
-    ///
-    /// Fails if `shape <= 0` or `scale <= 0`.
-    pub fn new(shape: f64, scale: f64) -> Gamma {
-        assert!(shape > 0.0, "Gamma::new called with shape <= 0");
-        assert!(scale > 0.0, "Gamma::new called with scale <= 0");
-
-        match shape {
-            1.0        => One(Exp::new(1.0 / scale)),
-            0.0 .. 1.0 => Small(GammaSmallShape::new_raw(shape, scale)),
-            _          => Large(GammaLargeShape::new_raw(shape, scale))
-        }
-    }
-}
-
-impl GammaSmallShape {
-    fn new_raw(shape: f64, scale: f64) -> GammaSmallShape {
-        GammaSmallShape {
-            inv_shape: 1. / shape,
-            large_shape: GammaLargeShape::new_raw(shape + 1.0, scale)
-        }
-    }
-}
-
-impl GammaLargeShape {
-    fn new_raw(shape: f64, scale: f64) -> GammaLargeShape {
-        let d = shape - 1. / 3.;
-        GammaLargeShape {
-            shape: shape,
-            scale: scale,
-            c: 1. / num::sqrt(9. * d),
-            d: d
-        }
-    }
-}
-
-impl Sample<f64> for Gamma {
-    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
-}
-impl Sample<f64> for GammaSmallShape {
-    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
-}
-impl Sample<f64> for GammaLargeShape {
-    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
-}
-
-impl IndependentSample<f64> for Gamma {
-    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
-        match *self {
-            Small(ref g) => g.ind_sample(rng),
-            One(ref g) => g.ind_sample(rng),
-            Large(ref g) => g.ind_sample(rng),
-        }
-    }
-}
-impl IndependentSample<f64> for GammaSmallShape {
-    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
-        let Open01(u) = rng.gen::<Open01<f64>>();
-
-        self.large_shape.ind_sample(rng) * num::powf(u, self.inv_shape)
-    }
-}
-impl IndependentSample<f64> for GammaLargeShape {
-    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
-        loop {
-            let StandardNormal(x) = rng.gen::<StandardNormal>();
-            let v_cbrt = 1.0 + self.c * x;
-            if v_cbrt <= 0.0 { // a^3 <= 0 iff a <= 0
-                continue
-            }
-
-            let v = v_cbrt * v_cbrt * v_cbrt;
-            let Open01(u) = rng.gen::<Open01<f64>>();
-
-            let x_sqr = x * x;
-            if u < 1.0 - 0.0331 * x_sqr * x_sqr ||
-                num::ln(u) < 0.5 * x_sqr + self.d * (1.0 - v + num::ln(v)) {
-                return self.d * v * self.scale
-            }
-        }
-    }
-}
-
-/// The chi-squared distribution `χ²(k)`, where `k` is the degrees of
-/// freedom.
-///
-/// For `k > 0` integral, this distribution is the sum of the squares
-/// of `k` independent standard normal random variables. For other
-/// `k`, this uses the equivalent characterisation `χ²(k) = Gamma(k/2,
-/// 2)`.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand;
-/// use std::rand::distributions::{ChiSquared, IndependentSample};
-///
-/// let chi = ChiSquared::new(11.0);
-/// let v = chi.ind_sample(&mut rand::task_rng());
-/// println!("{} is from a χ²(11) distribution", v)
-/// ```
-pub enum ChiSquared {
-    // k == 1, Gamma(alpha, ..) is particularly slow for alpha < 1,
-    // e.g. when alpha = 1/2 as it would be for this case, so special-
-    // casing and using the definition of N(0,1)^2 is faster.
-    priv DoFExactlyOne,
-    priv DoFAnythingElse(Gamma)
-}
-
-impl ChiSquared {
-    /// Create a new chi-squared distribution with degrees-of-freedom
-    /// `k`. Fails if `k < 0`.
-    pub fn new(k: f64) -> ChiSquared {
-        if k == 1.0 {
-            DoFExactlyOne
-        } else {
-            assert!(k > 0.0, "ChiSquared::new called with `k` < 0");
-            DoFAnythingElse(Gamma::new(0.5 * k, 2.0))
-        }
-    }
-}
-impl Sample<f64> for ChiSquared {
-    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
-}
-impl IndependentSample<f64> for ChiSquared {
-    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
-        match *self {
-            DoFExactlyOne => {
-                // k == 1 => N(0,1)^2
-                let StandardNormal(norm) = rng.gen::<StandardNormal>();
-                norm * norm
-            }
-            DoFAnythingElse(ref g) => g.ind_sample(rng)
-        }
-    }
-}
-
-/// The Fisher F distribution `F(m, n)`.
-///
-/// This distribution is equivalent to the ratio of two normalised
-/// chi-squared distributions, that is, `F(m,n) = (χ²(m)/m) /
-/// (χ²(n)/n)`.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand;
-/// use std::rand::distributions::{FisherF, IndependentSample};
-///
-/// let f = FisherF::new(2.0, 32.0);
-/// let v = f.ind_sample(&mut rand::task_rng());
-/// println!("{} is from an F(2, 32) distribution", v)
-/// ```
-pub struct FisherF {
-    priv numer: ChiSquared,
-    priv denom: ChiSquared,
-    // denom_dof / numer_dof so that this can just be a straight
-    // multiplication, rather than a division.
-    priv dof_ratio: f64,
-}
-
-impl FisherF {
-    /// Create a new `FisherF` distribution, with the given
-    /// parameter. Fails if either `m` or `n` are not positive.
-    pub fn new(m: f64, n: f64) -> FisherF {
-        assert!(m > 0.0, "FisherF::new called with `m < 0`");
-        assert!(n > 0.0, "FisherF::new called with `n < 0`");
-
-        FisherF {
-            numer: ChiSquared::new(m),
-            denom: ChiSquared::new(n),
-            dof_ratio: n / m
-        }
-    }
-}
-impl Sample<f64> for FisherF {
-    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
-}
-impl IndependentSample<f64> for FisherF {
-    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
-        self.numer.ind_sample(rng) / self.denom.ind_sample(rng) * self.dof_ratio
-    }
-}
-
-/// The Student t distribution, `t(nu)`, where `nu` is the degrees of
-/// freedom.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand;
-/// use std::rand::distributions::{StudentT, IndependentSample};
-///
-/// let t = StudentT::new(11.0);
-/// let v = t.ind_sample(&mut rand::task_rng());
-/// println!("{} is from a t(11) distribution", v)
-/// ```
-pub struct StudentT {
-    priv chi: ChiSquared,
-    priv dof: f64
-}
-
-impl StudentT {
-    /// Create a new Student t distribution with `n` degrees of
-    /// freedom. Fails if `n <= 0`.
-    pub fn new(n: f64) -> StudentT {
-        assert!(n > 0.0, "StudentT::new called with `n <= 0`");
-        StudentT {
-            chi: ChiSquared::new(n),
-            dof: n
-        }
-    }
-}
-impl Sample<f64> for StudentT {
-    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
-}
-impl IndependentSample<f64> for StudentT {
-    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
-        let StandardNormal(norm) = rng.gen::<StandardNormal>();
-        norm * (self.dof / self.chi.ind_sample(rng)).sqrt()
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use rand::distributions::*;
-    use prelude::*;
-    use rand::*;
-    use super::*;
-
-    #[test]
-    fn test_chi_squared_one() {
-        let mut chi = ChiSquared::new(1.0);
-        let mut rng = task_rng();
-        for _ in range(0, 1000) {
-            chi.sample(&mut rng);
-            chi.ind_sample(&mut rng);
-        }
-    }
-    #[test]
-    fn test_chi_squared_small() {
-        let mut chi = ChiSquared::new(0.5);
-        let mut rng = task_rng();
-        for _ in range(0, 1000) {
-            chi.sample(&mut rng);
-            chi.ind_sample(&mut rng);
-        }
-    }
-    #[test]
-    fn test_chi_squared_large() {
-        let mut chi = ChiSquared::new(30.0);
-        let mut rng = task_rng();
-        for _ in range(0, 1000) {
-            chi.sample(&mut rng);
-            chi.ind_sample(&mut rng);
-        }
-    }
-    #[test]
-    #[should_fail]
-    fn test_log_normal_invalid_dof() {
-        ChiSquared::new(-1.0);
-    }
-
-    #[test]
-    fn test_f() {
-        let mut f = FisherF::new(2.0, 32.0);
-        let mut rng = task_rng();
-        for _ in range(0, 1000) {
-            f.sample(&mut rng);
-            f.ind_sample(&mut rng);
-        }
-    }
-
-    #[test]
-    fn test_t() {
-        let mut t = StudentT::new(11.0);
-        let mut rng = task_rng();
-        for _ in range(0, 1000) {
-            t.sample(&mut rng);
-            t.ind_sample(&mut rng);
-        }
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    extern crate test;
-    use self::test::BenchHarness;
-    use mem::size_of;
-    use prelude::*;
-    use rand::distributions::IndependentSample;
-    use rand::{StdRng, RAND_BENCH_N};
-    use super::*;
-
-
-    #[bench]
-    fn bench_gamma_large_shape(bh: &mut BenchHarness) {
-        let gamma = Gamma::new(10., 1.0);
-        let mut rng = StdRng::new();
-
-        bh.iter(|| {
-            for _ in range(0, RAND_BENCH_N) {
-                gamma.ind_sample(&mut rng);
-            }
-        });
-        bh.bytes = size_of::<f64>() as u64 * RAND_BENCH_N;
-    }
-
-    #[bench]
-    fn bench_gamma_small_shape(bh: &mut BenchHarness) {
-        let gamma = Gamma::new(0.1, 1.0);
-        let mut rng = StdRng::new();
-
-        bh.iter(|| {
-            for _ in range(0, RAND_BENCH_N) {
-                gamma.ind_sample(&mut rng);
-            }
-        });
-        bh.bytes = size_of::<f64>() as u64 * RAND_BENCH_N;
-    }
-}
diff --git a/src/libstd/rand/distributions/mod.rs b/src/libstd/rand/distributions/mod.rs
deleted file mode 100644 (file)
index 41a106e..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-Sampling from random distributions.
-
-This is a generalization of `Rand` to allow parameters to control the
-exact properties of the generated values, e.g. the mean and standard
-deviation of a normal distribution. The `Sample` trait is the most
-general, and allows for generating values that change some state
-internally. The `IndependentSample` trait is for generating values
-that do not need to record state.
-
-*/
-
-use container::Container;
-use iter::{range, Iterator};
-use option::{Some, None};
-use num;
-use num::CheckedAdd;
-use rand::{Rng, Rand};
-use clone::Clone;
-use vec::MutableVector;
-
-pub use self::range::Range;
-pub use self::gamma::{Gamma, ChiSquared, FisherF, StudentT};
-pub use self::normal::{Normal, LogNormal};
-pub use self::exponential::Exp;
-
-pub mod range;
-pub mod gamma;
-pub mod normal;
-pub mod exponential;
-
-/// Types that can be used to create a random instance of `Support`.
-pub trait Sample<Support> {
-    /// Generate a random value of `Support`, using `rng` as the
-    /// source of randomness.
-    fn sample<R: Rng>(&mut self, rng: &mut R) -> Support;
-}
-
-/// `Sample`s that do not require keeping track of state.
-///
-/// Since no state is recorded, each sample is (statistically)
-/// independent of all others, assuming the `Rng` used has this
-/// property.
-// FIXME maybe having this separate is overkill (the only reason is to
-// take &self rather than &mut self)? or maybe this should be the
-// trait called `Sample` and the other should be `DependentSample`.
-pub trait IndependentSample<Support>: Sample<Support> {
-    /// Generate a random value.
-    fn ind_sample<R: Rng>(&self, &mut R) -> Support;
-}
-
-/// A wrapper for generating types that implement `Rand` via the
-/// `Sample` & `IndependentSample` traits.
-pub struct RandSample<Sup>;
-
-impl<Sup: Rand> Sample<Sup> for RandSample<Sup> {
-    fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
-}
-
-impl<Sup: Rand> IndependentSample<Sup> for RandSample<Sup> {
-    fn ind_sample<R: Rng>(&self, rng: &mut R) -> Sup {
-        rng.gen()
-    }
-}
-
-/// A value with a particular weight for use with `WeightedChoice`.
-pub struct Weighted<T> {
-    /// The numerical weight of this item
-    weight: uint,
-    /// The actual item which is being weighted
-    item: T,
-}
-
-/// A distribution that selects from a finite collection of weighted items.
-///
-/// Each item has an associated weight that influences how likely it
-/// is to be chosen: higher weight is more likely.
-///
-/// The `Clone` restriction is a limitation of the `Sample` and
-/// `IndependentSample` traits. Note that `&T` is (cheaply) `Clone` for
-/// all `T`, as is `uint`, so one can store references or indices into
-/// another vector.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand;
-/// use std::rand::distributions::{Weighted, WeightedChoice, IndependentSample};
-///
-/// let wc = WeightedChoice::new(~[Weighted { weight: 2, item: 'a' },
-///                                Weighted { weight: 4, item: 'b' },
-///                                Weighted { weight: 1, item: 'c' }]);
-/// let mut rng = rand::task_rng();
-/// for _ in range(0, 16) {
-///      // on average prints 'a' 4 times, 'b' 8 and 'c' twice.
-///      println!("{}", wc.ind_sample(&mut rng));
-/// }
-/// ```
-pub struct WeightedChoice<T> {
-    priv items: ~[Weighted<T>],
-    priv weight_range: Range<uint>
-}
-
-impl<T: Clone> WeightedChoice<T> {
-    /// Create a new `WeightedChoice`.
-    ///
-    /// Fails if:
-    /// - `v` is empty
-    /// - the total weight is 0
-    /// - the total weight is larger than a `uint` can contain.
-    pub fn new(mut items: ~[Weighted<T>]) -> WeightedChoice<T> {
-        // strictly speaking, this is subsumed by the total weight == 0 case
-        assert!(!items.is_empty(), "WeightedChoice::new called with no items");
-
-        let mut running_total = 0u;
-
-        // we convert the list from individual weights to cumulative
-        // weights so we can binary search. This *could* drop elements
-        // with weight == 0 as an optimisation.
-        for item in items.mut_iter() {
-            running_total = running_total.checked_add(&item.weight)
-                .expect("WeightedChoice::new called with a total weight larger \
-                        than a uint can contain");
-
-            item.weight = running_total;
-        }
-        assert!(running_total != 0, "WeightedChoice::new called with a total weight of 0");
-
-        WeightedChoice {
-            items: items,
-            // we're likely to be generating numbers in this range
-            // relatively often, so might as well cache it
-            weight_range: Range::new(0, running_total)
-        }
-    }
-}
-
-impl<T: Clone> Sample<T> for WeightedChoice<T> {
-    fn sample<R: Rng>(&mut self, rng: &mut R) -> T { self.ind_sample(rng) }
-}
-
-impl<T: Clone> IndependentSample<T> for WeightedChoice<T> {
-    fn ind_sample<R: Rng>(&self, rng: &mut R) -> T {
-        // we want to find the first element that has cumulative
-        // weight > sample_weight, which we do by binary since the
-        // cumulative weights of self.items are sorted.
-
-        // choose a weight in [0, total_weight)
-        let sample_weight = self.weight_range.ind_sample(rng);
-
-        // short circuit when it's the first item
-        if sample_weight < self.items[0].weight {
-            return self.items[0].item.clone();
-        }
-
-        let mut idx = 0;
-        let mut modifier = self.items.len();
-
-        // now we know that every possibility has an element to the
-        // left, so we can just search for the last element that has
-        // cumulative weight <= sample_weight, then the next one will
-        // be "it". (Note that this greatest element will never be the
-        // last element of the vector, since sample_weight is chosen
-        // in [0, total_weight) and the cumulative weight of the last
-        // one is exactly the total weight.)
-        while modifier > 1 {
-            let i = idx + modifier / 2;
-            if self.items[i].weight <= sample_weight {
-                // we're small, so look to the right, but allow this
-                // exact element still.
-                idx = i;
-                // we need the `/ 2` to round up otherwise we'll drop
-                // the trailing elements when `modifier` is odd.
-                modifier += 1;
-            } else {
-                // otherwise we're too big, so go left. (i.e. do
-                // nothing)
-            }
-            modifier /= 2;
-        }
-        return self.items[idx + 1].item.clone();
-    }
-}
-
-mod ziggurat_tables;
-
-/// Sample a random number using the Ziggurat method (specifically the
-/// ZIGNOR variant from Doornik 2005). Most of the arguments are
-/// directly from the paper:
-///
-/// * `rng`: source of randomness
-/// * `symmetric`: whether this is a symmetric distribution, or one-sided with P(x < 0) = 0.
-/// * `X`: the $x_i$ abscissae.
-/// * `F`: precomputed values of the PDF at the $x_i$, (i.e. $f(x_i)$)
-/// * `F_DIFF`: precomputed values of $f(x_i) - f(x_{i+1})$
-/// * `pdf`: the probability density function
-/// * `zero_case`: manual sampling from the tail when we chose the
-///    bottom box (i.e. i == 0)
-
-// the perf improvement (25-50%) is definitely worth the extra code
-// size from force-inlining.
-#[inline(always)]
-fn ziggurat<R:Rng>(
-            rng: &mut R,
-            symmetric: bool,
-            x_tab: ziggurat_tables::ZigTable,
-            f_tab: ziggurat_tables::ZigTable,
-            pdf: 'static |f64| -> f64,
-            zero_case: 'static |&mut R, f64| -> f64)
-            -> f64 {
-    static SCALE: f64 = (1u64 << 53) as f64;
-    loop {
-        // reimplement the f64 generation as an optimisation suggested
-        // by the Doornik paper: we have a lot of precision-space
-        // (i.e. there are 11 bits of the 64 of a u64 to use after
-        // creating a f64), so we might as well reuse some to save
-        // generating a whole extra random number. (Seems to be 15%
-        // faster.)
-        let bits: u64 = rng.gen();
-        let i = (bits & 0xff) as uint;
-        let f = (bits >> 11) as f64 / SCALE;
-
-        // u is either U(-1, 1) or U(0, 1) depending on if this is a
-        // symmetric distribution or not.
-        let u = if symmetric {2.0 * f - 1.0} else {f};
-        let x = u * x_tab[i];
-
-        let test_x = if symmetric {num::abs(x)} else {x};
-
-        // algebraically equivalent to |u| < x_tab[i+1]/x_tab[i] (or u < x_tab[i+1]/x_tab[i])
-        if test_x < x_tab[i + 1] {
-            return x;
-        }
-        if i == 0 {
-            return zero_case(rng, u);
-        }
-        // algebraically equivalent to f1 + DRanU()*(f0 - f1) < 1
-        if f_tab[i + 1] + (f_tab[i] - f_tab[i + 1]) * rng.gen() < pdf(x) {
-            return x;
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use rand::*;
-    use super::*;
-
-    #[deriving(Eq, Show)]
-    struct ConstRand(uint);
-    impl Rand for ConstRand {
-        fn rand<R: Rng>(_: &mut R) -> ConstRand {
-            ConstRand(0)
-        }
-    }
-
-    // 0, 1, 2, 3, ...
-    struct CountingRng { i: u32 }
-    impl Rng for CountingRng {
-        fn next_u32(&mut self) -> u32 {
-            self.i += 1;
-            self.i - 1
-        }
-        fn next_u64(&mut self) -> u64 {
-            self.next_u32() as u64
-        }
-    }
-
-    #[test]
-    fn test_rand_sample() {
-        let mut rand_sample = RandSample::<ConstRand>;
-
-        assert_eq!(rand_sample.sample(&mut task_rng()), ConstRand(0));
-        assert_eq!(rand_sample.ind_sample(&mut task_rng()), ConstRand(0));
-    }
-    #[test]
-    fn test_weighted_choice() {
-        // this makes assumptions about the internal implementation of
-        // WeightedChoice, specifically: it doesn't reorder the items,
-        // it doesn't do weird things to the RNG (so 0 maps to 0, 1 to
-        // 1, internally; modulo a modulo operation).
-
-        macro_rules! t (
-            ($items:expr, $expected:expr) => {{
-                let wc = WeightedChoice::new($items);
-                let expected = $expected;
-
-                let mut rng = CountingRng { i: 0 };
-
-                for &val in expected.iter() {
-                    assert_eq!(wc.ind_sample(&mut rng), val)
-                }
-            }}
-        );
-
-        t!(~[Weighted { weight: 1, item: 10}], ~[10]);
-
-        // skip some
-        t!(~[Weighted { weight: 0, item: 20},
-             Weighted { weight: 2, item: 21},
-             Weighted { weight: 0, item: 22},
-             Weighted { weight: 1, item: 23}],
-           ~[21,21, 23]);
-
-        // different weights
-        t!(~[Weighted { weight: 4, item: 30},
-             Weighted { weight: 3, item: 31}],
-           ~[30,30,30,30, 31,31,31]);
-
-        // check that we're binary searching
-        // correctly with some vectors of odd
-        // length.
-        t!(~[Weighted { weight: 1, item: 40},
-             Weighted { weight: 1, item: 41},
-             Weighted { weight: 1, item: 42},
-             Weighted { weight: 1, item: 43},
-             Weighted { weight: 1, item: 44}],
-           ~[40, 41, 42, 43, 44]);
-        t!(~[Weighted { weight: 1, item: 50},
-             Weighted { weight: 1, item: 51},
-             Weighted { weight: 1, item: 52},
-             Weighted { weight: 1, item: 53},
-             Weighted { weight: 1, item: 54},
-             Weighted { weight: 1, item: 55},
-             Weighted { weight: 1, item: 56}],
-           ~[50, 51, 52, 53, 54, 55, 56]);
-    }
-
-    #[test] #[should_fail]
-    fn test_weighted_choice_no_items() {
-        WeightedChoice::<int>::new(~[]);
-    }
-    #[test] #[should_fail]
-    fn test_weighted_choice_zero_weight() {
-        WeightedChoice::new(~[Weighted { weight: 0, item: 0},
-                              Weighted { weight: 0, item: 1}]);
-    }
-    #[test] #[should_fail]
-    fn test_weighted_choice_weight_overflows() {
-        let x = (-1) as uint / 2; // x + x + 2 is the overflow
-        WeightedChoice::new(~[Weighted { weight: x, item: 0 },
-                              Weighted { weight: 1, item: 1 },
-                              Weighted { weight: x, item: 2 },
-                              Weighted { weight: 1, item: 3 }]);
-    }
-}
diff --git a/src/libstd/rand/distributions/normal.rs b/src/libstd/rand/distributions/normal.rs
deleted file mode 100644 (file)
index b2f952e..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The normal and derived distributions.
-
-use num::Float;
-use rand::{Rng, Rand, Open01};
-use rand::distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample};
-
-/// A wrapper around an `f64` to generate N(0, 1) random numbers
-/// (a.k.a.  a standard normal, or Gaussian).
-///
-/// See `Normal` for the general normal distribution. That this has to
-/// be unwrapped before use as an `f64` (using either `*` or
-/// `cast::transmute` is safe).
-///
-/// Implemented via the ZIGNOR variant[1] of the Ziggurat method.
-///
-/// [1]: Jurgen A. Doornik (2005). [*An Improved Ziggurat Method to
-/// Generate Normal Random
-/// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
-/// College, Oxford
-pub struct StandardNormal(f64);
-
-impl Rand for StandardNormal {
-    fn rand<R:Rng>(rng: &mut R) -> StandardNormal {
-        #[inline]
-        fn pdf(x: f64) -> f64 {
-            (-x*x/2.0).exp()
-        }
-        #[inline]
-        fn zero_case<R:Rng>(rng: &mut R, u: f64) -> f64 {
-            // compute a random number in the tail by hand
-
-            // strange initial conditions, because the loop is not
-            // do-while, so the condition should be true on the first
-            // run, they get overwritten anyway (0 < 1, so these are
-            // good).
-            let mut x = 1.0f64;
-            let mut y = 0.0f64;
-
-            while -2.0 * y < x * x {
-                let Open01(x_) = rng.gen::<Open01<f64>>();
-                let Open01(y_) = rng.gen::<Open01<f64>>();
-
-                x = x_.ln() / ziggurat_tables::ZIG_NORM_R;
-                y = y_.ln();
-            }
-
-            if u < 0.0 { x - ziggurat_tables::ZIG_NORM_R } else { ziggurat_tables::ZIG_NORM_R - x }
-        }
-
-        StandardNormal(ziggurat(
-            rng,
-            true, // this is symmetric
-            &ziggurat_tables::ZIG_NORM_X,
-            &ziggurat_tables::ZIG_NORM_F,
-            pdf, zero_case))
-    }
-}
-
-/// The normal distribution `N(mean, std_dev**2)`.
-///
-/// This uses the ZIGNOR variant of the Ziggurat method, see
-/// `StandardNormal` for more details.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand;
-/// use std::rand::distributions::{Normal, IndependentSample};
-///
-/// // mean 2, standard deviation 3
-/// let normal = Normal::new(2.0, 3.0);
-/// let v = normal.ind_sample(&mut rand::task_rng());
-/// println!("{} is from a N(2, 9) distribution", v)
-/// ```
-pub struct Normal {
-    priv mean: f64,
-    priv std_dev: f64
-}
-
-impl Normal {
-    /// Construct a new `Normal` distribution with the given mean and
-    /// standard deviation. Fails if `std_dev < 0`.
-    pub fn new(mean: f64, std_dev: f64) -> Normal {
-        assert!(std_dev >= 0.0, "Normal::new called with `std_dev` < 0");
-        Normal {
-            mean: mean,
-            std_dev: std_dev
-        }
-    }
-}
-impl Sample<f64> for Normal {
-    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
-}
-impl IndependentSample<f64> for Normal {
-    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
-        let StandardNormal(n) = rng.gen::<StandardNormal>();
-        self.mean + self.std_dev * n
-    }
-}
-
-
-/// The log-normal distribution `ln N(mean, std_dev**2)`.
-///
-/// If `X` is log-normal distributed, then `ln(X)` is `N(mean,
-/// std_dev**2)` distributed.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand;
-/// use std::rand::distributions::{LogNormal, IndependentSample};
-///
-/// // mean 2, standard deviation 3
-/// let log_normal = LogNormal::new(2.0, 3.0);
-/// let v = log_normal.ind_sample(&mut rand::task_rng());
-/// println!("{} is from an ln N(2, 9) distribution", v)
-/// ```
-pub struct LogNormal {
-    priv norm: Normal
-}
-
-impl LogNormal {
-    /// Construct a new `LogNormal` distribution with the given mean
-    /// and standard deviation. Fails if `std_dev < 0`.
-    pub fn new(mean: f64, std_dev: f64) -> LogNormal {
-        assert!(std_dev >= 0.0, "LogNormal::new called with `std_dev` < 0");
-        LogNormal { norm: Normal::new(mean, std_dev) }
-    }
-}
-impl Sample<f64> for LogNormal {
-    fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 { self.ind_sample(rng) }
-}
-impl IndependentSample<f64> for LogNormal {
-    fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
-        self.norm.ind_sample(rng).exp()
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use rand::*;
-    use super::*;
-    use rand::distributions::*;
-
-    #[test]
-    fn test_normal() {
-        let mut norm = Normal::new(10.0, 10.0);
-        let mut rng = task_rng();
-        for _ in range(0, 1000) {
-            norm.sample(&mut rng);
-            norm.ind_sample(&mut rng);
-        }
-    }
-    #[test]
-    #[should_fail]
-    fn test_normal_invalid_sd() {
-        Normal::new(10.0, -1.0);
-    }
-
-
-    #[test]
-    fn test_log_normal() {
-        let mut lnorm = LogNormal::new(10.0, 10.0);
-        let mut rng = task_rng();
-        for _ in range(0, 1000) {
-            lnorm.sample(&mut rng);
-            lnorm.ind_sample(&mut rng);
-        }
-    }
-    #[test]
-    #[should_fail]
-    fn test_log_normal_invalid_sd() {
-        LogNormal::new(10.0, -1.0);
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    extern crate test;
-    use self::test::BenchHarness;
-    use mem::size_of;
-    use prelude::*;
-    use rand::{XorShiftRng, RAND_BENCH_N};
-    use rand::distributions::*;
-    use super::*;
-
-    #[bench]
-    fn rand_normal(bh: &mut BenchHarness) {
-        let mut rng = XorShiftRng::new();
-        let mut normal = Normal::new(-2.71828, 3.14159);
-
-        bh.iter(|| {
-            for _ in range(0, RAND_BENCH_N) {
-                normal.sample(&mut rng);
-            }
-        });
-        bh.bytes = size_of::<f64>() as u64 * RAND_BENCH_N;
-    }
-}
diff --git a/src/libstd/rand/distributions/range.rs b/src/libstd/rand/distributions/range.rs
deleted file mode 100644 (file)
index 8141b3d..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Generating numbers between two others.
-
-// this is surprisingly complicated to be both generic & correct
-
-use cmp::Ord;
-use num::Bounded;
-use rand::Rng;
-use rand::distributions::{Sample, IndependentSample};
-
-/// Sample values uniformly between two bounds.
-///
-/// This gives a uniform distribution (assuming the RNG used to sample
-/// it is itself uniform & the `SampleRange` implementation for the
-/// given type is correct), even for edge cases like `low = 0u8`,
-/// `high = 170u8`, for which a naive modulo operation would return
-/// numbers less than 85 with double the probability to those greater
-/// than 85.
-///
-/// Types should attempt to sample in `[low, high)`, i.e., not
-/// including `high`, but this may be very difficult. All the
-/// primitive integer types satisfy this property, and the float types
-/// normally satisfy it, but rounding may mean `high` can occur.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand;
-/// use std::rand::distributions::{IndependentSample, Range};
-///
-/// fn main() {
-///     let between = Range::new(10u, 10000u);
-///     let mut rng = rand::task_rng();
-///     let mut sum = 0;
-///     for _ in range(0, 1000) {
-///         sum += between.ind_sample(&mut rng);
-///     }
-///     println!("{}", sum);
-/// }
-/// ```
-pub struct Range<X> {
-    priv low: X,
-    priv range: X,
-    priv accept_zone: X
-}
-
-impl<X: SampleRange + Ord> Range<X> {
-    /// Create a new `Range` instance that samples uniformly from
-    /// `[low, high)`. Fails if `low >= high`.
-    pub fn new(low: X, high: X) -> Range<X> {
-        assert!(low < high, "Range::new called with `low >= high`");
-        SampleRange::construct_range(low, high)
-    }
-}
-
-impl<Sup: SampleRange> Sample<Sup> for Range<Sup> {
-    #[inline]
-    fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
-}
-impl<Sup: SampleRange> IndependentSample<Sup> for Range<Sup> {
-    fn ind_sample<R: Rng>(&self, rng: &mut R) -> Sup {
-        SampleRange::sample_range(self, rng)
-    }
-}
-
-/// The helper trait for types that have a sensible way to sample
-/// uniformly between two values. This should not be used directly,
-/// and is only to facilitate `Range`.
-pub trait SampleRange {
-    /// Construct the `Range` object that `sample_range`
-    /// requires. This should not ever be called directly, only via
-    /// `Range::new`, which will check that `low < high`, so this
-    /// function doesn't have to repeat the check.
-    fn construct_range(low: Self, high: Self) -> Range<Self>;
-
-    /// Sample a value from the given `Range` with the given `Rng` as
-    /// a source of randomness.
-    fn sample_range<R: Rng>(r: &Range<Self>, rng: &mut R) -> Self;
-}
-
-macro_rules! integer_impl {
-    ($ty:ty, $unsigned:ty) => {
-        impl SampleRange for $ty {
-            // we play free and fast with unsigned vs signed here
-            // (when $ty is signed), but that's fine, since the
-            // contract of this macro is for $ty and $unsigned to be
-            // "bit-equal", so casting between them is a no-op & a
-            // bijection.
-
-            fn construct_range(low: $ty, high: $ty) -> Range<$ty> {
-                let range = high as $unsigned - low as $unsigned;
-                let unsigned_max: $unsigned = Bounded::max_value();
-
-                // this is the largest number that fits into $unsigned
-                // that `range` divides evenly, so, if we've sampled
-                // `n` uniformly from this region, then `n % range` is
-                // uniform in [0, range)
-                let zone = unsigned_max - unsigned_max % range;
-
-                Range {
-                    low: low,
-                    range: range as $ty,
-                    accept_zone: zone as $ty
-                }
-            }
-            #[inline]
-            fn sample_range<R: Rng>(r: &Range<$ty>, rng: &mut R) -> $ty {
-                loop {
-                    // rejection sample
-                    let v = rng.gen::<$unsigned>();
-                    // until we find something that fits into the
-                    // region which r.range evenly divides (this will
-                    // be uniformly distributed)
-                    if v < r.accept_zone as $unsigned {
-                        // and return it, with some adjustments
-                        return r.low + (v % r.range as $unsigned) as $ty;
-                    }
-                }
-            }
-        }
-    }
-}
-
-integer_impl! { i8, u8 }
-integer_impl! { i16, u16 }
-integer_impl! { i32, u32 }
-integer_impl! { i64, u64 }
-integer_impl! { int, uint }
-integer_impl! { u8, u8 }
-integer_impl! { u16, u16 }
-integer_impl! { u32, u32 }
-integer_impl! { u64, u64 }
-integer_impl! { uint, uint }
-
-macro_rules! float_impl {
-    ($ty:ty) => {
-        impl SampleRange for $ty {
-            fn construct_range(low: $ty, high: $ty) -> Range<$ty> {
-                Range {
-                    low: low,
-                    range: high - low,
-                    accept_zone: 0.0 // unused
-                }
-            }
-            fn sample_range<R: Rng>(r: &Range<$ty>, rng: &mut R) -> $ty {
-                r.low + r.range * rng.gen()
-            }
-        }
-    }
-}
-
-float_impl! { f32 }
-float_impl! { f64 }
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use super::*;
-    use rand::*;
-    use rand::distributions::*;
-    use num::Bounded;
-
-    #[should_fail]
-    #[test]
-    fn test_range_bad_limits_equal() {
-        Range::new(10, 10);
-    }
-    #[should_fail]
-    #[test]
-    fn test_range_bad_limits_flipped() {
-        Range::new(10, 5);
-    }
-
-    #[test]
-    fn test_integers() {
-        let mut rng = task_rng();
-        macro_rules! t (
-            ($($ty:ty),*) => {{
-                $(
-                   let v: &[($ty, $ty)] = [(0, 10),
-                                           (10, 127),
-                                           (Bounded::min_value(), Bounded::max_value())];
-                   for &(low, high) in v.iter() {
-                        let mut sampler: Range<$ty> = Range::new(low, high);
-                        for _ in range(0, 1000) {
-                            let v = sampler.sample(&mut rng);
-                            assert!(low <= v && v < high);
-                            let v = sampler.ind_sample(&mut rng);
-                            assert!(low <= v && v < high);
-                        }
-                    }
-                 )*
-            }}
-        );
-        t!(i8, i16, i32, i64, int,
-           u8, u16, u32, u64, uint)
-    }
-
-    #[test]
-    fn test_floats() {
-        let mut rng = task_rng();
-        macro_rules! t (
-            ($($ty:ty),*) => {{
-                $(
-                   let v: &[($ty, $ty)] = [(0.0, 100.0),
-                                           (-1e35, -1e25),
-                                           (1e-35, 1e-25),
-                                           (-1e35, 1e35)];
-                   for &(low, high) in v.iter() {
-                        let mut sampler: Range<$ty> = Range::new(low, high);
-                        for _ in range(0, 1000) {
-                            let v = sampler.sample(&mut rng);
-                            assert!(low <= v && v < high);
-                            let v = sampler.ind_sample(&mut rng);
-                            assert!(low <= v && v < high);
-                        }
-                    }
-                 )*
-            }}
-        );
-
-        t!(f32, f64)
-    }
-
-}
diff --git a/src/libstd/rand/distributions/ziggurat_tables.rs b/src/libstd/rand/distributions/ziggurat_tables.rs
deleted file mode 100644 (file)
index 049ef3d..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Tables for distributions which are sampled using the ziggurat
-// algorithm. Autogenerated by `ziggurat_tables.py`.
-
-pub type ZigTable = &'static [f64, .. 257];
-pub static ZIG_NORM_R: f64 = 3.654152885361008796;
-pub static ZIG_NORM_X: [f64, .. 257] =
-    [3.910757959537090045, 3.654152885361008796, 3.449278298560964462, 3.320244733839166074,
-     3.224575052047029100, 3.147889289517149969, 3.083526132001233044, 3.027837791768635434,
-     2.978603279880844834, 2.934366867207854224, 2.894121053612348060, 2.857138730872132548,
-     2.822877396825325125, 2.790921174000785765, 2.760944005278822555, 2.732685359042827056,
-     2.705933656121858100, 2.680514643284522158, 2.656283037575502437, 2.633116393630324570,
-     2.610910518487548515, 2.589575986706995181, 2.569035452680536569, 2.549221550323460761,
-     2.530075232158516929, 2.511544441625342294, 2.493583041269680667, 2.476149939669143318,
-     2.459208374333311298, 2.442725318198956774, 2.426670984935725972, 2.411018413899685520,
-     2.395743119780480601, 2.380822795170626005, 2.366237056715818632, 2.351967227377659952,
-     2.337996148795031370, 2.324308018869623016, 2.310888250599850036, 2.297723348901329565,
-     2.284800802722946056, 2.272108990226823888, 2.259637095172217780, 2.247375032945807760,
-     2.235313384928327984, 2.223443340090905718, 2.211756642882544366, 2.200245546609647995,
-     2.188902771624720689, 2.177721467738641614, 2.166695180352645966, 2.155817819875063268,
-     2.145083634046203613, 2.134487182844320152, 2.124023315687815661, 2.113687150684933957,
-     2.103474055713146829, 2.093379631137050279, 2.083399693996551783, 2.073530263516978778,
-     2.063767547809956415, 2.054107931648864849, 2.044547965215732788, 2.035084353727808715,
-     2.025713947862032960, 2.016433734904371722, 2.007240830558684852, 1.998132471356564244,
-     1.989106007615571325, 1.980158896898598364, 1.971288697931769640, 1.962493064942461896,
-     1.953769742382734043, 1.945116560006753925, 1.936531428273758904, 1.928012334050718257,
-     1.919557336591228847, 1.911164563769282232, 1.902832208548446369, 1.894558525668710081,
-     1.886341828534776388, 1.878180486290977669, 1.870072921069236838, 1.862017605397632281,
-     1.854013059758148119, 1.846057850283119750, 1.838150586580728607, 1.830289919680666566,
-     1.822474540091783224, 1.814703175964167636, 1.806974591348693426, 1.799287584547580199,
-     1.791640986550010028, 1.784033659547276329, 1.776464495522344977, 1.768932414909077933,
-     1.761436365316706665, 1.753975320315455111, 1.746548278279492994, 1.739154261283669012,
-     1.731792314050707216, 1.724461502945775715, 1.717160915015540690, 1.709889657069006086,
-     1.702646854797613907, 1.695431651932238548, 1.688243209434858727, 1.681080704722823338,
-     1.673943330923760353, 1.666830296159286684, 1.659740822855789499, 1.652674147080648526,
-     1.645629517902360339, 1.638606196773111146, 1.631603456932422036, 1.624620582830568427,
-     1.617656869570534228, 1.610711622367333673, 1.603784156023583041, 1.596873794420261339,
-     1.589979870021648534, 1.583101723393471438, 1.576238702733332886, 1.569390163412534456,
-     1.562555467528439657, 1.555733983466554893, 1.548925085471535512, 1.542128153226347553,
-     1.535342571438843118, 1.528567729435024614, 1.521803020758293101, 1.515047842773992404,
-     1.508301596278571965, 1.501563685112706548, 1.494833515777718391, 1.488110497054654369,
-     1.481394039625375747, 1.474683555695025516, 1.467978458615230908, 1.461278162507407830,
-     1.454582081885523293, 1.447889631277669675, 1.441200224845798017, 1.434513276002946425,
-     1.427828197027290358, 1.421144398672323117, 1.414461289772464658, 1.407778276843371534,
-     1.401094763676202559, 1.394410150925071257, 1.387723835686884621, 1.381035211072741964,
-     1.374343665770030531, 1.367648583594317957, 1.360949343030101844, 1.354245316759430606,
-     1.347535871177359290, 1.340820365893152122, 1.334098153216083604, 1.327368577624624679,
-     1.320630975217730096, 1.313884673146868964, 1.307128989027353860, 1.300363230327433728,
-     1.293586693733517645, 1.286798664489786415, 1.279998415710333237, 1.273185207661843732,
-     1.266358287014688333, 1.259516886060144225, 1.252660221891297887, 1.245787495544997903,
-     1.238897891102027415, 1.231990574742445110, 1.225064693752808020, 1.218119375481726552,
-     1.211153726239911244, 1.204166830140560140, 1.197157747875585931, 1.190125515422801650,
-     1.183069142678760732, 1.175987612011489825, 1.168879876726833800, 1.161744859441574240,
-     1.154581450355851802, 1.147388505416733873, 1.140164844363995789, 1.132909248648336975,
-     1.125620459211294389, 1.118297174115062909, 1.110938046009249502, 1.103541679420268151,
-     1.096106627847603487, 1.088631390649514197, 1.081114409698889389, 1.073554065787871714,
-     1.065948674757506653, 1.058296483326006454, 1.050595664586207123, 1.042844313139370538,
-     1.035040439828605274, 1.027181966030751292, 1.019266717460529215, 1.011292417434978441,
-     1.003256679539591412, 0.995156999629943084, 0.986990747093846266, 0.978755155288937750,
-     0.970447311058864615, 0.962064143217605250, 0.953602409875572654, 0.945058684462571130,
-     0.936429340280896860, 0.927710533396234771, 0.918898183643734989, 0.909987953490768997,
-     0.900975224455174528, 0.891855070726792376, 0.882622229578910122, 0.873271068082494550,
-     0.863795545546826915, 0.854189171001560554, 0.844444954902423661, 0.834555354079518752,
-     0.824512208745288633, 0.814306670128064347, 0.803929116982664893, 0.793369058833152785,
-     0.782615023299588763, 0.771654424216739354, 0.760473406422083165, 0.749056662009581653,
-     0.737387211425838629, 0.725446140901303549, 0.713212285182022732, 0.700661841097584448,
-     0.687767892786257717, 0.674499822827436479, 0.660822574234205984, 0.646695714884388928,
-     0.632072236375024632, 0.616896989996235545, 0.601104617743940417, 0.584616766093722262,
-     0.567338257040473026, 0.549151702313026790, 0.529909720646495108, 0.509423329585933393,
-     0.487443966121754335, 0.463634336771763245, 0.437518402186662658, 0.408389134588000746,
-     0.375121332850465727, 0.335737519180459465, 0.286174591747260509, 0.215241895913273806,
-     0.000000000000000000];
-pub static ZIG_NORM_F: [f64, .. 257] =
-    [0.000477467764586655, 0.001260285930498598, 0.002609072746106363, 0.004037972593371872,
-     0.005522403299264754, 0.007050875471392110, 0.008616582769422917, 0.010214971439731100,
-     0.011842757857943104, 0.013497450601780807, 0.015177088307982072, 0.016880083152595839,
-     0.018605121275783350, 0.020351096230109354, 0.022117062707379922, 0.023902203305873237,
-     0.025705804008632656, 0.027527235669693315, 0.029365939758230111, 0.031221417192023690,
-     0.033093219458688698, 0.034980941461833073, 0.036884215688691151, 0.038802707404656918,
-     0.040736110656078753, 0.042684144916619378, 0.044646552251446536, 0.046623094902089664,
-     0.048613553216035145, 0.050617723861121788, 0.052635418276973649, 0.054666461325077916,
-     0.056710690106399467, 0.058767952921137984, 0.060838108349751806, 0.062921024437977854,
-     0.065016577971470438, 0.067124653828023989, 0.069245144397250269, 0.071377949059141965,
-     0.073522973714240991, 0.075680130359194964, 0.077849336702372207, 0.080030515814947509,
-     0.082223595813495684, 0.084428509570654661, 0.086645194450867782, 0.088873592068594229,
-     0.091113648066700734, 0.093365311913026619, 0.095628536713353335, 0.097903279039215627,
-     0.100189498769172020, 0.102487158942306270, 0.104796225622867056, 0.107116667775072880,
-     0.109448457147210021, 0.111791568164245583, 0.114145977828255210, 0.116511665626037014,
-     0.118888613443345698, 0.121276805485235437, 0.123676228202051403, 0.126086870220650349,
-     0.128508722280473636, 0.130941777174128166, 0.133386029692162844, 0.135841476571757352,
-     0.138308116449064322, 0.140785949814968309, 0.143274978974047118, 0.145775208006537926,
-     0.148286642733128721, 0.150809290682410169, 0.153343161060837674, 0.155888264725064563,
-     0.158444614156520225, 0.161012223438117663, 0.163591108232982951, 0.166181285765110071,
-     0.168782774801850333, 0.171395595638155623, 0.174019770082499359, 0.176655321444406654,
-     0.179302274523530397, 0.181960655600216487, 0.184630492427504539, 0.187311814224516926,
-     0.190004651671193070, 0.192709036904328807, 0.195425003514885592, 0.198152586546538112,
-     0.200891822495431333, 0.203642749311121501, 0.206405406398679298, 0.209179834621935651,
-     0.211966076307852941, 0.214764175252008499, 0.217574176725178370, 0.220396127481011589,
-     0.223230075764789593, 0.226076071323264877, 0.228934165415577484, 0.231804410825248525,
-     0.234686861873252689, 0.237581574432173676, 0.240488605941449107, 0.243408015423711988,
-     0.246339863502238771, 0.249284212419516704, 0.252241126056943765, 0.255210669955677150,
-     0.258192911338648023, 0.261187919133763713, 0.264195763998317568, 0.267216518344631837,
-     0.270250256366959984, 0.273297054069675804, 0.276356989296781264, 0.279430141762765316,
-     0.282516593084849388, 0.285616426816658109, 0.288729728483353931, 0.291856585618280984,
-     0.294997087801162572, 0.298151326697901342, 0.301319396102034120, 0.304501391977896274,
-     0.307697412505553769, 0.310907558127563710, 0.314131931597630143, 0.317370638031222396,
-     0.320623784958230129, 0.323891482377732021, 0.327173842814958593, 0.330470981380537099,
-     0.333783015832108509, 0.337110066638412809, 0.340452257045945450, 0.343809713148291340,
-     0.347182563958251478, 0.350570941482881204, 0.353974980801569250, 0.357394820147290515,
-     0.360830600991175754, 0.364282468130549597, 0.367750569780596226, 0.371235057669821344,
-     0.374736087139491414, 0.378253817247238111, 0.381788410875031348, 0.385340034841733958,
-     0.388908860020464597, 0.392495061461010764, 0.396098818517547080, 0.399720314981931668,
-     0.403359739222868885, 0.407017284331247953, 0.410693148271983222, 0.414387534042706784,
-     0.418100649839684591, 0.421832709231353298, 0.425583931339900579, 0.429354541031341519,
-     0.433144769114574058, 0.436954852549929273, 0.440785034667769915, 0.444635565397727750,
-     0.448506701509214067, 0.452398706863882505, 0.456311852680773566, 0.460246417814923481,
-     0.464202689050278838, 0.468180961407822172, 0.472181538469883255, 0.476204732721683788,
-     0.480250865911249714, 0.484320269428911598, 0.488413284707712059, 0.492530263646148658,
-     0.496671569054796314, 0.500837575128482149, 0.505028667945828791, 0.509245245998136142,
-     0.513487720749743026, 0.517756517232200619, 0.522052074674794864, 0.526374847174186700,
-     0.530725304406193921, 0.535103932383019565, 0.539511234259544614, 0.543947731192649941,
-     0.548413963257921133, 0.552910490428519918, 0.557437893621486324, 0.561996775817277916,
-     0.566587763258951771, 0.571211506738074970, 0.575868682975210544, 0.580559996103683473,
-     0.585286179266300333, 0.590047996335791969, 0.594846243770991268, 0.599681752622167719,
-     0.604555390700549533, 0.609468064928895381, 0.614420723892076803, 0.619414360609039205,
-     0.624450015550274240, 0.629528779928128279, 0.634651799290960050, 0.639820277456438991,
-     0.645035480824251883, 0.650298743114294586, 0.655611470583224665, 0.660975147780241357,
-     0.666391343912380640, 0.671861719900766374, 0.677388036222513090, 0.682972161648791376,
-     0.688616083008527058, 0.694321916130032579, 0.700091918140490099, 0.705928501336797409,
-     0.711834248882358467, 0.717811932634901395, 0.723864533472881599, 0.729995264565802437,
-     0.736207598131266683, 0.742505296344636245, 0.748892447223726720, 0.755373506511754500,
-     0.761953346841546475, 0.768637315803334831, 0.775431304986138326, 0.782341832659861902,
-     0.789376143571198563, 0.796542330428254619, 0.803849483176389490, 0.811307874318219935,
-     0.818929191609414797, 0.826726833952094231, 0.834716292992930375, 0.842915653118441077,
-     0.851346258465123684, 0.860033621203008636, 0.869008688043793165, 0.878309655816146839,
-     0.887984660763399880, 0.898095921906304051, 0.908726440060562912, 0.919991505048360247,
-     0.932060075968990209, 0.945198953453078028, 0.959879091812415930, 0.977101701282731328,
-     1.000000000000000000];
-pub static ZIG_EXP_R: f64 = 7.697117470131050077;
-pub static ZIG_EXP_X: [f64, .. 257] =
-    [8.697117470131052741, 7.697117470131050077, 6.941033629377212577, 6.478378493832569696,
-     6.144164665772472667, 5.882144315795399869, 5.666410167454033697, 5.482890627526062488,
-     5.323090505754398016, 5.181487281301500047, 5.054288489981304089, 4.938777085901250530,
-     4.832939741025112035, 4.735242996601741083, 4.644491885420085175, 4.559737061707351380,
-     4.480211746528421912, 4.405287693473573185, 4.334443680317273007, 4.267242480277365857,
-     4.203313713735184365, 4.142340865664051464, 4.084051310408297830, 4.028208544647936762,
-     3.974606066673788796, 3.923062500135489739, 3.873417670399509127, 3.825529418522336744,
-     3.779270992411667862, 3.734528894039797375, 3.691201090237418825, 3.649195515760853770,
-     3.608428813128909507, 3.568825265648337020, 3.530315889129343354, 3.492837654774059608,
-     3.456332821132760191, 3.420748357251119920, 3.386035442460300970, 3.352149030900109405,
-     3.319047470970748037, 3.286692171599068679, 3.255047308570449882, 3.224079565286264160,
-     3.193757903212240290, 3.164053358025972873, 3.134938858084440394, 3.106389062339824481,
-     3.078380215254090224, 3.050890016615455114, 3.023897504455676621, 2.997382949516130601,
-     2.971327759921089662, 2.945714394895045718, 2.920526286512740821, 2.895747768600141825,
-     2.871364012015536371, 2.847360965635188812, 2.823725302450035279, 2.800444370250737780,
-     2.777506146439756574, 2.754899196562344610, 2.732612636194700073, 2.710636095867928752,
-     2.688959688741803689, 2.667573980773266573, 2.646469963151809157, 2.625639026797788489,
-     2.605072938740835564, 2.584763820214140750, 2.564704126316905253, 2.544886627111869970,
-     2.525304390037828028, 2.505950763528594027, 2.486819361740209455, 2.467904050297364815,
-     2.449198932978249754, 2.430698339264419694, 2.412396812688870629, 2.394289099921457886,
-     2.376370140536140596, 2.358635057409337321, 2.341079147703034380, 2.323697874390196372,
-     2.306486858283579799, 2.289441870532269441, 2.272558825553154804, 2.255833774367219213,
-     2.239262898312909034, 2.222842503111036816, 2.206569013257663858, 2.190438966723220027,
-     2.174449009937774679, 2.158595893043885994, 2.142876465399842001, 2.127287671317368289,
-     2.111826546019042183, 2.096490211801715020, 2.081275874393225145, 2.066180819490575526,
-     2.051202409468584786, 2.036338080248769611, 2.021585338318926173, 2.006941757894518563,
-     1.992404978213576650, 1.977972700957360441, 1.963642687789548313, 1.949412758007184943,
-     1.935280786297051359, 1.921244700591528076, 1.907302480018387536, 1.893452152939308242,
-     1.879691795072211180, 1.866019527692827973, 1.852433515911175554, 1.838931967018879954,
-     1.825513128903519799, 1.812175288526390649, 1.798916770460290859, 1.785735935484126014,
-     1.772631179231305643, 1.759600930889074766, 1.746643651946074405, 1.733757834985571566,
-     1.720942002521935299, 1.708194705878057773, 1.695514524101537912, 1.682900062917553896,
-     1.670349953716452118, 1.657862852574172763, 1.645437439303723659, 1.633072416535991334,
-     1.620766508828257901, 1.608518461798858379, 1.596327041286483395, 1.584191032532688892,
-     1.572109239386229707, 1.560080483527888084, 1.548103603714513499, 1.536177455041032092,
-     1.524300908219226258, 1.512472848872117082, 1.500692176842816750, 1.488957805516746058,
-     1.477268661156133867, 1.465623682245745352, 1.454021818848793446, 1.442462031972012504,
-     1.430943292938879674, 1.419464582769983219, 1.408024891569535697, 1.396623217917042137,
-     1.385258568263121992, 1.373929956328490576, 1.362636402505086775, 1.351376933258335189,
-     1.340150580529504643, 1.328956381137116560, 1.317793376176324749, 1.306660610415174117,
-     1.295557131686601027, 1.284481990275012642, 1.273434238296241139, 1.262412929069615330,
-     1.251417116480852521, 1.240445854334406572, 1.229498195693849105, 1.218573192208790124,
-     1.207669893426761121, 1.196787346088403092, 1.185924593404202199, 1.175080674310911677,
-     1.164254622705678921, 1.153445466655774743, 1.142652227581672841, 1.131873919411078511,
-     1.121109547701330200, 1.110358108727411031, 1.099618588532597308, 1.088889961938546813,
-     1.078171191511372307, 1.067461226479967662, 1.056759001602551429, 1.046063435977044209,
-     1.035373431790528542, 1.024687873002617211, 1.014005623957096480, 1.003325527915696735,
-     0.992646405507275897, 0.981967053085062602, 0.971286240983903260, 0.960602711668666509,
-     0.949915177764075969, 0.939222319955262286, 0.928522784747210395, 0.917815182070044311,
-     0.907098082715690257, 0.896370015589889935, 0.885629464761751528, 0.874874866291025066,
-     0.864104604811004484, 0.853317009842373353, 0.842510351810368485, 0.831682837734273206,
-     0.820832606554411814, 0.809957724057418282, 0.799056177355487174, 0.788125868869492430,
-     0.777164609759129710, 0.766170112735434672, 0.755139984181982249, 0.744071715500508102,
-     0.732962673584365398, 0.721810090308756203, 0.710611050909655040, 0.699362481103231959,
-     0.688061132773747808, 0.676703568029522584, 0.665286141392677943, 0.653804979847664947,
-     0.642255960424536365, 0.630634684933490286, 0.618936451394876075, 0.607156221620300030,
-     0.595288584291502887, 0.583327712748769489, 0.571267316532588332, 0.559100585511540626,
-     0.546820125163310577, 0.534417881237165604, 0.521885051592135052, 0.509211982443654398,
-     0.496388045518671162, 0.483401491653461857, 0.470239275082169006, 0.456886840931420235,
-     0.443327866073552401, 0.429543940225410703, 0.415514169600356364, 0.401214678896277765,
-     0.386617977941119573, 0.371692145329917234, 0.356399760258393816, 0.340696481064849122,
-     0.324529117016909452, 0.307832954674932158, 0.290527955491230394, 0.272513185478464703,
-     0.253658363385912022, 0.233790483059674731, 0.212671510630966620, 0.189958689622431842,
-     0.165127622564187282, 0.137304980940012589, 0.104838507565818778, 0.063852163815001570,
-     0.000000000000000000];
-pub static ZIG_EXP_F: [f64, .. 257] =
-    [0.000167066692307963, 0.000454134353841497, 0.000967269282327174, 0.001536299780301573,
-     0.002145967743718907, 0.002788798793574076, 0.003460264777836904, 0.004157295120833797,
-     0.004877655983542396, 0.005619642207205489, 0.006381905937319183, 0.007163353183634991,
-     0.007963077438017043, 0.008780314985808977, 0.009614413642502212, 0.010464810181029981,
-     0.011331013597834600, 0.012212592426255378, 0.013109164931254991, 0.014020391403181943,
-     0.014945968011691148, 0.015885621839973156, 0.016839106826039941, 0.017806200410911355,
-     0.018786700744696024, 0.019780424338009740, 0.020787204072578114, 0.021806887504283581,
-     0.022839335406385240, 0.023884420511558174, 0.024942026419731787, 0.026012046645134221,
-     0.027094383780955803, 0.028188948763978646, 0.029295660224637411, 0.030414443910466622,
-     0.031545232172893622, 0.032687963508959555, 0.033842582150874358, 0.035009037697397431,
-     0.036187284781931443, 0.037377282772959382, 0.038578995503074871, 0.039792391023374139,
-     0.041017441380414840, 0.042254122413316254, 0.043502413568888197, 0.044762297732943289,
-     0.046033761076175184, 0.047316792913181561, 0.048611385573379504, 0.049917534282706379,
-     0.051235237055126281, 0.052564494593071685, 0.053905310196046080, 0.055257689676697030,
-     0.056621641283742870, 0.057997175631200659, 0.059384305633420280, 0.060783046445479660,
-     0.062193415408541036, 0.063615431999807376, 0.065049117786753805, 0.066494496385339816,
-     0.067951593421936643, 0.069420436498728783, 0.070901055162371843, 0.072393480875708752,
-     0.073897746992364746, 0.075413888734058410, 0.076941943170480517, 0.078481949201606435,
-     0.080033947542319905, 0.081597980709237419, 0.083174093009632397, 0.084762330532368146,
-     0.086362741140756927, 0.087975374467270231, 0.089600281910032886, 0.091237516631040197,
-     0.092887133556043569, 0.094549189376055873, 0.096223742550432825, 0.097910853311492213,
-     0.099610583670637132, 0.101322997425953631, 0.103048160171257702, 0.104786139306570145,
-     0.106537004050001632, 0.108300825451033755, 0.110077676405185357, 0.111867631670056283,
-     0.113670767882744286, 0.115487163578633506, 0.117316899211555525, 0.119160057175327641,
-     0.121016721826674792, 0.122886979509545108, 0.124770918580830933, 0.126668629437510671,
-     0.128580204545228199, 0.130505738468330773, 0.132445327901387494, 0.134399071702213602,
-     0.136367070926428829, 0.138349428863580176, 0.140346251074862399, 0.142357645432472146,
-     0.144383722160634720, 0.146424593878344889, 0.148480375643866735, 0.150551185001039839,
-     0.152637142027442801, 0.154738369384468027, 0.156854992369365148, 0.158987138969314129,
-     0.161134939917591952, 0.163298528751901734, 0.165478041874935922, 0.167673618617250081,
-     0.169885401302527550, 0.172113535315319977, 0.174358169171353411, 0.176619454590494829,
-     0.178897546572478278, 0.181192603475496261, 0.183504787097767436, 0.185834262762197083,
-     0.188181199404254262, 0.190545769663195363, 0.192928149976771296, 0.195328520679563189,
-     0.197747066105098818, 0.200183974691911210, 0.202639439093708962, 0.205113656293837654,
-     0.207606827724221982, 0.210119159388988230, 0.212650861992978224, 0.215202151075378628,
-     0.217773247148700472, 0.220364375843359439, 0.222975768058120111, 0.225607660116683956,
-     0.228260293930716618, 0.230933917169627356, 0.233628783437433291, 0.236345152457059560,
-     0.239083290262449094, 0.241843469398877131, 0.244625969131892024, 0.247431075665327543,
-     0.250259082368862240, 0.253110290015629402, 0.255985007030415324, 0.258883549749016173,
-     0.261806242689362922, 0.264753418835062149, 0.267725419932044739, 0.270722596799059967,
-     0.273745309652802915, 0.276793928448517301, 0.279868833236972869, 0.282970414538780746,
-     0.286099073737076826, 0.289255223489677693, 0.292439288161892630, 0.295651704281261252,
-     0.298892921015581847, 0.302163400675693528, 0.305463619244590256, 0.308794066934560185,
-     0.312155248774179606, 0.315547685227128949, 0.318971912844957239, 0.322428484956089223,
-     0.325917972393556354, 0.329440964264136438, 0.332998068761809096, 0.336589914028677717,
-     0.340217149066780189, 0.343880444704502575, 0.347580494621637148, 0.351318016437483449,
-     0.355093752866787626, 0.358908472948750001, 0.362762973354817997, 0.366658079781514379,
-     0.370594648435146223, 0.374573567615902381, 0.378595759409581067, 0.382662181496010056,
-     0.386773829084137932, 0.390931736984797384, 0.395136981833290435, 0.399390684475231350,
-     0.403694012530530555, 0.408048183152032673, 0.412454465997161457, 0.416914186433003209,
-     0.421428728997616908, 0.425999541143034677, 0.430628137288459167, 0.435316103215636907,
-     0.440065100842354173, 0.444876873414548846, 0.449753251162755330, 0.454696157474615836,
-     0.459707615642138023, 0.464789756250426511, 0.469944825283960310, 0.475175193037377708,
-     0.480483363930454543, 0.485871987341885248, 0.491343869594032867, 0.496901987241549881,
-     0.502549501841348056, 0.508289776410643213, 0.514126393814748894, 0.520063177368233931,
-     0.526104213983620062, 0.532253880263043655, 0.538516872002862246, 0.544898237672440056,
-     0.551403416540641733, 0.558038282262587892, 0.564809192912400615, 0.571723048664826150,
-     0.578787358602845359, 0.586010318477268366, 0.593400901691733762, 0.600968966365232560,
-     0.608725382079622346, 0.616682180915207878, 0.624852738703666200, 0.633251994214366398,
-     0.641896716427266423, 0.650805833414571433, 0.660000841079000145, 0.669506316731925177,
-     0.679350572264765806, 0.689566496117078431, 0.700192655082788606, 0.711274760805076456,
-     0.722867659593572465, 0.735038092431424039, 0.747868621985195658, 0.761463388849896838,
-     0.775956852040116218, 0.791527636972496285, 0.808421651523009044, 0.826993296643051101,
-     0.847785500623990496, 0.871704332381204705, 0.900469929925747703, 0.938143680862176477,
-     1.000000000000000000];
diff --git a/src/libstd/rand/isaac.rs b/src/libstd/rand/isaac.rs
deleted file mode 100644 (file)
index 9871207..0000000
+++ /dev/null
@@ -1,535 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The ISAAC random number generator.
-
-use rand::{Rng, SeedableRng, OSRng};
-use iter::{Iterator, range, range_step, Repeat};
-use option::{None, Some};
-use vec::{raw, MutableVector, ImmutableVector};
-use mem;
-
-static RAND_SIZE_LEN: u32 = 8;
-static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
-
-/// A random number generator that uses the ISAAC algorithm[1].
-///
-/// The ISAAC algorithm is generally accepted as suitable for
-/// cryptographic purposes, but this implementation has not be
-/// verified as such. Prefer a generator like `OSRng` that defers to
-/// the operating system for cases that need high security.
-///
-/// [1]: Bob Jenkins, [*ISAAC: A fast cryptographic random number
-/// generator*](http://www.burtleburtle.net/bob/rand/isaacafa.html)
-pub struct IsaacRng {
-    priv cnt: u32,
-    priv rsl: [u32, .. RAND_SIZE],
-    priv mem: [u32, .. RAND_SIZE],
-    priv a: u32,
-    priv b: u32,
-    priv c: u32
-}
-static EMPTY: IsaacRng = IsaacRng {
-    cnt: 0,
-    rsl: [0, .. RAND_SIZE],
-    mem: [0, .. RAND_SIZE],
-    a: 0, b: 0, c: 0
-};
-
-impl IsaacRng {
-    /// Create an ISAAC random number generator with a random seed.
-    pub fn new() -> IsaacRng {
-        let mut rng = EMPTY;
-
-        unsafe {
-            let ptr = rng.rsl.as_mut_ptr();
-
-            raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl), |slice| {
-                OSRng::new().fill_bytes(slice);
-            })
-        }
-
-        rng.init(true);
-        rng
-    }
-
-    /// Create an ISAAC random number generator using the default
-    /// fixed seed.
-    pub fn new_unseeded() -> IsaacRng {
-        let mut rng = EMPTY;
-        rng.init(false);
-        rng
-    }
-
-    /// Initialises `self`. If `use_rsl` is true, then use the current value
-    /// of `rsl` as a seed, otherwise construct one algorithmically (not
-    /// randomly).
-    fn init(&mut self, use_rsl: bool) {
-        let mut a = 0x9e3779b9;
-        let mut b = a;
-        let mut c = a;
-        let mut d = a;
-        let mut e = a;
-        let mut f = a;
-        let mut g = a;
-        let mut h = a;
-
-        macro_rules! mix(
-            () => {{
-                a^=b<<11; d+=a; b+=c;
-                b^=c>>2;  e+=b; c+=d;
-                c^=d<<8;  f+=c; d+=e;
-                d^=e>>16; g+=d; e+=f;
-                e^=f<<10; h+=e; f+=g;
-                f^=g>>4;  a+=f; g+=h;
-                g^=h<<8;  b+=g; h+=a;
-                h^=a>>9;  c+=h; a+=b;
-            }}
-        );
-
-        for _ in range(0, 4) { mix!(); }
-
-        if use_rsl {
-            macro_rules! memloop (
-                ($arr:expr) => {{
-                    for i in range_step(0u32, RAND_SIZE, 8) {
-                        a+=$arr[i  ]; b+=$arr[i+1];
-                        c+=$arr[i+2]; d+=$arr[i+3];
-                        e+=$arr[i+4]; f+=$arr[i+5];
-                        g+=$arr[i+6]; h+=$arr[i+7];
-                        mix!();
-                        self.mem[i  ]=a; self.mem[i+1]=b;
-                        self.mem[i+2]=c; self.mem[i+3]=d;
-                        self.mem[i+4]=e; self.mem[i+5]=f;
-                        self.mem[i+6]=g; self.mem[i+7]=h;
-                    }
-                }}
-            );
-
-            memloop!(self.rsl);
-            memloop!(self.mem);
-        } else {
-            for i in range_step(0u32, RAND_SIZE, 8) {
-                mix!();
-                self.mem[i  ]=a; self.mem[i+1]=b;
-                self.mem[i+2]=c; self.mem[i+3]=d;
-                self.mem[i+4]=e; self.mem[i+5]=f;
-                self.mem[i+6]=g; self.mem[i+7]=h;
-            }
-        }
-
-        self.isaac();
-    }
-
-    /// Refills the output buffer (`self.rsl`)
-    #[inline]
-    fn isaac(&mut self) {
-        self.c += 1;
-        // abbreviations
-        let mut a = self.a;
-        let mut b = self.b + self.c;
-
-        static MIDPOINT: uint = RAND_SIZE as uint / 2;
-
-        macro_rules! ind (($x:expr) => {
-            self.mem[($x >> 2) & (RAND_SIZE - 1)]
-        });
-        macro_rules! rngstep(
-            ($j:expr, $shift:expr) => {{
-                let base = $j;
-                let mix = if $shift < 0 {
-                    a >> -$shift as uint
-                } else {
-                    a << $shift as uint
-                };
-
-                let x = self.mem[base  + mr_offset];
-                a = (a ^ mix) + self.mem[base + m2_offset];
-                let y = ind!(x) + a + b;
-                self.mem[base + mr_offset] = y;
-
-                b = ind!(y >> RAND_SIZE_LEN) + x;
-                self.rsl[base + mr_offset] = b;
-            }}
-        );
-
-        let r = [(0, MIDPOINT), (MIDPOINT, 0)];
-        for &(mr_offset, m2_offset) in r.iter() {
-            for i in range_step(0u, MIDPOINT, 4) {
-                rngstep!(i + 0, 13);
-                rngstep!(i + 1, -6);
-                rngstep!(i + 2, 2);
-                rngstep!(i + 3, -16);
-            }
-        }
-
-        self.a = a;
-        self.b = b;
-        self.cnt = RAND_SIZE;
-    }
-}
-
-impl Rng for IsaacRng {
-    #[inline]
-    fn next_u32(&mut self) -> u32 {
-        if self.cnt == 0 {
-            // make some more numbers
-            self.isaac();
-        }
-        self.cnt -= 1;
-        self.rsl[self.cnt]
-    }
-}
-
-impl<'a> SeedableRng<&'a [u32]> for IsaacRng {
-    fn reseed(&mut self, seed: &'a [u32]) {
-        // make the seed into [seed[0], seed[1], ..., seed[seed.len()
-        // - 1], 0, 0, ...], to fill rng.rsl.
-        let seed_iter = seed.iter().map(|&x| x).chain(Repeat::new(0u32));
-
-        for (rsl_elem, seed_elem) in self.rsl.mut_iter().zip(seed_iter) {
-            *rsl_elem = seed_elem;
-        }
-        self.cnt = 0;
-        self.a = 0;
-        self.b = 0;
-        self.c = 0;
-
-        self.init(true);
-    }
-
-    /// Create an ISAAC random number generator with a seed. This can
-    /// be any length, although the maximum number of elements used is
-    /// 256 and any more will be silently ignored. A generator
-    /// constructed with a given seed will generate the same sequence
-    /// of values as all other generators constructed with that seed.
-    fn from_seed(seed: &'a [u32]) -> IsaacRng {
-        let mut rng = EMPTY;
-        rng.reseed(seed);
-        rng
-    }
-}
-
-
-static RAND_SIZE_64_LEN: uint = 8;
-static RAND_SIZE_64: uint = 1 << RAND_SIZE_64_LEN;
-
-/// A random number generator that uses ISAAC-64[1], the 64-bit
-/// variant of the ISAAC algorithm.
-///
-/// The ISAAC algorithm is generally accepted as suitable for
-/// cryptographic purposes, but this implementation has not be
-/// verified as such. Prefer a generator like `OSRng` that defers to
-/// the operating system for cases that need high security.
-///
-/// [1]: Bob Jenkins, [*ISAAC: A fast cryptographic random number
-/// generator*](http://www.burtleburtle.net/bob/rand/isaacafa.html)
-pub struct Isaac64Rng {
-    priv cnt: uint,
-    priv rsl: [u64, .. RAND_SIZE_64],
-    priv mem: [u64, .. RAND_SIZE_64],
-    priv a: u64,
-    priv b: u64,
-    priv c: u64,
-}
-
-static EMPTY_64: Isaac64Rng = Isaac64Rng {
-    cnt: 0,
-    rsl: [0, .. RAND_SIZE_64],
-    mem: [0, .. RAND_SIZE_64],
-    a: 0, b: 0, c: 0,
-};
-
-impl Isaac64Rng {
-    /// Create a 64-bit ISAAC random number generator with a random
-    /// seed.
-    pub fn new() -> Isaac64Rng {
-        let mut rng = EMPTY_64;
-
-        unsafe {
-            let ptr = rng.rsl.as_mut_ptr();
-
-            raw::mut_buf_as_slice(ptr as *mut u8, mem::size_of_val(&rng.rsl), |slice| {
-                OSRng::new().fill_bytes(slice);
-            })
-        }
-
-        rng.init(true);
-        rng
-    }
-
-    /// Create a 64-bit ISAAC random number generator using the
-    /// default fixed seed.
-    pub fn new_unseeded() -> Isaac64Rng {
-        let mut rng = EMPTY_64;
-        rng.init(false);
-        rng
-    }
-
-    /// Initialises `self`. If `use_rsl` is true, then use the current value
-    /// of `rsl` as a seed, otherwise construct one algorithmically (not
-    /// randomly).
-    fn init(&mut self, use_rsl: bool) {
-        macro_rules! init (
-            ($var:ident) => (
-                let mut $var = 0x9e3779b97f4a7c13;
-            )
-        );
-        init!(a); init!(b); init!(c); init!(d);
-        init!(e); init!(f); init!(g); init!(h);
-
-        macro_rules! mix(
-            () => {{
-                a-=e; f^=h>>9;  h+=a;
-                b-=f; g^=a<<9;  a+=b;
-                c-=g; h^=b>>23; b+=c;
-                d-=h; a^=c<<15; c+=d;
-                e-=a; b^=d>>14; d+=e;
-                f-=b; c^=e<<20; e+=f;
-                g-=c; d^=f>>17; f+=g;
-                h-=d; e^=g<<14; g+=h;
-            }}
-        );
-
-        for _ in range(0, 4) { mix!(); }
-        if use_rsl {
-            macro_rules! memloop (
-                ($arr:expr) => {{
-                    for i in range(0, RAND_SIZE_64 / 8).map(|i| i * 8) {
-                        a+=$arr[i  ]; b+=$arr[i+1];
-                        c+=$arr[i+2]; d+=$arr[i+3];
-                        e+=$arr[i+4]; f+=$arr[i+5];
-                        g+=$arr[i+6]; h+=$arr[i+7];
-                        mix!();
-                        self.mem[i  ]=a; self.mem[i+1]=b;
-                        self.mem[i+2]=c; self.mem[i+3]=d;
-                        self.mem[i+4]=e; self.mem[i+5]=f;
-                        self.mem[i+6]=g; self.mem[i+7]=h;
-                    }
-                }}
-            );
-
-            memloop!(self.rsl);
-            memloop!(self.mem);
-        } else {
-            for i in range(0, RAND_SIZE_64 / 8).map(|i| i * 8) {
-                mix!();
-                self.mem[i  ]=a; self.mem[i+1]=b;
-                self.mem[i+2]=c; self.mem[i+3]=d;
-                self.mem[i+4]=e; self.mem[i+5]=f;
-                self.mem[i+6]=g; self.mem[i+7]=h;
-            }
-        }
-
-        self.isaac64();
-    }
-
-    /// Refills the output buffer (`self.rsl`)
-    fn isaac64(&mut self) {
-        self.c += 1;
-        // abbreviations
-        let mut a = self.a;
-        let mut b = self.b + self.c;
-        static MIDPOINT: uint =  RAND_SIZE_64 / 2;
-        static MP_VEC: [(uint, uint), .. 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
-        macro_rules! ind (
-            ($x:expr) => {
-                *self.mem.unsafe_ref(($x as uint >> 3) & (RAND_SIZE_64 - 1))
-            }
-        );
-        macro_rules! rngstep(
-            ($j:expr, $shift:expr) => {{
-                let base = base + $j;
-                let mix = a ^ (if $shift < 0 {
-                    a >> -$shift as uint
-                } else {
-                    a << $shift as uint
-                });
-                let mix = if $j == 0 {!mix} else {mix};
-
-                unsafe {
-                    let x = *self.mem.unsafe_ref(base + mr_offset);
-                    a = mix + *self.mem.unsafe_ref(base + m2_offset);
-                    let y = ind!(x) + a + b;
-                    self.mem.unsafe_set(base + mr_offset, y);
-
-                    b = ind!(y >> RAND_SIZE_64_LEN) + x;
-                    self.rsl.unsafe_set(base + mr_offset, b);
-                }
-            }}
-        );
-
-        for &(mr_offset, m2_offset) in MP_VEC.iter() {
-            for base in range(0, MIDPOINT / 4).map(|i| i * 4) {
-                rngstep!(0, 21);
-                rngstep!(1, -5);
-                rngstep!(2, 12);
-                rngstep!(3, -33);
-            }
-        }
-
-        self.a = a;
-        self.b = b;
-        self.cnt = RAND_SIZE_64;
-    }
-}
-
-impl Rng for Isaac64Rng {
-    // FIXME #7771: having next_u32 like this should be unnecessary
-    #[inline]
-    fn next_u32(&mut self) -> u32 {
-        self.next_u64() as u32
-    }
-
-    #[inline]
-    fn next_u64(&mut self) -> u64 {
-        if self.cnt == 0 {
-            // make some more numbers
-            self.isaac64();
-        }
-        self.cnt -= 1;
-        unsafe { *self.rsl.unsafe_ref(self.cnt) }
-    }
-}
-
-impl<'a> SeedableRng<&'a [u64]> for Isaac64Rng {
-    fn reseed(&mut self, seed: &'a [u64]) {
-        // make the seed into [seed[0], seed[1], ..., seed[seed.len()
-        // - 1], 0, 0, ...], to fill rng.rsl.
-        let seed_iter = seed.iter().map(|&x| x).chain(Repeat::new(0u64));
-
-        for (rsl_elem, seed_elem) in self.rsl.mut_iter().zip(seed_iter) {
-            *rsl_elem = seed_elem;
-        }
-        self.cnt = 0;
-        self.a = 0;
-        self.b = 0;
-        self.c = 0;
-
-        self.init(true);
-    }
-
-    /// Create an ISAAC random number generator with a seed. This can
-    /// be any length, although the maximum number of elements used is
-    /// 256 and any more will be silently ignored. A generator
-    /// constructed with a given seed will generate the same sequence
-    /// of values as all other generators constructed with that seed.
-    fn from_seed(seed: &'a [u64]) -> Isaac64Rng {
-        let mut rng = EMPTY_64;
-        rng.reseed(seed);
-        rng
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::*;
-    use rand::{Rng, SeedableRng, OSRng};
-    use prelude::*;
-    use vec;
-
-    #[test]
-    fn test_rng_32_rand_seeded() {
-        let s = OSRng::new().gen_vec::<u32>(256);
-        let mut ra: IsaacRng = SeedableRng::from_seed(s.as_slice());
-        let mut rb: IsaacRng = SeedableRng::from_seed(s.as_slice());
-        assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
-    }
-    #[test]
-    fn test_rng_64_rand_seeded() {
-        let s = OSRng::new().gen_vec::<u64>(256);
-        let mut ra: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
-        let mut rb: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
-        assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
-    }
-
-    #[test]
-    fn test_rng_32_seeded() {
-        let seed = &[1, 23, 456, 7890, 12345];
-        let mut ra: IsaacRng = SeedableRng::from_seed(seed);
-        let mut rb: IsaacRng = SeedableRng::from_seed(seed);
-        assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
-    }
-    #[test]
-    fn test_rng_64_seeded() {
-        let seed = &[1, 23, 456, 7890, 12345];
-        let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
-        let mut rb: Isaac64Rng = SeedableRng::from_seed(seed);
-        assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
-    }
-
-    #[test]
-    fn test_rng_32_reseed() {
-        let s = OSRng::new().gen_vec::<u32>(256);
-        let mut r: IsaacRng = SeedableRng::from_seed(s.as_slice());
-        let string1 = r.gen_ascii_str(100);
-
-        r.reseed(s);
-
-        let string2 = r.gen_ascii_str(100);
-        assert_eq!(string1, string2);
-    }
-    #[test]
-    fn test_rng_64_reseed() {
-        let s = OSRng::new().gen_vec::<u64>(256);
-        let mut r: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
-        let string1 = r.gen_ascii_str(100);
-
-        r.reseed(s);
-
-        let string2 = r.gen_ascii_str(100);
-        assert_eq!(string1, string2);
-    }
-
-    #[test]
-    fn test_rng_32_true_values() {
-        let seed = &[1, 23, 456, 7890, 12345];
-        let mut ra: IsaacRng = SeedableRng::from_seed(seed);
-        // Regression test that isaac is actually using the above vector
-        let v = vec::from_fn(10, |_| ra.next_u32());
-        assert_eq!(v,
-                   ~[2558573138, 873787463, 263499565, 2103644246, 3595684709,
-                     4203127393, 264982119, 2765226902, 2737944514, 3900253796]);
-
-        let seed = &[12345, 67890, 54321, 9876];
-        let mut rb: IsaacRng = SeedableRng::from_seed(seed);
-        // skip forward to the 10000th number
-        for _ in range(0, 10000) { rb.next_u32(); }
-
-        let v = vec::from_fn(10, |_| rb.next_u32());
-        assert_eq!(v,
-                   ~[3676831399, 3183332890, 2834741178, 3854698763, 2717568474,
-                     1576568959, 3507990155, 179069555, 141456972, 2478885421]);
-    }
-    #[test]
-    fn test_rng_64_true_values() {
-        let seed = &[1, 23, 456, 7890, 12345];
-        let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
-        // Regression test that isaac is actually using the above vector
-        let v = vec::from_fn(10, |_| ra.next_u64());
-        assert_eq!(v,
-                   ~[547121783600835980, 14377643087320773276, 17351601304698403469,
-                     1238879483818134882, 11952566807690396487, 13970131091560099343,
-                     4469761996653280935, 15552757044682284409, 6860251611068737823,
-                     13722198873481261842]);
-
-        let seed = &[12345, 67890, 54321, 9876];
-        let mut rb: Isaac64Rng = SeedableRng::from_seed(seed);
-        // skip forward to the 10000th number
-        for _ in range(0, 10000) { rb.next_u64(); }
-
-        let v = vec::from_fn(10, |_| rb.next_u64());
-        assert_eq!(v,
-                   ~[18143823860592706164, 8491801882678285927, 2699425367717515619,
-                     17196852593171130876, 2606123525235546165, 15790932315217671084,
-                     596345674630742204, 9947027391921273664, 11788097613744130851,
-                     10391409374914919106]);
-    }
-}
diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs
deleted file mode 100644 (file)
index 20bce8d..0000000
+++ /dev/null
@@ -1,906 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-Utilities for random number generation
-
-The key functions are `random()` and `Rng::gen()`. These are polymorphic
-and so can be used to generate any type that implements `Rand`. Type inference
-means that often a simple call to `rand::random()` or `rng.gen()` will
-suffice, but sometimes an annotation is required, e.g. `rand::random::<f64>()`.
-
-See the `distributions` submodule for sampling random numbers from
-distributions like normal and exponential.
-
-# Task-local RNG
-
-There is built-in support for a RNG associated with each task stored
-in task-local storage. This RNG can be accessed via `task_rng`, or
-used implicitly via `random`. This RNG is normally randomly seeded
-from an operating-system source of randomness, e.g. `/dev/urandom` on
-Unix systems, and will automatically reseed itself from this source
-after generating 32 KiB of random data.
-
-# Cryptographic security
-
-An application that requires random numbers for cryptographic purposes
-should prefer `OSRng`, which reads randomness from one of the source
-that the operating system provides (e.g. `/dev/urandom` on
-Unixes). The other random number generators provided by this module
-are either known to be insecure (`XorShiftRng`), or are not verified
-to be secure (`IsaacRng`, `Isaac64Rng` and `StdRng`).
-
-*Note*: on Linux, `/dev/random` is more secure than `/dev/urandom`,
-but it is a blocking RNG, and will wait until it has determined that
-it has collected enough entropy to fulfill a request for random
-data. It can be used with the `Rng` trait provided by this module by
-opening the file and passing it to `reader::ReaderRng`. Since it
-blocks, `/dev/random` should only be used to retrieve small amounts of
-randomness.
-
-# Examples
-
-```rust
-use std::rand;
-use std::rand::Rng;
-
-let mut rng = rand::rng();
-if rng.gen() { // bool
-    println!("int: {}, uint: {}", rng.gen::<int>(), rng.gen::<uint>())
-}
- ```
-
-```rust
-use std::rand;
-
-let tuple_ptr = rand::random::<~(f64, char)>();
-println!("{:?}", tuple_ptr)
- ```
-*/
-
-use cast;
-use cmp::Ord;
-use container::Container;
-use iter::{Iterator, range};
-use kinds::marker;
-use local_data;
-use prelude::*;
-use str;
-use vec;
-
-pub use self::isaac::{IsaacRng, Isaac64Rng};
-pub use self::os::OSRng;
-
-use self::distributions::{Range, IndependentSample};
-use self::distributions::range::SampleRange;
-
-pub mod distributions;
-pub mod isaac;
-pub mod os;
-pub mod reader;
-pub mod reseeding;
-mod rand_impls;
-
-/// A type that can be randomly generated using an `Rng`.
-pub trait Rand {
-    /// Generates a random instance of this type using the specified source of
-    /// randomness.
-    fn rand<R: Rng>(rng: &mut R) -> Self;
-}
-
-/// A random number generator.
-pub trait Rng {
-    /// Return the next random u32.
-    ///
-    /// This rarely needs to be called directly, prefer `r.gen()` to
-    /// `r.next_u32()`.
-    // FIXME #7771: Should be implemented in terms of next_u64
-    fn next_u32(&mut self) -> u32;
-
-    /// Return the next random u64.
-    ///
-    /// By default this is implemented in terms of `next_u32`. An
-    /// implementation of this trait must provide at least one of
-    /// these two methods. Similarly to `next_u32`, this rarely needs
-    /// to be called directly, prefer `r.gen()` to `r.next_u64()`.
-    fn next_u64(&mut self) -> u64 {
-        (self.next_u32() as u64 << 32) | (self.next_u32() as u64)
-    }
-
-    /// Fill `dest` with random data.
-    ///
-    /// This has a default implementation in terms of `next_u64` and
-    /// `next_u32`, but should be overridden by implementations that
-    /// offer a more efficient solution than just calling those
-    /// methods repeatedly.
-    ///
-    /// This method does *not* have a requirement to bear any fixed
-    /// relationship to the other methods, for example, it does *not*
-    /// have to result in the same output as progressively filling
-    /// `dest` with `self.gen::<u8>()`, and any such behaviour should
-    /// not be relied upon.
-    ///
-    /// This method should guarantee that `dest` is entirely filled
-    /// with new data, and may fail if this is impossible
-    /// (e.g. reading past the end of a file that is being used as the
-    /// source of randomness).
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::rand::{task_rng, Rng};
-    ///
-    /// let mut v = [0u8, .. 13579];
-    /// task_rng().fill_bytes(v);
-    /// println!("{:?}", v);
-    /// ```
-    fn fill_bytes(&mut self, dest: &mut [u8]) {
-        // this could, in theory, be done by transmuting dest to a
-        // [u64], but this is (1) likely to be undefined behaviour for
-        // LLVM, (2) has to be very careful about alignment concerns,
-        // (3) adds more `unsafe` that needs to be checked, (4)
-        // probably doesn't give much performance gain if
-        // optimisations are on.
-        let mut count = 0;
-        let mut num = 0;
-        for byte in dest.mut_iter() {
-            if count == 0 {
-                // we could micro-optimise here by generating a u32 if
-                // we only need a few more bytes to fill the vector
-                // (i.e. at most 4).
-                num = self.next_u64();
-                count = 8;
-            }
-
-            *byte = (num & 0xff) as u8;
-            num >>= 8;
-            count -= 1;
-        }
-    }
-
-    /// Return a random value of a `Rand` type.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::rand::{task_rng, Rng};
-    ///
-    /// let mut rng = task_rng();
-    /// let x: uint = rng.gen();
-    /// println!("{}", x);
-    /// println!("{:?}", rng.gen::<(f64, bool)>());
-    /// ```
-    #[inline(always)]
-    fn gen<T: Rand>(&mut self) -> T {
-        Rand::rand(self)
-    }
-
-    /// Return a random vector of the specified length.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::rand::{task_rng, Rng};
-    ///
-    /// let mut rng = task_rng();
-    /// let x: ~[uint] = rng.gen_vec(10);
-    /// println!("{:?}", x);
-    /// println!("{:?}", rng.gen_vec::<(f64, bool)>(5));
-    /// ```
-    fn gen_vec<T: Rand>(&mut self, len: uint) -> ~[T] {
-        vec::from_fn(len, |_| self.gen())
-    }
-
-    /// Generate a random value in the range [`low`, `high`). Fails if
-    /// `low >= high`.
-    ///
-    /// This is a convenience wrapper around
-    /// `distributions::Range`. If this function will be called
-    /// repeatedly with the same arguments, one should use `Range`, as
-    /// that will amortize the computations that allow for perfect
-    /// uniformity, as they only happen on initialization.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::rand::{task_rng, Rng};
-    ///
-    /// let mut rng = task_rng();
-    /// let n: uint = rng.gen_range(0u, 10);
-    /// println!("{}", n);
-    /// let m: f64 = rng.gen_range(-40.0, 1.3e5);
-    /// println!("{}", m);
-    /// ```
-    fn gen_range<T: Ord + SampleRange>(&mut self, low: T, high: T) -> T {
-        assert!(low < high, "Rng.gen_range called with low >= high");
-        Range::new(low, high).ind_sample(self)
-    }
-
-    /// Return a bool with a 1 in n chance of true
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::rand::{task_rng, Rng};
-    ///
-    /// let mut rng = task_rng();
-    /// println!("{:b}", rng.gen_weighted_bool(3));
-    /// ```
-    fn gen_weighted_bool(&mut self, n: uint) -> bool {
-        n == 0 || self.gen_range(0, n) == 0
-    }
-
-    /// Return a random string of the specified length composed of
-    /// A-Z,a-z,0-9.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::rand::{task_rng, Rng};
-    ///
-    /// println!("{}", task_rng().gen_ascii_str(10));
-    /// ```
-    fn gen_ascii_str(&mut self, len: uint) -> ~str {
-        static GEN_ASCII_STR_CHARSET: &'static [u8] = bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ\
-                                                             abcdefghijklmnopqrstuvwxyz\
-                                                             0123456789");
-        let mut s = str::with_capacity(len);
-        for _ in range(0, len) {
-            s.push_char(self.choose(GEN_ASCII_STR_CHARSET) as char)
-        }
-        s
-    }
-
-    /// Choose an item randomly, failing if `values` is empty.
-    fn choose<T: Clone>(&mut self, values: &[T]) -> T {
-        self.choose_option(values).expect("Rng.choose: `values` is empty").clone()
-    }
-
-    /// Choose `Some(&item)` randomly, returning `None` if values is
-    /// empty.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::rand::{task_rng, Rng};
-    ///
-    /// let choices = [1, 2, 4, 8, 16, 32];
-    /// let mut rng = task_rng();
-    /// println!("{:?}", rng.choose_option(choices));
-    /// println!("{:?}", rng.choose_option(choices.slice_to(0)));
-    /// ```
-    fn choose_option<'a, T>(&mut self, values: &'a [T]) -> Option<&'a T> {
-        if values.is_empty() {
-            None
-        } else {
-            Some(&values[self.gen_range(0u, values.len())])
-        }
-    }
-
-    /// Shuffle a vec
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::rand::{task_rng, Rng};
-    ///
-    /// println!("{:?}", task_rng().shuffle(~[1,2,3]));
-    /// ```
-    fn shuffle<T>(&mut self, values: ~[T]) -> ~[T] {
-        let mut v = values;
-        self.shuffle_mut(v);
-        v
-    }
-
-    /// Shuffle a mutable vector in place.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::rand::{task_rng, Rng};
-    ///
-    /// let mut rng = task_rng();
-    /// let mut y = [1,2,3];
-    /// rng.shuffle_mut(y);
-    /// println!("{:?}", y);
-    /// rng.shuffle_mut(y);
-    /// println!("{:?}", y);
-    /// ```
-    fn shuffle_mut<T>(&mut self, values: &mut [T]) {
-        let mut i = values.len();
-        while i >= 2u {
-            // invariant: elements with index >= i have been locked in place.
-            i -= 1u;
-            // lock element i in place.
-            values.swap(i, self.gen_range(0u, i + 1u));
-        }
-    }
-
-    /// Randomly sample up to `n` elements from an iterator.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::rand::{task_rng, Rng};
-    ///
-    /// let mut rng = task_rng();
-    /// let sample = rng.sample(range(1, 100), 5);
-    /// println!("{:?}", sample);
-    /// ```
-    fn sample<A, T: Iterator<A>>(&mut self, iter: T, n: uint) -> ~[A] {
-        let mut reservoir : ~[A] = vec::with_capacity(n);
-        for (i, elem) in iter.enumerate() {
-            if i < n {
-                reservoir.push(elem);
-                continue
-            }
-
-            let k = self.gen_range(0, i + 1);
-            if k < reservoir.len() {
-                reservoir[k] = elem
-            }
-        }
-        reservoir
-    }
-}
-
-/// A random number generator that can be explicitly seeded to produce
-/// the same stream of randomness multiple times.
-pub trait SeedableRng<Seed>: Rng {
-    /// Reseed an RNG with the given seed.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::rand::{Rng, SeedableRng, StdRng};
-    ///
-    /// let mut rng: StdRng = SeedableRng::from_seed(&[1, 2, 3, 4]);
-    /// println!("{}", rng.gen::<f64>());
-    /// rng.reseed([5, 6, 7, 8]);
-    /// println!("{}", rng.gen::<f64>());
-    /// ```
-    fn reseed(&mut self, Seed);
-
-    /// Create a new RNG with the given seed.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::rand::{Rng, SeedableRng, StdRng};
-    ///
-    /// let mut rng: StdRng = SeedableRng::from_seed(&[1, 2, 3, 4]);
-    /// println!("{}", rng.gen::<f64>());
-    /// ```
-    fn from_seed(seed: Seed) -> Self;
-}
-
-/// Create a random number generator with a default algorithm and seed.
-///
-/// It returns the strongest `Rng` algorithm currently implemented in
-/// pure Rust. If you require a specifically seeded `Rng` for
-/// consistency over time you should pick one algorithm and create the
-/// `Rng` yourself.
-///
-/// This is a very expensive operation as it has to read randomness
-/// from the operating system and use this in an expensive seeding
-/// operation. If one does not require high performance generation of
-/// random numbers, `task_rng` and/or `random` may be more
-/// appropriate.
-pub fn rng() -> StdRng {
-    StdRng::new()
-}
-
-/// The standard RNG. This is designed to be efficient on the current
-/// platform.
-#[cfg(not(target_word_size="64"))]
-pub struct StdRng { priv rng: IsaacRng }
-
-/// The standard RNG. This is designed to be efficient on the current
-/// platform.
-#[cfg(target_word_size="64")]
-pub struct StdRng { priv rng: Isaac64Rng }
-
-impl StdRng {
-    /// Create a randomly seeded instance of `StdRng`. This reads
-    /// randomness from the OS to seed the PRNG.
-    #[cfg(not(target_word_size="64"))]
-    pub fn new() -> StdRng {
-        StdRng { rng: IsaacRng::new() }
-    }
-    /// Create a randomly seeded instance of `StdRng`. This reads
-    /// randomness from the OS to seed the PRNG.
-    #[cfg(target_word_size="64")]
-    pub fn new() -> StdRng {
-        StdRng { rng: Isaac64Rng::new() }
-    }
-}
-
-impl Rng for StdRng {
-    #[inline]
-    fn next_u32(&mut self) -> u32 {
-        self.rng.next_u32()
-    }
-
-    #[inline]
-    fn next_u64(&mut self) -> u64 {
-        self.rng.next_u64()
-    }
-}
-
-impl<'a> SeedableRng<&'a [uint]> for StdRng {
-    fn reseed(&mut self, seed: &'a [uint]) {
-        // the internal RNG can just be seeded from the above
-        // randomness.
-        self.rng.reseed(unsafe {cast::transmute(seed)})
-    }
-
-    fn from_seed(seed: &'a [uint]) -> StdRng {
-        StdRng { rng: SeedableRng::from_seed(unsafe {cast::transmute(seed)}) }
-    }
-}
-
-/// Create a weak random number generator with a default algorithm and seed.
-///
-/// It returns the fastest `Rng` algorithm currently available in Rust without
-/// consideration for cryptography or security. If you require a specifically
-/// seeded `Rng` for consistency over time you should pick one algorithm and
-/// create the `Rng` yourself.
-///
-/// This will read randomness from the operating system to seed the
-/// generator.
-pub fn weak_rng() -> XorShiftRng {
-    XorShiftRng::new()
-}
-
-/// An Xorshift[1] random number
-/// generator.
-///
-/// The Xorshift algorithm is not suitable for cryptographic purposes
-/// but is very fast. If you do not know for sure that it fits your
-/// requirements, use a more secure one such as `IsaacRng` or `OSRng`.
-///
-/// [1]: Marsaglia, George (July 2003). ["Xorshift
-/// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
-/// Statistical Software*. Vol. 8 (Issue 14).
-pub struct XorShiftRng {
-    priv x: u32,
-    priv y: u32,
-    priv z: u32,
-    priv w: u32,
-}
-
-impl Rng for XorShiftRng {
-    #[inline]
-    fn next_u32(&mut self) -> u32 {
-        let x = self.x;
-        let t = x ^ (x << 11);
-        self.x = self.y;
-        self.y = self.z;
-        self.z = self.w;
-        let w = self.w;
-        self.w = w ^ (w >> 19) ^ (t ^ (t >> 8));
-        self.w
-    }
-}
-
-impl SeedableRng<[u32, .. 4]> for XorShiftRng {
-    /// Reseed an XorShiftRng. This will fail if `seed` is entirely 0.
-    fn reseed(&mut self, seed: [u32, .. 4]) {
-        assert!(!seed.iter().all(|&x| x == 0),
-                "XorShiftRng.reseed called with an all zero seed.");
-
-        self.x = seed[0];
-        self.y = seed[1];
-        self.z = seed[2];
-        self.w = seed[3];
-    }
-
-    /// Create a new XorShiftRng. This will fail if `seed` is entirely 0.
-    fn from_seed(seed: [u32, .. 4]) -> XorShiftRng {
-        assert!(!seed.iter().all(|&x| x == 0),
-                "XorShiftRng::from_seed called with an all zero seed.");
-
-        XorShiftRng {
-            x: seed[0],
-            y: seed[1],
-            z: seed[2],
-            w: seed[3]
-        }
-    }
-}
-
-impl XorShiftRng {
-    /// Create an xor shift random number generator with a random seed.
-    pub fn new() -> XorShiftRng {
-        let mut s = [0u8, ..16];
-        loop {
-            let mut r = OSRng::new();
-            r.fill_bytes(s);
-
-            if !s.iter().all(|x| *x == 0) {
-                break;
-            }
-        }
-        let s: [u32, ..4] = unsafe { cast::transmute(s) };
-        SeedableRng::from_seed(s)
-    }
-}
-
-/// Controls how the task-local RNG is reseeded.
-struct TaskRngReseeder;
-
-impl reseeding::Reseeder<StdRng> for TaskRngReseeder {
-    fn reseed(&mut self, rng: &mut StdRng) {
-        *rng = StdRng::new();
-    }
-}
-static TASK_RNG_RESEED_THRESHOLD: uint = 32_768;
-type TaskRngInner = reseeding::ReseedingRng<StdRng, TaskRngReseeder>;
-/// The task-local RNG.
-pub struct TaskRng {
-    // This points into TLS (specifically, it points to the endpoint
-    // of a ~ stored in TLS, to make it robust against TLS moving
-    // things internally) and so this struct cannot be legally
-    // transferred between tasks *and* it's unsafe to deallocate the
-    // RNG other than when a task is finished.
-    //
-    // The use of unsafe code here is OK if the invariants above are
-    // satisfied; and it allows us to avoid (unnecessarily) using a
-    // GC'd or RC'd pointer.
-    priv rng: *mut TaskRngInner,
-    priv marker: marker::NoSend,
-}
-
-// used to make space in TLS for a random number generator
-local_data_key!(TASK_RNG_KEY: ~TaskRngInner)
-
-/// Retrieve the lazily-initialized task-local random number
-/// generator, seeded by the system. Intended to be used in method
-/// chaining style, e.g. `task_rng().gen::<int>()`.
-///
-/// The RNG provided will reseed itself from the operating system
-/// after generating a certain amount of randomness.
-///
-/// The internal RNG used is platform and architecture dependent, even
-/// if the operating system random number generator is rigged to give
-/// the same sequence always. If absolute consistency is required,
-/// explicitly select an RNG, e.g. `IsaacRng` or `Isaac64Rng`.
-pub fn task_rng() -> TaskRng {
-    local_data::get_mut(TASK_RNG_KEY, |rng| match rng {
-        None => {
-            let mut rng = ~reseeding::ReseedingRng::new(StdRng::new(),
-                                                        TASK_RNG_RESEED_THRESHOLD,
-                                                        TaskRngReseeder);
-            let ptr = &mut *rng as *mut TaskRngInner;
-
-            local_data::set(TASK_RNG_KEY, rng);
-
-            TaskRng { rng: ptr, marker: marker::NoSend }
-        }
-        Some(rng) => TaskRng { rng: &mut **rng, marker: marker::NoSend }
-    })
-}
-
-impl Rng for TaskRng {
-    fn next_u32(&mut self) -> u32 {
-        unsafe { (*self.rng).next_u32() }
-    }
-
-    fn next_u64(&mut self) -> u64 {
-        unsafe { (*self.rng).next_u64() }
-    }
-
-    #[inline]
-    fn fill_bytes(&mut self, bytes: &mut [u8]) {
-        unsafe { (*self.rng).fill_bytes(bytes) }
-    }
-}
-
-/// Generate a random value using the task-local random number
-/// generator.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand::random;
-///
-/// if random() {
-///     let x = random();
-///     println!("{}", 2u * x);
-/// } else {
-///     println!("{}", random::<f64>());
-/// }
-/// ```
-#[inline]
-pub fn random<T: Rand>() -> T {
-    task_rng().gen()
-}
-
-/// A wrapper for generating floating point numbers uniformly in the
-/// open interval `(0,1)` (not including either endpoint).
-///
-/// Use `Closed01` for the closed interval `[0,1]`, and the default
-/// `Rand` implementation for `f32` and `f64` for the half-open
-/// `[0,1)`.
-///
-/// # Example
-/// ```rust,ignore
-/// use std::rand::{random, Open01};
-///
-/// let Open01(val) = random::<Open01<f32>>();
-/// println!("f32 from (0,1): {}", val);
-/// ```
-pub struct Open01<F>(F);
-
-/// A wrapper for generating floating point numbers uniformly in the
-/// closed interval `[0,1]` (including both endpoints).
-///
-/// Use `Open01` for the closed interval `(0,1)`, and the default
-/// `Rand` implementation of `f32` and `f64` for the half-open
-/// `[0,1)`.
-///
-/// # Example
-/// ```rust,ignore
-/// use std::rand::{random, Closed01};
-///
-/// let Closed01(val) = random::<Closed01<f32>>();
-/// println!("f32 from [0,1]: {}", val);
-/// ```
-pub struct Closed01<F>(F);
-
-#[cfg(test)]
-mod test {
-    use prelude::*;
-    use vec;
-    use super::*;
-
-    struct ConstRng { i: u64 }
-    impl Rng for ConstRng {
-        fn next_u32(&mut self) -> u32 { self.i as u32 }
-        fn next_u64(&mut self) -> u64 { self.i }
-
-        // no fill_bytes on purpose
-    }
-
-    #[test]
-    fn test_fill_bytes_default() {
-        let mut r = ConstRng { i: 0x11_22_33_44_55_66_77_88 };
-
-        // check every remainder mod 8, both in small and big vectors.
-        let lengths = [0, 1, 2, 3, 4, 5, 6, 7,
-                       80, 81, 82, 83, 84, 85, 86, 87];
-        for &n in lengths.iter() {
-            let mut v = vec::from_elem(n, 0u8);
-            r.fill_bytes(v);
-
-            // use this to get nicer error messages.
-            for (i, &byte) in v.iter().enumerate() {
-                if byte == 0 {
-                    fail!("byte {} of {} is zero", i, n)
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn test_gen_range() {
-        let mut r = rng();
-        for _ in range(0, 1000) {
-            let a = r.gen_range(-3i, 42);
-            assert!(a >= -3 && a < 42);
-            assert_eq!(r.gen_range(0, 1), 0);
-            assert_eq!(r.gen_range(-12, -11), -12);
-        }
-
-        for _ in range(0, 1000) {
-            let a = r.gen_range(10, 42);
-            assert!(a >= 10 && a < 42);
-            assert_eq!(r.gen_range(0, 1), 0);
-            assert_eq!(r.gen_range(3_000_000u, 3_000_001), 3_000_000);
-        }
-
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_gen_range_fail_int() {
-        let mut r = rng();
-        r.gen_range(5i, -2);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_gen_range_fail_uint() {
-        let mut r = rng();
-        r.gen_range(5u, 2u);
-    }
-
-    #[test]
-    fn test_gen_f64() {
-        let mut r = rng();
-        let a = r.gen::<f64>();
-        let b = r.gen::<f64>();
-        debug!("{:?}", (a, b));
-    }
-
-    #[test]
-    fn test_gen_weighted_bool() {
-        let mut r = rng();
-        assert_eq!(r.gen_weighted_bool(0u), true);
-        assert_eq!(r.gen_weighted_bool(1u), true);
-    }
-
-    #[test]
-    fn test_gen_ascii_str() {
-        let mut r = rng();
-        debug!("{}", r.gen_ascii_str(10u));
-        debug!("{}", r.gen_ascii_str(10u));
-        debug!("{}", r.gen_ascii_str(10u));
-        assert_eq!(r.gen_ascii_str(0u).len(), 0u);
-        assert_eq!(r.gen_ascii_str(10u).len(), 10u);
-        assert_eq!(r.gen_ascii_str(16u).len(), 16u);
-    }
-
-    #[test]
-    fn test_gen_vec() {
-        let mut r = rng();
-        assert_eq!(r.gen_vec::<u8>(0u).len(), 0u);
-        assert_eq!(r.gen_vec::<u8>(10u).len(), 10u);
-        assert_eq!(r.gen_vec::<f64>(16u).len(), 16u);
-    }
-
-    #[test]
-    fn test_choose() {
-        let mut r = rng();
-        assert_eq!(r.choose([1, 1, 1]), 1);
-    }
-
-    #[test]
-    fn test_choose_option() {
-        let mut r = rng();
-        let v: &[int] = &[];
-        assert!(r.choose_option(v).is_none());
-
-        let i = 1;
-        let v = [1,1,1];
-        assert_eq!(r.choose_option(v), Some(&i));
-    }
-
-    #[test]
-    fn test_shuffle() {
-        let mut r = rng();
-        let empty: ~[int] = ~[];
-        assert_eq!(r.shuffle(~[]), empty);
-        assert_eq!(r.shuffle(~[1, 1, 1]), ~[1, 1, 1]);
-    }
-
-    #[test]
-    fn test_task_rng() {
-        let mut r = task_rng();
-        r.gen::<int>();
-        assert_eq!(r.shuffle(~[1, 1, 1]), ~[1, 1, 1]);
-        assert_eq!(r.gen_range(0u, 1u), 0u);
-    }
-
-    #[test]
-    fn test_random() {
-        // not sure how to test this aside from just getting some values
-        let _n : uint = random();
-        let _f : f32 = random();
-        let _o : Option<Option<i8>> = random();
-        let _many : ((),
-                     (~uint, @int, ~Option<~(@u32, ~(@bool,))>),
-                     (u8, i8, u16, i16, u32, i32, u64, i64),
-                     (f32, (f64, (f64,)))) = random();
-    }
-
-    #[test]
-    fn test_sample() {
-        let min_val = 1;
-        let max_val = 100;
-
-        let mut r = rng();
-        let vals = range(min_val, max_val).to_owned_vec();
-        let small_sample = r.sample(vals.iter(), 5);
-        let large_sample = r.sample(vals.iter(), vals.len() + 5);
-
-        assert_eq!(small_sample.len(), 5);
-        assert_eq!(large_sample.len(), vals.len());
-
-        assert!(small_sample.iter().all(|e| {
-            **e >= min_val && **e <= max_val
-        }));
-    }
-
-    #[test]
-    fn test_std_rng_seeded() {
-        let s = OSRng::new().gen_vec::<uint>(256);
-        let mut ra: StdRng = SeedableRng::from_seed(s.as_slice());
-        let mut rb: StdRng = SeedableRng::from_seed(s.as_slice());
-        assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
-    }
-
-    #[test]
-    fn test_std_rng_reseed() {
-        let s = OSRng::new().gen_vec::<uint>(256);
-        let mut r: StdRng = SeedableRng::from_seed(s.as_slice());
-        let string1 = r.gen_ascii_str(100);
-
-        r.reseed(s);
-
-        let string2 = r.gen_ascii_str(100);
-        assert_eq!(string1, string2);
-    }
-}
-
-#[cfg(test)]
-static RAND_BENCH_N: u64 = 100;
-
-#[cfg(test)]
-mod bench {
-    extern crate test;
-    use self::test::BenchHarness;
-    use prelude::*;
-    use rand::{XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng, RAND_BENCH_N};
-    use mem::size_of;
-
-    #[bench]
-    fn rand_xorshift(bh: &mut BenchHarness) {
-        let mut rng = XorShiftRng::new();
-        bh.iter(|| {
-            for _ in range(0, RAND_BENCH_N) {
-                rng.gen::<uint>();
-            }
-        });
-        bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
-    }
-
-    #[bench]
-    fn rand_isaac(bh: &mut BenchHarness) {
-        let mut rng = IsaacRng::new();
-        bh.iter(|| {
-            for _ in range(0, RAND_BENCH_N) {
-                rng.gen::<uint>();
-            }
-        });
-        bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
-    }
-
-    #[bench]
-    fn rand_isaac64(bh: &mut BenchHarness) {
-        let mut rng = Isaac64Rng::new();
-        bh.iter(|| {
-            for _ in range(0, RAND_BENCH_N) {
-                rng.gen::<uint>();
-            }
-        });
-        bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
-    }
-
-    #[bench]
-    fn rand_std(bh: &mut BenchHarness) {
-        let mut rng = StdRng::new();
-        bh.iter(|| {
-            for _ in range(0, RAND_BENCH_N) {
-                rng.gen::<uint>();
-            }
-        });
-        bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
-    }
-
-    #[bench]
-    fn rand_shuffle_100(bh: &mut BenchHarness) {
-        let mut rng = XorShiftRng::new();
-        let x : &mut[uint] = [1,..100];
-        bh.iter(|| {
-            rng.shuffle_mut(x);
-        })
-    }
-}
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs
deleted file mode 100644 (file)
index e9068c6..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Interfaces to the operating system provided random number
-//! generators.
-
-use rand::Rng;
-use ops::Drop;
-
-#[cfg(unix)]
-use rand::reader::ReaderRng;
-#[cfg(unix)]
-use io::File;
-
-#[cfg(windows)]
-use cast;
-#[cfg(windows)]
-use libc::{c_long, DWORD, BYTE};
-#[cfg(windows)]
-type HCRYPTPROV = c_long;
-// the extern functions imported from the runtime on Windows are
-// implemented so that they either succeed or abort(), so we can just
-// assume they work when we call them.
-
-/// A random number generator that retrieves randomness straight from
-/// the operating system. Platform sources:
-///
-/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
-///   `/dev/urandom`.
-/// - Windows: calls `CryptGenRandom`, using the default cryptographic
-///   service provider with the `PROV_RSA_FULL` type.
-///
-/// This does not block.
-#[cfg(unix)]
-pub struct OSRng {
-    priv inner: ReaderRng<File>
-}
-/// A random number generator that retrieves randomness straight from
-/// the operating system. Platform sources:
-///
-/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
-///   `/dev/urandom`.
-/// - Windows: calls `CryptGenRandom`, using the default cryptographic
-///   service provider with the `PROV_RSA_FULL` type.
-///
-/// This does not block.
-#[cfg(windows)]
-pub struct OSRng {
-    priv hcryptprov: HCRYPTPROV
-}
-
-impl OSRng {
-    /// Create a new `OSRng`.
-    #[cfg(unix)]
-    pub fn new() -> OSRng {
-        use path::Path;
-        let reader = File::open(&Path::new("/dev/urandom"));
-        let reader = reader.ok().expect("Error opening /dev/urandom");
-        let reader_rng = ReaderRng::new(reader);
-
-        OSRng { inner: reader_rng }
-    }
-
-    /// Create a new `OSRng`.
-    #[cfg(windows)]
-    pub fn new() -> OSRng {
-        extern { fn rust_win32_rand_acquire(phProv: *mut HCRYPTPROV); }
-
-        let mut hcp = 0;
-        unsafe {rust_win32_rand_acquire(&mut hcp)};
-
-        OSRng { hcryptprov: hcp }
-    }
-}
-
-#[cfg(unix)]
-impl Rng for OSRng {
-    fn next_u32(&mut self) -> u32 {
-        self.inner.next_u32()
-    }
-    fn next_u64(&mut self) -> u64 {
-        self.inner.next_u64()
-    }
-    fn fill_bytes(&mut self, v: &mut [u8]) {
-        self.inner.fill_bytes(v)
-    }
-}
-
-#[cfg(windows)]
-impl Rng for OSRng {
-    fn next_u32(&mut self) -> u32 {
-        let mut v = [0u8, .. 4];
-        self.fill_bytes(v);
-        unsafe { cast::transmute(v) }
-    }
-    fn next_u64(&mut self) -> u64 {
-        let mut v = [0u8, .. 8];
-        self.fill_bytes(v);
-        unsafe { cast::transmute(v) }
-    }
-    fn fill_bytes(&mut self, v: &mut [u8]) {
-        use container::Container;
-        use vec::MutableVector;
-
-        extern {
-            fn rust_win32_rand_gen(hProv: HCRYPTPROV, dwLen: DWORD,
-                                   pbBuffer: *mut BYTE);
-        }
-
-        unsafe {rust_win32_rand_gen(self.hcryptprov, v.len() as DWORD, v.as_mut_ptr())}
-    }
-}
-
-impl Drop for OSRng {
-    #[cfg(unix)]
-    fn drop(&mut self) {
-        // ensure that OSRng is not implicitly copyable on all
-        // platforms, for consistency.
-    }
-
-    #[cfg(windows)]
-    fn drop(&mut self) {
-        extern { fn rust_win32_rand_release(hProv: HCRYPTPROV); }
-
-        unsafe {rust_win32_rand_release(self.hcryptprov)}
-    }
-}
-
-
-#[cfg(test)]
-mod test {
-    use prelude::*;
-    use super::*;
-    use rand::Rng;
-    use task;
-
-    #[test]
-    fn test_os_rng() {
-        let mut r = OSRng::new();
-
-        r.next_u32();
-        r.next_u64();
-
-        let mut v = [0u8, .. 1000];
-        r.fill_bytes(v);
-    }
-
-    #[test]
-    fn test_os_rng_tasks() {
-
-        let mut chans = ~[];
-        for _ in range(0, 20) {
-            let (p, c) = Chan::new();
-            chans.push(c);
-            task::spawn(proc() {
-                // wait until all the tasks are ready to go.
-                p.recv();
-
-                // deschedule to attempt to interleave things as much
-                // as possible (XXX: is this a good test?)
-                let mut r = OSRng::new();
-                task::deschedule();
-                let mut v = [0u8, .. 1000];
-
-                for _ in range(0, 100) {
-                    r.next_u32();
-                    task::deschedule();
-                    r.next_u64();
-                    task::deschedule();
-                    r.fill_bytes(v);
-                    task::deschedule();
-                }
-            })
-        }
-
-        // start all the tasks
-        for c in chans.iter() {
-            c.send(())
-        }
-    }
-}
diff --git a/src/libstd/rand/rand_impls.rs b/src/libstd/rand/rand_impls.rs
deleted file mode 100644 (file)
index 8f4752b..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The implementations of `Rand` for the built-in types.
-
-use char;
-use int;
-use option::{Option, Some, None};
-use rand::{Rand,Rng};
-use uint;
-
-impl Rand for int {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> int {
-        if int::BITS == 32 {
-            rng.gen::<i32>() as int
-        } else {
-            rng.gen::<i64>() as int
-        }
-    }
-}
-
-impl Rand for i8 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> i8 {
-        rng.next_u32() as i8
-    }
-}
-
-impl Rand for i16 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> i16 {
-        rng.next_u32() as i16
-    }
-}
-
-impl Rand for i32 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> i32 {
-        rng.next_u32() as i32
-    }
-}
-
-impl Rand for i64 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> i64 {
-        rng.next_u64() as i64
-    }
-}
-
-impl Rand for uint {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> uint {
-        if uint::BITS == 32 {
-            rng.gen::<u32>() as uint
-        } else {
-            rng.gen::<u64>() as uint
-        }
-    }
-}
-
-impl Rand for u8 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> u8 {
-        rng.next_u32() as u8
-    }
-}
-
-impl Rand for u16 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> u16 {
-        rng.next_u32() as u16
-    }
-}
-
-impl Rand for u32 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> u32 {
-        rng.next_u32()
-    }
-}
-
-impl Rand for u64 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> u64 {
-        rng.next_u64()
-    }
-}
-
-macro_rules! float_impls {
-    ($mod_name:ident, $ty:ty, $mantissa_bits:expr, $method_name:ident, $ignored_bits:expr) => {
-        mod $mod_name {
-            use rand::{Rand, Rng, Open01, Closed01};
-
-            static SCALE: $ty = (1u64 << $mantissa_bits) as $ty;
-
-            impl Rand for $ty {
-                /// Generate a floating point number in the half-open
-                /// interval `[0,1)`.
-                ///
-                /// See `Closed01` for the closed interval `[0,1]`,
-                /// and `Open01` for the open interval `(0,1)`.
-                #[inline]
-                fn rand<R: Rng>(rng: &mut R) -> $ty {
-                    // using any more than `mantissa_bits` bits will
-                    // cause (e.g.) 0xffff_ffff to correspond to 1
-                    // exactly, so we need to drop some (8 for f32, 11
-                    // for f64) to guarantee the open end.
-                    (rng.$method_name() >> $ignored_bits) as $ty / SCALE
-                }
-            }
-            impl Rand for Open01<$ty> {
-                #[inline]
-                fn rand<R: Rng>(rng: &mut R) -> Open01<$ty> {
-                    // add a small amount (specifically 2 bits below
-                    // the precision of f64/f32 at 1.0), so that small
-                    // numbers are larger than 0, but large numbers
-                    // aren't pushed to/above 1.
-                    Open01(((rng.$method_name() >> $ignored_bits) as $ty + 0.25) / SCALE)
-                }
-            }
-            impl Rand for Closed01<$ty> {
-                #[inline]
-                fn rand<R: Rng>(rng: &mut R) -> Closed01<$ty> {
-                    // divide by the maximum value of the numerator to
-                    // get a non-zero probability of getting exactly
-                    // 1.0.
-                    Closed01((rng.$method_name() >> $ignored_bits) as $ty / (SCALE - 1.0))
-                }
-            }
-        }
-    }
-}
-float_impls! { f64_rand_impls, f64, 53, next_u64, 11 }
-float_impls! { f32_rand_impls, f32, 24, next_u32, 8 }
-
-impl Rand for char {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> char {
-        // a char is 21 bits
-        static CHAR_MASK: u32 = 0x001f_ffff;
-        loop {
-            // Rejection sampling. About 0.2% of numbers with at most
-            // 21-bits are invalid codepoints (surrogates), so this
-            // will succeed first go almost every time.
-            match char::from_u32(rng.next_u32() & CHAR_MASK) {
-                Some(c) => return c,
-                None => {}
-            }
-        }
-    }
-}
-
-impl Rand for bool {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> bool {
-        rng.gen::<u8>() & 1 == 1
-    }
-}
-
-macro_rules! tuple_impl {
-    // use variables to indicate the arity of the tuple
-    ($($tyvar:ident),* ) => {
-        // the trailing commas are for the 1 tuple
-        impl<
-            $( $tyvar : Rand ),*
-            > Rand for ( $( $tyvar ),* , ) {
-
-            #[inline]
-            fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) {
-                (
-                    // use the $tyvar's to get the appropriate number of
-                    // repeats (they're not actually needed)
-                    $(
-                        _rng.gen::<$tyvar>()
-                    ),*
-                    ,
-                )
-            }
-        }
-    }
-}
-
-impl Rand for () {
-    #[inline]
-    fn rand<R: Rng>(_: &mut R) -> () { () }
-}
-tuple_impl!{A}
-tuple_impl!{A, B}
-tuple_impl!{A, B, C}
-tuple_impl!{A, B, C, D}
-tuple_impl!{A, B, C, D, E}
-tuple_impl!{A, B, C, D, E, F}
-tuple_impl!{A, B, C, D, E, F, G}
-tuple_impl!{A, B, C, D, E, F, G, H}
-tuple_impl!{A, B, C, D, E, F, G, H, I}
-tuple_impl!{A, B, C, D, E, F, G, H, I, J}
-
-impl<T:Rand> Rand for Option<T> {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> Option<T> {
-        if rng.gen() {
-            Some(rng.gen())
-        } else {
-            None
-        }
-    }
-}
-
-impl<T: Rand> Rand for ~T {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> ~T { ~rng.gen() }
-}
-
-impl<T: Rand + 'static> Rand for @T {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> @T { @rng.gen() }
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use rand::{Rng, task_rng, Open01, Closed01};
-
-    struct ConstantRng(u64);
-    impl Rng for ConstantRng {
-        fn next_u32(&mut self) -> u32 {
-            let ConstantRng(v) = *self;
-            v as u32
-        }
-        fn next_u64(&mut self) -> u64 {
-            let ConstantRng(v) = *self;
-            v
-        }
-    }
-
-    #[test]
-    fn floating_point_edge_cases() {
-        // the test for exact equality is correct here.
-        assert!(ConstantRng(0xffff_ffff).gen::<f32>() != 1.0)
-        assert!(ConstantRng(0xffff_ffff_ffff_ffff).gen::<f64>() != 1.0)
-    }
-
-    #[test]
-    fn rand_open() {
-        // this is unlikely to catch an incorrect implementation that
-        // generates exactly 0 or 1, but it keeps it sane.
-        let mut rng = task_rng();
-        for _ in range(0, 1_000) {
-            // strict inequalities
-            let Open01(f) = rng.gen::<Open01<f64>>();
-            assert!(0.0 < f && f < 1.0);
-
-            let Open01(f) = rng.gen::<Open01<f32>>();
-            assert!(0.0 < f && f < 1.0);
-        }
-    }
-
-    #[test]
-    fn rand_closed() {
-        let mut rng = task_rng();
-        for _ in range(0, 1_000) {
-            // strict inequalities
-            let Closed01(f) = rng.gen::<Closed01<f64>>();
-            assert!(0.0 <= f && f <= 1.0);
-
-            let Closed01(f) = rng.gen::<Closed01<f32>>();
-            assert!(0.0 <= f && f <= 1.0);
-        }
-    }
-}
diff --git a/src/libstd/rand/reader.rs b/src/libstd/rand/reader.rs
deleted file mode 100644 (file)
index 4c9a8f7..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A wrapper around any Reader to treat it as an RNG.
-
-use container::Container;
-use result::{Ok, Err};
-use io::Reader;
-
-use rand::Rng;
-
-/// An RNG that reads random bytes straight from a `Reader`. This will
-/// work best with an infinite reader, but this is not required.
-///
-/// It will fail if it there is insufficient data to fulfill a request.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand::{reader, Rng};
-/// use std::io::MemReader;
-///
-/// let mut rng = reader::ReaderRng::new(MemReader::new(~[1,2,3,4,5,6,7,8]));
-/// println!("{:x}", rng.gen::<uint>());
-/// ```
-pub struct ReaderRng<R> {
-    priv reader: R
-}
-
-impl<R: Reader> ReaderRng<R> {
-    /// Create a new `ReaderRng` from a `Reader`.
-    pub fn new(r: R) -> ReaderRng<R> {
-        ReaderRng {
-            reader: r
-        }
-    }
-}
-
-impl<R: Reader> Rng for ReaderRng<R> {
-    fn next_u32(&mut self) -> u32 {
-        // This is designed for speed: reading a LE integer on a LE
-        // platform just involves blitting the bytes into the memory
-        // of the u32, similarly for BE on BE; avoiding byteswapping.
-        if cfg!(target_endian="little") {
-            self.reader.read_le_u32().unwrap()
-        } else {
-            self.reader.read_be_u32().unwrap()
-        }
-    }
-    fn next_u64(&mut self) -> u64 {
-        // see above for explanation.
-        if cfg!(target_endian="little") {
-            self.reader.read_le_u64().unwrap()
-        } else {
-            self.reader.read_be_u64().unwrap()
-        }
-    }
-    fn fill_bytes(&mut self, v: &mut [u8]) {
-        if v.len() == 0 { return }
-        match self.reader.read(v) {
-            Ok(n) if n == v.len() => return,
-            Ok(n) => fail!("ReaderRng.fill_bytes could not fill buffer: \
-                            read {} out of {} bytes.", n, v.len()),
-            Err(e) => fail!("ReaderRng.fill_bytes error: {}", e)
-        }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::*;
-    use io::MemReader;
-    use cast;
-    use rand::*;
-    use prelude::*;
-
-    #[test]
-    fn test_reader_rng_u64() {
-        // transmute from the target to avoid endianness concerns.
-        let v = ~[1u64, 2u64, 3u64];
-        let bytes: ~[u8] = unsafe {cast::transmute(v)};
-        let mut rng = ReaderRng::new(MemReader::new(bytes));
-
-        assert_eq!(rng.next_u64(), 1);
-        assert_eq!(rng.next_u64(), 2);
-        assert_eq!(rng.next_u64(), 3);
-    }
-    #[test]
-    fn test_reader_rng_u32() {
-        // transmute from the target to avoid endianness concerns.
-        let v = ~[1u32, 2u32, 3u32];
-        let bytes: ~[u8] = unsafe {cast::transmute(v)};
-        let mut rng = ReaderRng::new(MemReader::new(bytes));
-
-        assert_eq!(rng.next_u32(), 1);
-        assert_eq!(rng.next_u32(), 2);
-        assert_eq!(rng.next_u32(), 3);
-    }
-    #[test]
-    fn test_reader_rng_fill_bytes() {
-        let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
-        let mut w = [0u8, .. 8];
-
-        let mut rng = ReaderRng::new(MemReader::new(v.to_owned()));
-        rng.fill_bytes(w);
-
-        assert!(v == w);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_reader_rng_insufficient_bytes() {
-        let mut rng = ReaderRng::new(MemReader::new(~[]));
-        let mut v = [0u8, .. 3];
-        rng.fill_bytes(v);
-    }
-}
diff --git a/src/libstd/rand/reseeding.rs b/src/libstd/rand/reseeding.rs
deleted file mode 100644 (file)
index a916ce1..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A wrapper around another RNG that reseeds it after it
-//! generates a certain number of random bytes.
-
-use container::Container;
-use default::Default;
-use rand::{Rng, SeedableRng};
-
-/// How many bytes of entropy the underling RNG is allowed to generate
-/// before it is reseeded.
-static DEFAULT_GENERATION_THRESHOLD: uint = 32 * 1024;
-
-/// A wrapper around any RNG which reseeds the underlying RNG after it
-/// has generated a certain number of random bytes.
-pub struct ReseedingRng<R, Rsdr> {
-    priv rng: R,
-    priv generation_threshold: uint,
-    priv bytes_generated: uint,
-    /// Controls the behaviour when reseeding the RNG.
-    reseeder: Rsdr
-}
-
-impl<R: Rng, Rsdr: Reseeder<R>> ReseedingRng<R, Rsdr> {
-    /// Create a new `ReseedingRng` with the given parameters.
-    ///
-    /// # Arguments
-    ///
-    /// * `rng`: the random number generator to use.
-    /// * `generation_threshold`: the number of bytes of entropy at which to reseed the RNG.
-    /// * `reseeder`: the reseeding object to use.
-    pub fn new(rng: R, generation_threshold: uint, reseeder: Rsdr) -> ReseedingRng<R,Rsdr> {
-        ReseedingRng {
-            rng: rng,
-            generation_threshold: generation_threshold,
-            bytes_generated: 0,
-            reseeder: reseeder
-        }
-    }
-
-    /// Reseed the internal RNG if the number of bytes that have been
-    /// generated exceed the threshold.
-    pub fn reseed_if_necessary(&mut self) {
-        if self.bytes_generated >= self.generation_threshold {
-            self.reseeder.reseed(&mut self.rng);
-            self.bytes_generated = 0;
-        }
-    }
-}
-
-
-impl<R: Rng, Rsdr: Reseeder<R>> Rng for ReseedingRng<R, Rsdr> {
-    fn next_u32(&mut self) -> u32 {
-        self.reseed_if_necessary();
-        self.bytes_generated += 4;
-        self.rng.next_u32()
-    }
-
-    fn next_u64(&mut self) -> u64 {
-        self.reseed_if_necessary();
-        self.bytes_generated += 8;
-        self.rng.next_u64()
-    }
-
-    fn fill_bytes(&mut self, dest: &mut [u8]) {
-        self.reseed_if_necessary();
-        self.bytes_generated += dest.len();
-        self.rng.fill_bytes(dest)
-    }
-}
-
-impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R>>
-     SeedableRng<(Rsdr, S)> for ReseedingRng<R, Rsdr> {
-    fn reseed(&mut self, (rsdr, seed): (Rsdr, S)) {
-        self.rng.reseed(seed);
-        self.reseeder = rsdr;
-        self.bytes_generated = 0;
-    }
-    /// Create a new `ReseedingRng` from the given reseeder and
-    /// seed. This uses a default value for `generation_threshold`.
-    fn from_seed((rsdr, seed): (Rsdr, S)) -> ReseedingRng<R, Rsdr> {
-        ReseedingRng {
-            rng: SeedableRng::from_seed(seed),
-            generation_threshold: DEFAULT_GENERATION_THRESHOLD,
-            bytes_generated: 0,
-            reseeder: rsdr
-        }
-    }
-}
-
-/// Something that can be used to reseed an RNG via `ReseedingRng`.
-///
-/// # Example
-///
-/// ```rust
-/// use std::rand;
-/// use std::rand::{Rng, SeedableRng};
-/// use std::rand::reseeding::{Reseeder, ReseedingRng};
-///
-/// struct TickTockReseeder { tick: bool }
-/// impl Reseeder<rand::StdRng> for TickTockReseeder {
-///     fn reseed(&mut self, rng: &mut rand::StdRng) {
-///         let val = if self.tick {0} else {1};
-///         rng.reseed(&[val]);
-///         self.tick = !self.tick;
-///     }
-/// }
-/// fn main() {
-///     let rsdr = TickTockReseeder { tick: true };
-///     let mut rng = ReseedingRng::new(rand::StdRng::new(), 10, rsdr);
-///
-///     // this will repeat, because it gets reseeded very regularly.
-///     println!("{}", rng.gen_ascii_str(100));
-/// }
-///
-/// ```
-pub trait Reseeder<R> {
-    /// Reseed the given RNG.
-    fn reseed(&mut self, rng: &mut R);
-}
-
-/// Reseed an RNG using a `Default` instance. This reseeds by
-/// replacing the RNG with the result of a `Default::default` call.
-pub struct ReseedWithDefault;
-
-impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {
-    fn reseed(&mut self, rng: &mut R) {
-        *rng = Default::default();
-    }
-}
-impl Default for ReseedWithDefault {
-    fn default() -> ReseedWithDefault { ReseedWithDefault }
-}
-
-#[cfg(test)]
-mod test {
-    use prelude::*;
-    use super::*;
-    use default::Default;
-    use rand::{SeedableRng, Rng};
-
-    struct Counter {
-        i: u32
-    }
-
-    impl Rng for Counter {
-        fn next_u32(&mut self) -> u32 {
-            self.i += 1;
-            // very random
-            self.i - 1
-        }
-    }
-    impl Default for Counter {
-        fn default() -> Counter {
-            Counter { i: 0 }
-        }
-    }
-    impl SeedableRng<u32> for Counter {
-        fn reseed(&mut self, seed: u32) {
-            self.i = seed;
-        }
-        fn from_seed(seed: u32) -> Counter {
-            Counter { i: seed }
-        }
-    }
-    type MyRng = ReseedingRng<Counter, ReseedWithDefault>;
-
-    #[test]
-    fn test_reseeding() {
-        let mut rs = ReseedingRng::new(Counter {i:0}, 400, ReseedWithDefault);
-
-        let mut i = 0;
-        for _ in range(0, 1000) {
-            assert_eq!(rs.next_u32(), i % 100);
-            i += 1;
-        }
-    }
-
-    #[test]
-    fn test_rng_seeded() {
-        let mut ra: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2));
-        let mut rb: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2));
-        assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
-    }
-
-    #[test]
-    fn test_rng_reseed() {
-        let mut r: MyRng = SeedableRng::from_seed((ReseedWithDefault, 3));
-        let string1 = r.gen_ascii_str(100);
-
-        r.reseed((ReseedWithDefault, 3));
-
-        let string2 = r.gen_ascii_str(100);
-        assert_eq!(string1, string2);
-    }
-
-    static fill_bytes_v_len: uint = 13579;
-    #[test]
-    fn test_rng_fill_bytes() {
-        use rand::task_rng;
-        let mut v = ~[0u8, .. fill_bytes_v_len];
-        task_rng().fill_bytes(v);
-
-        // Sanity test: if we've gotten here, `fill_bytes` has not infinitely
-        // recursed.
-        assert_eq!(v.len(), fill_bytes_v_len);
-
-        // To test that `fill_bytes` actually did something, check that the
-        // average of `v` is not 0.
-        let mut sum = 0.0;
-        for &x in v.iter() {
-            sum += x as f64;
-        }
-        assert!(sum / v.len() as f64 != 0.0);
-    }
-}
index da9679eb65578a1aef250e66b5d9970f9f65be38..2d16c87b78b1972de4f0d9dd0bb7d4a031f8e1dd 100644 (file)
@@ -26,7 +26,7 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt,
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
-        path: Path::new(vec!("std", "rand", "Rand")),
+        path: Path::new(vec!("rand", "Rand")),
         additional_bounds: Vec::new(),
         generics: LifetimeBounds::empty(),
         methods: vec!(
@@ -35,7 +35,7 @@ pub fn expand_deriving_rand(cx: &mut ExtCtxt,
                 generics: LifetimeBounds {
                     lifetimes: Vec::new(),
                     bounds: vec!(("R",
-                               vec!( Path::new(vec!("std", "rand", "Rng")) )))
+                               vec!( Path::new(vec!("rand", "Rng")) )))
                 },
                 explicit_self: None,
                 args: vec!(
@@ -58,7 +58,6 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
         _ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`")
     };
     let rand_ident = vec!(
-        cx.ident_of("std"),
         cx.ident_of("rand"),
         cx.ident_of("Rand"),
         cx.ident_of("rand")
@@ -89,7 +88,7 @@ fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
                                         Vec::new());
             let rand_name = cx.expr_path(rand_name);
 
-            // ::std::rand::Rand::rand(rng)
+            // ::rand::Rand::rand(rng)
             let rv_call = cx.expr_call(trait_span,
                                        rand_name,
                                        vec!( *rng.get(0) ));
index 6ba121c5d2d04be07e1f83e5320c1ff7b8c80128..8ab8636aa3a28fca32546b72dc4514e1643061f3 100644 (file)
@@ -410,7 +410,7 @@ rust_win32_rand_acquire(HCRYPTPROV* phProv) {
     win32_require
         (_T("CryptAcquireContext"),
          // changes to the parameters here should be reflected in the docs of
-         // std::rand::os::OSRng
+         // rand::os::OSRng
          CryptAcquireContext(phProv, NULL, NULL, PROV_RSA_FULL,
                              CRYPT_VERIFYCONTEXT|CRYPT_SILENT));
 
index beabe03674a86471c140178cb60b55197ee5f8c2..8b9d4de9f04c1d3194a439c1bbcd43e61150aef1 100644 (file)
 
 // ensure that the TaskRng isn't/doesn't become accidentally sendable.
 
+extern crate rand;
+
 fn test_send<S: Send>() {}
 
 pub fn main() {
-    test_send::<::std::rand::TaskRng>();
-    //~^ ERROR: incompatible type `std::rand::TaskRng`, which does not fulfill `Send`
+    test_send::<::rand::TaskRng>();
+    //~^ ERROR: incompatible type `rand::TaskRng`, which does not fulfill `Send`
 }