Skip to content

Commit 432923f

Browse files
committed
Remove impl of SeedableRng for SmallRng
1 parent ee83070 commit 432923f

File tree

1 file changed

+38
-51
lines changed

1 file changed

+38
-51
lines changed

src/rngs/small.rs

Lines changed: 38 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
//! A small fast RNG
1010
1111
use rand_core::{Error, RngCore, SeedableRng};
12+
use crate::thread_rng;
1213

1314
#[cfg(target_pointer_width = "64")]
1415
type Rng = super::xoshiro256plusplus::Xoshiro256PlusPlus;
@@ -22,58 +23,20 @@ type Rng = super::xoshiro128plusplus::Xoshiro128PlusPlus;
2223
/// Note that depending on the application, [`StdRng`] may be faster on many
2324
/// modern platforms while providing higher-quality randomness. Furthermore,
2425
/// `SmallRng` is **not** a good choice when:
25-
/// - Security against prediction is important. Use [`StdRng`] instead.
26-
/// - Seeds with many zeros are provided. In such cases, it takes `SmallRng`
27-
/// about 10 samples to produce 0 and 1 bits with equal probability. Either
28-
/// provide seeds with an approximately equal number of 0 and 1 (for example
29-
/// by using [`SeedableRng::from_entropy`] or [`SeedableRng::seed_from_u64`]),
30-
/// or use [`StdRng`] instead.
3126
///
32-
/// The algorithm is deterministic but should not be considered reproducible
33-
/// due to dependence on platform and possible replacement in future
34-
/// library versions. For a reproducible generator, use a named PRNG from an
35-
/// external crate, e.g. [rand_xoshiro] or [rand_chacha].
36-
/// Refer also to [The Book](https://rust-random.github.io/book/guide-rngs.html).
27+
/// - Portability is required. Its implementation is not fixed. Use a named
28+
/// generator from an external crate instead, for example [rand_xoshiro] or
29+
/// [rand_chacha]. Refer also to
30+
/// [The Book](https://rust-random.github.io/book/guide-rngs.html).
31+
/// - Security against prediction is important. Use [`StdRng`] instead.
3732
///
3833
/// The PRNG algorithm in `SmallRng` is chosen to be efficient on the current
3934
/// platform, without consideration for cryptography or security. The size of
4035
/// its state is much smaller than [`StdRng`]. The current algorithm is
4136
/// `Xoshiro256PlusPlus` on 64-bit platforms and `Xoshiro128PlusPlus` on 32-bit
4237
/// platforms. Both are also implemented by the [rand_xoshiro] crate.
4338
///
44-
/// # Examples
45-
///
46-
/// Initializing `SmallRng` with a random seed can be done using [`SeedableRng::from_entropy`]:
47-
///
48-
/// ```
49-
/// use rand::{Rng, SeedableRng};
50-
/// use rand::rngs::SmallRng;
51-
///
52-
/// // Create small, cheap to initialize and fast RNG with a random seed.
53-
/// // The randomness is supplied by the operating system.
54-
/// let mut small_rng = SmallRng::from_entropy();
55-
/// # let v: u32 = small_rng.gen();
56-
/// ```
57-
///
58-
/// When initializing a lot of `SmallRng`'s, using [`thread_rng`] can be more
59-
/// efficient:
60-
///
61-
/// ```
62-
/// use rand::{SeedableRng, thread_rng};
63-
/// use rand::rngs::SmallRng;
64-
///
65-
/// // Create a big, expensive to initialize and slower, but unpredictable RNG.
66-
/// // This is cached and done only once per thread.
67-
/// let mut thread_rng = thread_rng();
68-
/// // Create small, cheap to initialize and fast RNGs with random seeds.
69-
/// // One can generally assume this won't fail.
70-
/// let rngs: Vec<SmallRng> = (0..10)
71-
/// .map(|_| SmallRng::from_rng(&mut thread_rng).unwrap())
72-
/// .collect();
73-
/// ```
74-
///
7539
/// [`StdRng`]: crate::rngs::StdRng
76-
/// [`thread_rng`]: crate::thread_rng
7740
/// [rand_chacha]: https://crates.io/crates/rand_chacha
7841
/// [rand_xoshiro]: https://crates.io/crates/rand_xoshiro
7942
#[cfg_attr(doc_cfg, doc(cfg(feature = "small_rng")))]
@@ -102,21 +65,45 @@ impl RngCore for SmallRng {
10265
}
10366
}
10467

105-
impl SeedableRng for SmallRng {
106-
type Seed = <Rng as SeedableRng>::Seed;
107-
68+
impl SmallRng {
69+
/// Construct an instance seeded from another `Rng`
70+
///
71+
/// We recommend that the source (master) RNG uses a different algorithm
72+
/// (i.e. is not `SmallRng`) to avoid correlations between the child PRNGs.
73+
///
74+
/// # Example
75+
/// ```
76+
/// # use rand::rngs::SmallRng;
77+
/// let rng = SmallRng::from_rng(rand::thread_rng());
78+
/// ```
10879
#[inline(always)]
109-
fn from_seed(seed: Self::Seed) -> Self {
110-
SmallRng(Rng::from_seed(seed))
80+
pub fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> {
81+
Rng::from_rng(rng).map(SmallRng)
11182
}
11283

84+
/// Construct an instance seeded from the thread-local RNG
11385
#[inline(always)]
114-
fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> {
115-
Rng::from_rng(rng).map(SmallRng)
86+
pub fn from_thread_rng() -> Result<Self, Error> {
87+
Rng::from_rng(thread_rng()).map(SmallRng)
11688
}
11789

90+
/// Construct an instance from a `u64` seed
91+
///
92+
/// This provides a convenient method of seeding a `SmallRng` from a simple
93+
/// number by use of another algorithm to mutate and expand the input.
94+
/// This is suitable for use with low Hamming Weight numbers like 0 and 1.
95+
///
96+
/// **Warning:** the implementation is deterministic but not portable:
97+
/// output values may differ according to platform and may be changed by a
98+
/// future version of the library.
99+
///
100+
/// # Example
101+
/// ```
102+
/// # use rand::rngs::SmallRng;
103+
/// let rng = SmallRng::seed_from_u64(1);
104+
/// ```
118105
#[inline(always)]
119-
fn seed_from_u64(state: u64) -> Self {
106+
pub fn seed_from_u64(state: u64) -> Self {
120107
SmallRng(Rng::seed_from_u64(state))
121108
}
122109
}

0 commit comments

Comments
 (0)