mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 02:03:53 +00:00
Auto merge of #39156 - GuillaumeGomez:debug_librand, r=alexcrichton
Add missing Debug implementation for librand structs Part of #31869.
This commit is contained in:
commit
b4cb1878f0
@ -10,6 +10,7 @@
|
||||
|
||||
//! The ChaCha random number generator.
|
||||
|
||||
use core::fmt;
|
||||
use {Rand, Rng, SeedableRng};
|
||||
|
||||
const KEY_WORDS: usize = 8; // 8 words for the 256-bit key
|
||||
@ -32,6 +33,16 @@ pub struct ChaChaRng {
|
||||
index: usize, // Index into state
|
||||
}
|
||||
|
||||
impl fmt::Debug for ChaChaRng {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("ChaChaRng")
|
||||
.field("buffer", &self.buffer.iter())
|
||||
.field("state", &self.state.iter())
|
||||
.field("index", &self.index)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
static EMPTY: ChaChaRng = ChaChaRng {
|
||||
buffer: [0; STATE_WORDS],
|
||||
state: [0; STATE_WORDS],
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
//! The exponential distribution.
|
||||
|
||||
use core::fmt;
|
||||
|
||||
#[cfg(not(test))] // only necessary for no_std
|
||||
use FloatMath;
|
||||
|
||||
@ -55,6 +57,14 @@ impl Rand for Exp1 {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Exp1 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_tuple("Exp1")
|
||||
.field(&self.0)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// The exponential distribution `Exp(lambda)`.
|
||||
///
|
||||
/// This distribution has density function: `f(x) = lambda *
|
||||
@ -79,6 +89,7 @@ impl Sample<f64> for Exp {
|
||||
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>();
|
||||
@ -86,6 +97,14 @@ impl IndependentSample<f64> for Exp {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Exp {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Exp")
|
||||
.field("lambda_inverse", &self.lambda_inverse)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use distributions::{IndependentSample, Sample};
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
//! The Gamma and derived distributions.
|
||||
|
||||
use core::fmt;
|
||||
|
||||
use self::GammaRepr::*;
|
||||
use self::ChiSquaredRepr::*;
|
||||
|
||||
@ -44,6 +46,19 @@ pub struct Gamma {
|
||||
repr: GammaRepr,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Gamma {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Gamma")
|
||||
.field("repr",
|
||||
&match self.repr {
|
||||
GammaRepr::Large(_) => "Large",
|
||||
GammaRepr::One(_) => "Exp",
|
||||
GammaRepr::Small(_) => "Small"
|
||||
})
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
enum GammaRepr {
|
||||
Large(GammaLargeShape),
|
||||
One(Exp),
|
||||
@ -182,6 +197,18 @@ pub struct ChiSquared {
|
||||
repr: ChiSquaredRepr,
|
||||
}
|
||||
|
||||
impl fmt::Debug for ChiSquared {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("ChiSquared")
|
||||
.field("repr",
|
||||
&match self.repr {
|
||||
ChiSquaredRepr::DoFExactlyOne => "DoFExactlyOne",
|
||||
ChiSquaredRepr::DoFAnythingElse(_) => "DoFAnythingElse",
|
||||
})
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
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-
|
||||
@ -203,11 +230,13 @@ impl ChiSquared {
|
||||
ChiSquared { repr: repr }
|
||||
}
|
||||
}
|
||||
|
||||
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.repr {
|
||||
@ -248,17 +277,29 @@ impl FisherF {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for FisherF {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("FisherF")
|
||||
.field("numer", &self.numer)
|
||||
.field("denom", &self.denom)
|
||||
.field("dof_ratio", &self.dof_ratio)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// The Student t distribution, `t(nu)`, where `nu` is the degrees of
|
||||
/// freedom.
|
||||
pub struct StudentT {
|
||||
@ -277,11 +318,13 @@ impl StudentT {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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>();
|
||||
@ -289,6 +332,15 @@ impl IndependentSample<f64> for StudentT {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for StudentT {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("StudentT")
|
||||
.field("chi", &self.chi)
|
||||
.field("dof", &self.dof)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use distributions::{IndependentSample, Sample};
|
||||
|
@ -17,6 +17,8 @@
|
||||
//! internally. The `IndependentSample` trait is for generating values
|
||||
//! that do not need to record state.
|
||||
|
||||
use core::fmt;
|
||||
|
||||
#[cfg(not(test))] // only necessary for no_std
|
||||
use core::num::Float;
|
||||
|
||||
@ -78,6 +80,12 @@ impl<Sup: Rand> IndependentSample<Sup> for RandSample<Sup> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Sup> fmt::Debug for RandSample<Sup> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.pad("RandSample { .. }")
|
||||
}
|
||||
}
|
||||
|
||||
/// A value with a particular weight for use with `WeightedChoice`.
|
||||
pub struct Weighted<T> {
|
||||
/// The numerical weight of this item
|
||||
@ -86,6 +94,15 @@ pub struct Weighted<T> {
|
||||
pub item: T,
|
||||
}
|
||||
|
||||
impl<T: fmt::Debug> fmt::Debug for Weighted<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Weighted")
|
||||
.field("weight", &self.weight)
|
||||
.field("item", &self.item)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// A distribution that selects from a finite collection of weighted items.
|
||||
///
|
||||
/// Each item has an associated weight that influences how likely it
|
||||
@ -189,6 +206,15 @@ impl<'a, T: Clone> IndependentSample<T> for WeightedChoice<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: fmt::Debug> fmt::Debug for WeightedChoice<'a, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("WeightedChoice")
|
||||
.field("items", &self.items)
|
||||
.field("weight_range", &self.weight_range)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
mod ziggurat_tables;
|
||||
|
||||
/// Sample a random number using the Ziggurat method (specifically the
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
//! The normal and derived distributions.
|
||||
|
||||
use core::fmt;
|
||||
|
||||
#[cfg(not(test))] // only necessary for no_std
|
||||
use FloatMath;
|
||||
|
||||
@ -73,6 +75,14 @@ impl Rand for StandardNormal {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for StandardNormal {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_tuple("StandardNormal")
|
||||
.field(&self.0)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// The normal distribution `N(mean, std_dev**2)`.
|
||||
///
|
||||
/// This uses the ZIGNOR variant of the Ziggurat method, see
|
||||
@ -98,11 +108,13 @@ impl Normal {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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>();
|
||||
@ -110,6 +122,15 @@ impl IndependentSample<f64> for Normal {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Normal {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Normal")
|
||||
.field("mean", &self.mean)
|
||||
.field("std_dev", &self.std_dev)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// The log-normal distribution `ln N(mean, std_dev**2)`.
|
||||
///
|
||||
@ -132,17 +153,27 @@ impl LogNormal {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for LogNormal {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("LogNormal")
|
||||
.field("norm", &self.norm)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use distributions::{IndependentSample, Sample};
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
// this is surprisingly complicated to be both generic & correct
|
||||
|
||||
use core::fmt;
|
||||
use core::marker::Sized;
|
||||
use Rng;
|
||||
use distributions::{IndependentSample, Sample};
|
||||
@ -50,12 +51,23 @@ impl<Sup: SampleRange> Sample<Sup> for Range<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)
|
||||
}
|
||||
}
|
||||
|
||||
impl<X: fmt::Debug> fmt::Debug for Range<X> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Range")
|
||||
.field("low", &self.low)
|
||||
.field("range", &self.range)
|
||||
.field("accept_zone", &self.accept_zone)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// 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`.
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use core::fmt;
|
||||
use core::slice;
|
||||
use core::iter::repeat;
|
||||
use core::num::Wrapping as w;
|
||||
@ -44,6 +45,19 @@ pub struct IsaacRng {
|
||||
c: w32,
|
||||
}
|
||||
|
||||
impl fmt::Debug for IsaacRng {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("IsaacRng")
|
||||
.field("cnt", &self.cnt)
|
||||
.field("rsl", &self.rsl.iter())
|
||||
.field("mem", &self.mem.iter())
|
||||
.field("a", &self.a)
|
||||
.field("b", &self.b)
|
||||
.field("c", &self.c)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
static EMPTY: IsaacRng = IsaacRng {
|
||||
cnt: 0,
|
||||
rsl: [w(0); RAND_SIZE_USIZE],
|
||||
@ -322,6 +336,19 @@ pub struct Isaac64Rng {
|
||||
c: w64,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Isaac64Rng {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Isaac64Rng")
|
||||
.field("cnt", &self.cnt)
|
||||
.field("rsl", &self.rsl.iter())
|
||||
.field("mem", &self.mem.iter())
|
||||
.field("a", &self.a)
|
||||
.field("b", &self.b)
|
||||
.field("c", &self.c)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
static EMPTY_64: Isaac64Rng = Isaac64Rng {
|
||||
cnt: 0,
|
||||
rsl: [w(0); RAND_SIZE_64],
|
||||
|
@ -24,6 +24,7 @@
|
||||
html_playground_url = "https://play.rust-lang.org/",
|
||||
test(attr(deny(warnings))))]
|
||||
#![deny(warnings)]
|
||||
#![deny(missing_debug_implementations)]
|
||||
#![no_std]
|
||||
#![unstable(feature = "rand",
|
||||
reason = "use `rand` from crates.io",
|
||||
@ -32,6 +33,7 @@
|
||||
#![feature(staged_api)]
|
||||
#![feature(step_by)]
|
||||
#![feature(custom_attribute)]
|
||||
#![feature(specialization)]
|
||||
#![allow(unused_attributes)]
|
||||
|
||||
#![cfg_attr(not(test), feature(core_float))] // only necessary for no_std
|
||||
@ -43,6 +45,7 @@
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
|
||||
use core::fmt;
|
||||
use core::f64;
|
||||
use core::intrinsics;
|
||||
use core::marker::PhantomData;
|
||||
@ -288,6 +291,14 @@ impl<'a, T: Rand, R: Rng> Iterator for Generator<'a, T, R> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, R: fmt::Debug> fmt::Debug for Generator<'a, T, R> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Generator")
|
||||
.field("rng", &self.rng)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator which will continuously generate random ascii characters.
|
||||
///
|
||||
/// This iterator is created via the `gen_ascii_chars` method on `Rng`.
|
||||
@ -306,6 +317,14 @@ impl<'a, R: Rng> Iterator for AsciiGenerator<'a, R> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R: fmt::Debug> fmt::Debug for AsciiGenerator<'a, R> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("AsciiGenerator")
|
||||
.field("rng", &self.rng)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// A random number generator that can be explicitly seeded to produce
|
||||
/// the same stream of randomness multiple times.
|
||||
pub trait SeedableRng<Seed>: Rng {
|
||||
@ -326,7 +345,7 @@ pub trait SeedableRng<Seed>: Rng {
|
||||
/// [1]: Marsaglia, George (July 2003). ["Xorshift
|
||||
/// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
|
||||
/// Statistical Software*. Vol. 8 (Issue 14).
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct XorShiftRng {
|
||||
x: u32,
|
||||
y: u32,
|
||||
@ -415,6 +434,14 @@ impl Rand for XorShiftRng {
|
||||
/// `[0,1)`.
|
||||
pub struct Open01<F>(pub F);
|
||||
|
||||
impl<F: fmt::Debug> fmt::Debug for Open01<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_tuple("Open01")
|
||||
.field(&self.0)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper for generating floating point numbers uniformly in the
|
||||
/// closed interval `[0,1]` (including both endpoints).
|
||||
///
|
||||
@ -423,6 +450,14 @@ pub struct Open01<F>(pub F);
|
||||
/// `[0,1)`.
|
||||
pub struct Closed01<F>(pub F);
|
||||
|
||||
impl<F: fmt::Debug> fmt::Debug for Closed01<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_tuple("Closed01")
|
||||
.field(&self.0)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::__rand as rand;
|
||||
|
@ -11,6 +11,7 @@
|
||||
//! A wrapper around another RNG that reseeds it after it
|
||||
//! generates a certain number of random bytes.
|
||||
|
||||
use core::fmt;
|
||||
use {Rng, SeedableRng};
|
||||
|
||||
/// How many bytes of entropy the underling RNG is allowed to generate
|
||||
@ -54,7 +55,6 @@ impl<R: Rng, Rsdr: Reseeder<R>> ReseedingRng<R, Rsdr> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<R: Rng, Rsdr: Reseeder<R>> Rng for ReseedingRng<R, Rsdr> {
|
||||
fn next_u32(&mut self) -> u32 {
|
||||
self.reseed_if_necessary();
|
||||
@ -95,6 +95,17 @@ impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R> + Default>
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: fmt::Debug, Rsdr: fmt::Debug> fmt::Debug for ReseedingRng<R, Rsdr> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("ReseedingRng")
|
||||
.field("rng", &self.rng)
|
||||
.field("generation_threshold", &self.generation_threshold)
|
||||
.field("bytes_generated", &self.bytes_generated)
|
||||
.field("reseeder", &self.reseeder)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// Something that can be used to reseed an RNG via `ReseedingRng`.
|
||||
pub trait Reseeder<R> {
|
||||
/// Reseed the given RNG.
|
||||
@ -103,7 +114,7 @@ pub trait Reseeder<R> {
|
||||
|
||||
/// Reseed an RNG using a `Default` instance. This reseeds by
|
||||
/// replacing the RNG with the result of a `Default::default` call.
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct ReseedWithDefault;
|
||||
|
||||
impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {
|
||||
|
Loading…
Reference in New Issue
Block a user