Skip to content

Commit 4d7dd68

Browse files
authored
Merge branch 'master' into improve-beta
2 parents ea8345b + 9a3f2f4 commit 4d7dd68

28 files changed

+469
-36
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.
1919
is supported (#744, #1003). Note that `a` and `b` can no longer be references or SIMD types.
2020
- Replace `AsByteSliceMut` with `Fill` (#940)
2121
- Move alias method for `WeightedIndex` to `rand_distr` (#945)
22+
- `Alphanumeric` samples bytes instead of chars (#935)
2223
- Better NaN handling for `WeightedIndex` (#1005)
2324
- Implement `IntoIterator` for `IndexVec`, replacing the `into_iter` method (#1007)
2425
- Reduce packaged crate size (#983)

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,7 @@ rand_hc = { path = "rand_hc", version = "0.2" }
8686
bincode = "1.2.1"
8787

8888
[package.metadata.docs.rs]
89+
# To build locally:
90+
# RUSTDOCFLAGS="--cfg doc_cfg" cargo +nightly doc --all-features --no-deps --open
8991
all-features = true
92+
rustdoc-args = ["--cfg", "doc_cfg"]

benches/distributions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ distr_nz_int!(distr_standard_nz64, NonZeroU64, u64, Standard);
176176
distr_nz_int!(distr_standard_nz128, NonZeroU128, u128, Standard);
177177

178178
distr!(distr_standard_bool, bool, Standard);
179-
distr!(distr_standard_alphanumeric, char, Alphanumeric);
179+
distr!(distr_standard_alphanumeric, u8, Alphanumeric);
180180
distr!(distr_standard_codepoint, char, Standard);
181181

182182
distr_float!(distr_standard_f32, f32, Standard);

benches/seq.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,24 @@ sample_indices!(misc_sample_indices_100_of_1G, sample, 100, 1000_000_000);
177177
sample_indices!(misc_sample_indices_200_of_1G, sample, 200, 1000_000_000);
178178
sample_indices!(misc_sample_indices_400_of_1G, sample, 400, 1000_000_000);
179179
sample_indices!(misc_sample_indices_600_of_1G, sample, 600, 1000_000_000);
180+
181+
macro_rules! sample_indices_rand_weights {
182+
($name:ident, $amount:expr, $length:expr) => {
183+
#[bench]
184+
fn $name(b: &mut Bencher) {
185+
let mut rng = SmallRng::from_rng(thread_rng()).unwrap();
186+
b.iter(|| {
187+
index::sample_weighted(&mut rng, $length, |idx| (1 + (idx % 100)) as u32, $amount)
188+
})
189+
}
190+
};
191+
}
192+
193+
sample_indices_rand_weights!(misc_sample_weighted_indices_1_of_1k, 1, 1000);
194+
sample_indices_rand_weights!(misc_sample_weighted_indices_10_of_1k, 10, 1000);
195+
sample_indices_rand_weights!(misc_sample_weighted_indices_100_of_1k, 100, 1000);
196+
sample_indices_rand_weights!(misc_sample_weighted_indices_100_of_1M, 100, 1000_000);
197+
sample_indices_rand_weights!(misc_sample_weighted_indices_200_of_1M, 200, 1000_000);
198+
sample_indices_rand_weights!(misc_sample_weighted_indices_400_of_1M, 400, 1000_000);
199+
sample_indices_rand_weights!(misc_sample_weighted_indices_600_of_1M, 600, 1000_000);
200+
sample_indices_rand_weights!(misc_sample_weighted_indices_1k_of_1M, 1000, 1000_000);

rand_core/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,7 @@ serde = { version = "1", features = ["derive"], optional = true }
2828
getrandom = { version = "0.1", optional = true }
2929

3030
[package.metadata.docs.rs]
31+
# To build locally:
32+
# RUSTDOCFLAGS="--cfg doc_cfg" cargo +nightly doc --all-features --no-deps --open
3133
all-features = true
34+
rustdoc-args = ["--cfg", "doc_cfg"]

rand_core/src/block.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@
2121
//!
2222
//! # Example
2323
//!
24-
//! ```norun
24+
//! ```no_run
25+
//! use rand_core::{RngCore, SeedableRng};
2526
//! use rand_core::block::{BlockRngCore, BlockRng};
2627
//!
2728
//! struct MyRngCore;
2829
//!
2930
//! impl BlockRngCore for MyRngCore {
31+
//! type Item = u32;
3032
//! type Results = [u32; 16];
3133
//!
3234
//! fn generate(&mut self, results: &mut Self::Results) {
@@ -35,7 +37,7 @@
3537
//! }
3638
//!
3739
//! impl SeedableRng for MyRngCore {
38-
//! type Seed = unimplemented!();
40+
//! type Seed = [u8; 32];
3941
//! fn from_seed(seed: Self::Seed) -> Self {
4042
//! unimplemented!()
4143
//! }
@@ -44,7 +46,8 @@
4446
//! // optionally, also implement CryptoRng for MyRngCore
4547
//!
4648
//! // Final RNG.
47-
//! type MyRng = BlockRng<u32, MyRngCore>;
49+
//! let mut rng = BlockRng::<MyRngCore>::seed_from_u64(0);
50+
//! println!("First value: {}", rng.next_u32());
4851
//! ```
4952
//!
5053
//! [`BlockRngCore`]: crate::block::BlockRngCore
@@ -54,7 +57,8 @@ use crate::impls::{fill_via_u32_chunks, fill_via_u64_chunks};
5457
use crate::{CryptoRng, Error, RngCore, SeedableRng};
5558
use core::convert::AsRef;
5659
use core::fmt;
57-
#[cfg(feature = "serde1")] use serde::{Deserialize, Serialize};
60+
#[cfg(feature = "serde1")]
61+
use serde::{Deserialize, Serialize};
5862

5963
/// A trait for RNGs which do not generate random numbers individually, but in
6064
/// blocks (typically `[u32; N]`). This technique is commonly used by
@@ -73,7 +77,6 @@ pub trait BlockRngCore {
7377
fn generate(&mut self, results: &mut Self::Results);
7478
}
7579

76-
7780
/// A wrapper type implementing [`RngCore`] for some type implementing
7881
/// [`BlockRngCore`] with `u32` array buffer; i.e. this can be used to implement
7982
/// a full RNG from just a `generate` function.
@@ -170,7 +173,8 @@ impl<R: BlockRngCore> BlockRng<R> {
170173
}
171174

172175
impl<R: BlockRngCore<Item = u32>> RngCore for BlockRng<R>
173-
where <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>
176+
where
177+
<R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]>,
174178
{
175179
#[inline]
176180
fn next_u32(&mut self) -> u32 {
@@ -249,7 +253,6 @@ impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng<R> {
249253
}
250254
}
251255

252-
253256
/// A wrapper type implementing [`RngCore`] for some type implementing
254257
/// [`BlockRngCore`] with `u64` array buffer; i.e. this can be used to implement
255258
/// a full RNG from just a `generate` function.
@@ -338,7 +341,8 @@ impl<R: BlockRngCore> BlockRng64<R> {
338341
}
339342

340343
impl<R: BlockRngCore<Item = u64>> RngCore for BlockRng64<R>
341-
where <R as BlockRngCore>::Results: AsRef<[u64]> + AsMut<[u64]>
344+
where
345+
<R as BlockRngCore>::Results: AsRef<[u64]> + AsMut<[u64]>,
342346
{
343347
#[inline]
344348
fn next_u32(&mut self) -> u32 {

rand_core/src/error.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
use core::fmt;
1212
use core::num::NonZeroU32;
1313

14-
1514
/// Error type of random number generators
1615
///
1716
/// In order to be compatible with `std` and `no_std`, this type has two
@@ -39,9 +38,12 @@ impl Error {
3938
///
4039
/// See also `From<NonZeroU32>`, which is available with and without `std`.
4140
#[cfg(feature = "std")]
41+
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
4242
#[inline]
4343
pub fn new<E>(err: E) -> Self
44-
where E: Into<Box<dyn std::error::Error + Send + Sync + 'static>> {
44+
where
45+
E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
46+
{
4547
Error { inner: err.into() }
4648
}
4749

@@ -50,6 +52,7 @@ impl Error {
5052
/// When configured with `std`, this is a trivial operation and never
5153
/// panics. Without `std`, this method is simply unavailable.
5254
#[cfg(feature = "std")]
55+
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
5356
#[inline]
5457
pub fn inner(&self) -> &(dyn std::error::Error + Send + Sync + 'static) {
5558
&*self.inner
@@ -60,6 +63,7 @@ impl Error {
6063
/// When configured with `std`, this is a trivial operation and never
6164
/// panics. Without `std`, this method is simply unavailable.
6265
#[cfg(feature = "std")]
66+
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
6367
#[inline]
6468
pub fn take_inner(self) -> Box<dyn std::error::Error + Send + Sync + 'static> {
6569
self.inner

rand_core/src/impls.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use core::mem::size_of;
2323
use core::ptr::copy_nonoverlapping;
2424
use core::slice;
2525

26-
2726
/// Implement `next_u64` via `next_u32`, little-endian order.
2827
pub fn next_u64_via_u32<R: RngCore + ?Sized>(rng: &mut R) -> u64 {
2928
// Use LE; we explicitly generate one value before the next.

rand_core/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#![doc(test(attr(allow(unused_variables), deny(warnings))))]
3838
#![allow(clippy::unreadable_literal)]
3939
#![cfg_attr(not(feature = "std"), no_std)]
40-
40+
#![cfg_attr(doc_cfg, feature(doc_cfg))]
4141

4242
use core::convert::AsMut;
4343
use core::default::Default;
@@ -364,6 +364,7 @@ pub trait SeedableRng: Sized {
364364
///
365365
/// [`getrandom`]: https://docs.rs/getrandom
366366
#[cfg(feature = "getrandom")]
367+
#[cfg_attr(doc_cfg, doc(cfg(feature = "getrandom")))]
367368
fn from_entropy() -> Self {
368369
let mut seed = Self::Seed::default();
369370
if let Err(err) = getrandom::getrandom(seed.as_mut()) {

rand_core/src/os.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use getrandom::getrandom;
4343
/// ```
4444
///
4545
/// [getrandom]: https://crates.io/crates/getrandom
46+
#[cfg_attr(doc_cfg, doc(cfg(feature = "getrandom")))]
4647
#[derive(Clone, Copy, Debug, Default)]
4748
pub struct OsRng;
4849

rand_distr/CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,20 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
## Unreleased
7+
## [0.3.0] - 2020-08-25
88
- Move alias method for `WeightedIndex` from `rand` (#945)
9+
- Rename `WeightedIndex` to `WeightedAliasIndex` (#1008)
910
- Replace custom `Float` trait with `num-traits::Float` (#987)
1011
- Enable `no_std` support via `num-traits` math functions (#987)
1112
- Remove `Distribution<u64>` impl for `Poisson` (#987)
1213
- Tweak `Dirichlet` and `alias_method` to use boxed slice instead of `Vec` (#987)
14+
- Use whitelist for package contents, reducing size by 5kb (#983)
15+
- Add case `lambda = 0` in the parametrixation of `Exp` (#972)
1316
- Implement inverse Gaussian distribution (#954)
17+
- Reformatting and use of `rustfmt::skip` (#926)
1418
- All error types now implement `std::error::Error` (#919)
1519
- Re-exported `rand::distributions::BernoulliError` (#919)
16-
- Add case `lambda = 0` in the parametrixation of `Exp` (#972)
20+
- Add value stability tests for distributions (#891)
1721
- Improve algorithm for sampling `Beta` (#1000)
1822

1923
## [0.2.2] - 2019-09-10

rand_distr/src/dirichlet.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use alloc::{boxed::Box, vec, vec::Vec};
3131
/// let samples = dirichlet.sample(&mut rand::thread_rng());
3232
/// println!("{:?} is from a Dirichlet([1.0, 2.0, 3.0]) distribution", samples);
3333
/// ```
34+
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
3435
#[derive(Clone, Debug)]
3536
pub struct Dirichlet<F>
3637
where
@@ -44,6 +45,7 @@ where
4445
}
4546

4647
/// Error type returned from `Dirchlet::new`.
48+
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
4749
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4850
pub enum Error {
4951
/// `alpha.len() < 2`.

rand_distr/src/exponential.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ where F: Float, Exp1: Distribution<F>
124124
///
125125
/// # Remarks
126126
///
127-
/// For custom types `N` implementing the [`Float`](crate::Float) trait,
127+
/// For custom types `N` implementing the [`Float`] trait,
128128
/// the case `lambda = 0` is handled as follows: each sample corresponds
129129
/// to a sample from an `Exp1` multiplied by `1 / 0`. Primitive types
130130
/// yield infinity, since `1 / 0 = infinity`.

rand_distr/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
)]
2121
#![allow(clippy::neg_cmp_op_on_partial_ord)] // suggested fix too verbose
2222
#![no_std]
23+
#![cfg_attr(doc_cfg, feature(doc_cfg))]
2324

2425
//! Generating random samples from probability distributions.
2526
//!
@@ -107,13 +108,15 @@ pub use self::unit_disc::UnitDisc;
107108
pub use self::unit_sphere::UnitSphere;
108109
pub use self::weibull::{Error as WeibullError, Weibull};
109110
#[cfg(feature = "alloc")]
111+
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
110112
pub use rand::distributions::weighted::{WeightedError, WeightedIndex};
111113
#[cfg(feature = "alloc")]
112114
pub use weighted_alias::WeightedAliasIndex;
113115

114116
pub use num_traits;
115117

116118
#[cfg(feature = "alloc")]
119+
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
117120
pub mod weighted_alias;
118121

119122
mod binomial;

rand_distr/src/weighted_alias.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ use alloc::{boxed::Box, vec, vec::Vec};
6363
/// [`Vec<u32>`]: Vec
6464
/// [`Uniform<u32>::sample`]: Distribution::sample
6565
/// [`Uniform<W>::sample`]: Distribution::sample
66+
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
6667
pub struct WeightedAliasIndex<W: AliasableWeight> {
6768
aliases: Box<[u32]>,
6869
no_alias_odds: Box<[W]>,
@@ -269,6 +270,7 @@ where Uniform<W>: Clone
269270
/// Trait that must be implemented for weights, that are used with
270271
/// [`WeightedAliasIndex`]. Currently no guarantees on the correctness of
271272
/// [`WeightedAliasIndex`] are given for custom implementations of this trait.
273+
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
272274
pub trait AliasableWeight:
273275
Sized
274276
+ Copy

src/distributions/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ mod bernoulli;
108108
pub mod uniform;
109109

110110
#[deprecated(since = "0.8.0", note = "use rand::distributions::{WeightedIndex, WeightedError} instead")]
111-
#[cfg(feature = "alloc")] pub mod weighted;
111+
#[cfg(feature = "alloc")]
112+
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
113+
pub mod weighted;
112114
#[cfg(feature = "alloc")] mod weighted_index;
113115

114116
#[cfg(feature = "serde1")]
@@ -166,7 +168,7 @@ pub trait Distribution<T> {
166168
/// let v: Vec<f32> = Standard.sample_iter(rng).take(16).collect();
167169
///
168170
/// // String:
169-
/// let s: String = Alphanumeric.sample_iter(rng).take(7).collect();
171+
/// let s: String = Alphanumeric.sample_iter(rng).take(7).map(char::from).collect();
170172
///
171173
/// // Dice-rolling:
172174
/// let die_range = Uniform::new_inclusive(1, 6);

src/distributions/other.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use serde::{Serialize, Deserialize};
1919

2020
// ----- Sampling distributions -----
2121

22-
/// Sample a `char`, uniformly distributed over ASCII letters and numbers:
22+
/// Sample a `u8`, uniformly distributed over ASCII letters and numbers:
2323
/// a-z, A-Z and 0-9.
2424
///
2525
/// # Example
@@ -32,6 +32,7 @@ use serde::{Serialize, Deserialize};
3232
/// let mut rng = thread_rng();
3333
/// let chars: String = iter::repeat(())
3434
/// .map(|()| rng.sample(Alphanumeric))
35+
/// .map(char::from)
3536
/// .take(7)
3637
/// .collect();
3738
/// println!("Random chars: {}", chars);
@@ -81,8 +82,8 @@ impl Distribution<char> for Standard {
8182
}
8283
}
8384

84-
impl Distribution<char> for Alphanumeric {
85-
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> char {
85+
impl Distribution<u8> for Alphanumeric {
86+
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u8 {
8687
const RANGE: u32 = 26 + 26 + 10;
8788
const GEN_ASCII_STR_CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
8889
abcdefghijklmnopqrstuvwxyz\
@@ -94,7 +95,7 @@ impl Distribution<char> for Alphanumeric {
9495
loop {
9596
let var = rng.next_u32() >> (32 - 6);
9697
if var < RANGE {
97-
return GEN_ASCII_STR_CHARSET[var as usize] as char;
98+
return GEN_ASCII_STR_CHARSET[var as usize];
9899
}
99100
}
100101
}
@@ -238,7 +239,7 @@ mod tests {
238239
// take the rejection sampling path.
239240
let mut incorrect = false;
240241
for _ in 0..100 {
241-
let c = rng.sample(Alphanumeric);
242+
let c: char = rng.sample(Alphanumeric).into();
242243
incorrect |= !((c >= '0' && c <= '9') ||
243244
(c >= 'A' && c <= 'Z') ||
244245
(c >= 'a' && c <= 'z') );
@@ -266,7 +267,7 @@ mod tests {
266267
'\u{ed692}',
267268
'\u{35888}',
268269
]);
269-
test_samples(&Alphanumeric, 'a', &['h', 'm', 'e', '3', 'M']);
270+
test_samples(&Alphanumeric, 0, &[104, 109, 101, 51, 77]);
270271
test_samples(&Standard, false, &[true, true, false, true, false]);
271272
test_samples(&Standard, None as Option<bool>, &[
272273
Some(true),

src/distributions/utils.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#[cfg(feature = "simd_support")] use packed_simd::*;
1212

1313

14-
pub trait WideningMultiply<RHS = Self> {
14+
pub(crate) trait WideningMultiply<RHS = Self> {
1515
type Output;
1616

1717
fn wmul(self, x: RHS) -> Self::Output;
@@ -208,9 +208,6 @@ mod simd_wmul {
208208
wmul_impl_large! { (u32x16,) u32, 16 }
209209
wmul_impl_large! { (u64x2, u64x4, u64x8,) u64, 32 }
210210
}
211-
#[cfg(all(feature = "simd_support", feature = "nightly"))]
212-
pub use self::simd_wmul::*;
213-
214211

215212
/// Helper trait when dealing with scalar and SIMD floating point types.
216213
pub(crate) trait FloatSIMDUtils {

0 commit comments

Comments
 (0)