Merge pull request #134 from tomprince/nonblocking-note
Add a note about `OsRng` blocking in early init.
diff --git a/.travis.yml b/.travis.yml
index 2c5dbd6..73058dc 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,8 +9,10 @@
- pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
script:
- cargo build --verbose
+ - ([ $TRAVIS_RUST_VERSION != nightly ] || cargo build --verbose --features nightly)
- cargo test --verbose
- - cargo doc --no-deps
+ - ([ $TRAVIS_RUST_VERSION != nightly ] || cargo test --verbose --features nightly)
+ - ([ $TRAVIS_RUST_VERSION != nightly ] || cargo doc --no-deps --features nightly)
after_success:
- travis-cargo --only nightly doc-upload
env:
diff --git a/Cargo.toml b/Cargo.toml
index b4320d0..393ec45 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,6 +12,11 @@
Random number generators and other randomness functionality.
"""
keywords = ["random", "rng"]
+categories = ["algorithms"]
+
+[features]
+i128_support = []
+nightly = ["i128_support"]
[dependencies]
libc = "0.2"
diff --git a/appveyor.yml b/appveyor.yml
index 4a61042..9085347 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -15,3 +15,4 @@
test_script:
- cargo test --verbose --target %TARGET%
+ - cargo test --verbose --target %TARGET% --features nightly
diff --git a/src/chacha.rs b/src/chacha.rs
index a347ec5..1acec5e 100644
--- a/src/chacha.rs
+++ b/src/chacha.rs
@@ -26,7 +26,7 @@
///
/// [1]: D. J. Bernstein, [*ChaCha, a variant of
/// Salsa20*](http://cr.yp.to/chacha.html)
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
pub struct ChaChaRng {
buffer: [w32; STATE_WORDS], // Internal buffer of output
state: [w32; STATE_WORDS], // Initial state
diff --git a/src/distributions/exponential.rs b/src/distributions/exponential.rs
index 1be1f8d..c3c924c 100644
--- a/src/distributions/exponential.rs
+++ b/src/distributions/exponential.rs
@@ -34,7 +34,7 @@
/// let Exp1(x) = rand::random();
/// println!("{}", x);
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct Exp1(pub f64);
// This could be done via `-rng.gen::<f64>().ln()` but that is slower.
@@ -71,7 +71,7 @@
/// let v = exp.ind_sample(&mut rand::thread_rng());
/// println!("{} is from a Exp(2) distribution", v);
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct Exp {
/// `lambda` stored as `1/lambda`, since this is what we scale by.
lambda_inverse: f64
diff --git a/src/distributions/gamma.rs b/src/distributions/gamma.rs
index 7ecbc03..1cff4dd 100644
--- a/src/distributions/gamma.rs
+++ b/src/distributions/gamma.rs
@@ -49,12 +49,12 @@
/// 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)
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct Gamma {
repr: GammaRepr,
}
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
enum GammaRepr {
Large(GammaLargeShape),
One(Exp),
@@ -75,7 +75,7 @@
///
/// See `Gamma` for sampling from a Gamma distribution with general
/// shape parameters.
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
struct GammaSmallShape {
inv_shape: f64,
large_shape: GammaLargeShape
@@ -85,7 +85,7 @@
///
/// See `Gamma` for sampling from a Gamma distribution with general
/// shape parameters.
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
struct GammaLargeShape {
scale: f64,
c: f64,
@@ -195,12 +195,12 @@
/// let v = chi.ind_sample(&mut rand::thread_rng());
/// println!("{} is from a χ²(11) distribution", v)
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct ChiSquared {
repr: ChiSquaredRepr,
}
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
enum ChiSquaredRepr {
// 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-
@@ -253,7 +253,7 @@
/// let v = f.ind_sample(&mut rand::thread_rng());
/// println!("{} is from an F(2, 32) distribution", v)
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct FisherF {
numer: ChiSquared,
denom: ChiSquared,
@@ -297,7 +297,7 @@
/// let v = t.ind_sample(&mut rand::thread_rng());
/// println!("{} is from a t(11) distribution", v)
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct StudentT {
chi: ChiSquared,
dof: f64
diff --git a/src/distributions/mod.rs b/src/distributions/mod.rs
index 50f9d95..f128b75 100644
--- a/src/distributions/mod.rs
+++ b/src/distributions/mod.rs
@@ -53,6 +53,7 @@
/// A wrapper for generating types that implement `Rand` via the
/// `Sample` & `IndependentSample` traits.
+#[derive(Debug)]
pub struct RandSample<Sup> {
_marker: marker::PhantomData<fn() -> Sup>,
}
@@ -79,8 +80,7 @@
}
/// A value with a particular weight for use with `WeightedChoice`.
-#[derive(Copy)]
-#[derive(Clone)]
+#[derive(Copy, Clone, Debug)]
pub struct Weighted<T> {
/// The numerical weight of this item
pub weight: u32,
@@ -113,6 +113,7 @@
/// println!("{}", wc.ind_sample(&mut rng));
/// }
/// ```
+#[derive(Debug)]
pub struct WeightedChoice<'a, T:'a> {
items: &'a mut [Weighted<T>],
weight_range: Range<u32>
diff --git a/src/distributions/normal.rs b/src/distributions/normal.rs
index 42872fa..280613d 100644
--- a/src/distributions/normal.rs
+++ b/src/distributions/normal.rs
@@ -33,7 +33,7 @@
/// let StandardNormal(x) = rand::random();
/// println!("{}", x);
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct StandardNormal(pub f64);
impl Rand for StandardNormal {
@@ -88,7 +88,7 @@
/// let v = normal.ind_sample(&mut rand::thread_rng());
/// println!("{} is from a N(2, 9) distribution", v)
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct Normal {
mean: f64,
std_dev: f64,
@@ -136,7 +136,7 @@
/// let v = log_normal.ind_sample(&mut rand::thread_rng());
/// println!("{} is from an ln N(2, 9) distribution", v)
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct LogNormal {
norm: Normal
}
diff --git a/src/distributions/range.rs b/src/distributions/range.rs
index 3a3f3e7..7206941 100644
--- a/src/distributions/range.rs
+++ b/src/distributions/range.rs
@@ -46,7 +46,7 @@
/// println!("{}", sum);
/// }
/// ```
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct Range<X> {
low: X,
range: X,
diff --git a/src/isaac.rs b/src/isaac.rs
index 42de352..b70a8e6 100644
--- a/src/isaac.rs
+++ b/src/isaac.rs
@@ -15,6 +15,7 @@
use std::slice;
use std::iter::repeat;
use std::num::Wrapping as w;
+use std::fmt;
use {Rng, SeedableRng, Rand, w32, w64};
@@ -260,6 +261,12 @@
}
}
+impl fmt::Debug for IsaacRng {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "IsaacRng {{}}")
+ }
+}
+
const RAND_SIZE_64_LEN: usize = 8;
const RAND_SIZE_64: usize = 1 << RAND_SIZE_64_LEN;
@@ -503,6 +510,11 @@
}
}
+impl fmt::Debug for Isaac64Rng {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "Isaac64Rng {{}}")
+ }
+}
#[cfg(test)]
mod test {
diff --git a/src/lib.rs b/src/lib.rs
index 472e4ec..fd0fbf0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -241,8 +241,13 @@
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/rand/")]
+#![deny(missing_debug_implementations)]
+
+#![cfg_attr(feature = "i128_support", feature(i128_type))]
+
#[cfg(test)] #[macro_use] extern crate log;
+
use std::cell::RefCell;
use std::marker;
use std::mem;
@@ -289,7 +294,7 @@
///
/// This rarely needs to be called directly, prefer `r.gen()` to
/// `r.next_u32()`.
- // FIXME #7771: Should be implemented in terms of next_u64
+ // FIXME #rust-lang/rfcs#628: Should be implemented in terms of next_u64
fn next_u32(&mut self) -> u32;
/// Return the next random u64.
@@ -604,6 +609,7 @@
///
/// [`gen_iter`]: trait.Rng.html#method.gen_iter
/// [`Rng`]: trait.Rng.html
+#[derive(Debug)]
pub struct Generator<'a, T, R:'a> {
rng: &'a mut R,
_marker: marker::PhantomData<fn() -> T>,
@@ -623,6 +629,7 @@
///
/// [`gen_ascii_chars`]: trait.Rng.html#method.gen_ascii_chars
/// [`Rng`]: trait.Rng.html
+#[derive(Debug)]
pub struct AsciiGenerator<'a, R:'a> {
rng: &'a mut R,
}
@@ -682,7 +689,7 @@
/// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
/// Statistical Software*. Vol. 8 (Issue 14).
#[allow(missing_copy_implementations)]
-#[derive(Clone)]
+#[derive(Clone, Debug)]
pub struct XorShiftRng {
x: w32,
y: w32,
@@ -772,6 +779,7 @@
/// let Open01(val) = random::<Open01<f32>>();
/// println!("f32 from (0,1): {}", val);
/// ```
+#[derive(Debug)]
pub struct Open01<F>(pub F);
/// A wrapper for generating floating point numbers uniformly in the
@@ -789,11 +797,12 @@
/// let Closed01(val) = random::<Closed01<f32>>();
/// println!("f32 from [0,1]: {}", val);
/// ```
+#[derive(Debug)]
pub struct Closed01<F>(pub F);
/// The standard RNG. This is designed to be efficient on the current
/// platform.
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
pub struct StdRng {
rng: IsaacWordRng,
}
@@ -856,6 +865,7 @@
}
/// Controls how the thread-local RNG is reseeded.
+#[derive(Debug)]
struct ThreadRngReseeder;
impl reseeding::Reseeder<StdRng> for ThreadRngReseeder {
@@ -870,7 +880,7 @@
type ThreadRngInner = reseeding::ReseedingRng<StdRng, ThreadRngReseeder>;
/// The thread-local RNG.
-#[derive(Clone)]
+#[derive(Clone, Debug)]
pub struct ThreadRng {
rng: Rc<RefCell<ThreadRngInner>>,
}
diff --git a/src/os.rs b/src/os.rs
index 8ee3606..970cfd7 100644
--- a/src/os.rs
+++ b/src/os.rs
@@ -11,7 +11,7 @@
//! Interfaces to the operating system provided random number
//! generators.
-use std::{io, mem};
+use std::{io, mem, fmt};
use Rng;
/// A random number generator that retrieves randomness straight from
@@ -47,6 +47,12 @@
fn fill_bytes(&mut self, v: &mut [u8]) { self.0.fill_bytes(v) }
}
+impl fmt::Debug for OsRng {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "OsRng {{}}")
+ }
+}
+
fn next_u32(mut fill_buf: &mut FnMut(&mut [u8])) -> u32 {
let mut buf: [u8; 4] = [0; 4];
fill_buf(&mut buf);
@@ -218,6 +224,7 @@
use Rng;
use self::libc::{c_int, size_t};
+ #[derive(Debug)]
pub struct OsRng;
enum SecRandom {}
@@ -264,6 +271,7 @@
use super::{next_u32, next_u64};
+ #[derive(Debug)]
pub struct OsRng;
impl OsRng {
@@ -307,6 +315,7 @@
use super::{next_u32, next_u64};
+ #[derive(Debug)]
pub struct OsRng;
impl OsRng {
@@ -344,6 +353,7 @@
use Rng;
use read::ReadRng;
+ #[derive(Debug)]
pub struct OsRng {
inner: ReadRng<File>,
}
@@ -401,6 +411,7 @@
fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL;
}
+ #[derive(Debug)]
pub struct OsRng {
hcryptprov: HCRYPTPROV
}
@@ -468,6 +479,7 @@
use super::{next_u32, next_u64};
+ #[derive(Debug)]
pub struct OsRng(extern fn(dest: *mut libc::c_void,
bytes: libc::size_t,
read: *mut libc::size_t) -> libc::c_int);
diff --git a/src/rand_impls.rs b/src/rand_impls.rs
index 5a7e3de..a9cf5d9 100644
--- a/src/rand_impls.rs
+++ b/src/rand_impls.rs
@@ -54,6 +54,14 @@
}
}
+#[cfg(feature = "i128_support")]
+impl Rand for i128 {
+ #[inline]
+ fn rand<R: Rng>(rng: &mut R) -> i128 {
+ rng.gen::<u128>() as i128
+ }
+}
+
impl Rand for usize {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> usize {
@@ -93,6 +101,15 @@
}
}
+#[cfg(feature = "i128_support")]
+impl Rand for u128 {
+ #[inline]
+ fn rand<R: Rng>(rng: &mut R) -> u128 {
+ ((rng.next_u64() as u128) << 64) | (rng.next_u64() as u128)
+ }
+}
+
+
macro_rules! float_impls {
($mod_name:ident, $ty:ty, $mantissa_bits:expr, $method_name:ident) => {
mod $mod_name {
diff --git a/src/read.rs b/src/read.rs
index 9e420bc..c7351b7 100644
--- a/src/read.rs
+++ b/src/read.rs
@@ -30,6 +30,7 @@
/// let mut rng = read::ReadRng::new(&data[..]);
/// println!("{:x}", rng.gen::<u32>());
/// ```
+#[derive(Debug)]
pub struct ReadRng<R> {
reader: R
}
diff --git a/src/reseeding.rs b/src/reseeding.rs
index 39e464d..2fba9f4 100644
--- a/src/reseeding.rs
+++ b/src/reseeding.rs
@@ -21,6 +21,7 @@
/// A wrapper around any RNG which reseeds the underlying RNG after it
/// has generated a certain number of random bytes.
+#[derive(Debug)]
pub struct ReseedingRng<R, Rsdr> {
rng: R,
generation_threshold: u64,
@@ -132,7 +133,7 @@
/// Reseed an RNG using a `Default` instance. This reseeds by
/// replacing the RNG with the result of a `Default::default` call.
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub struct ReseedWithDefault;
impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {