diff options
Diffstat (limited to 'third_party/rust/rand/src/rngs/small.rs')
-rw-r--r-- | third_party/rust/rand/src/rngs/small.rs | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/third_party/rust/rand/src/rngs/small.rs b/third_party/rust/rand/src/rngs/small.rs new file mode 100644 index 0000000000..fb0e0d119b --- /dev/null +++ b/third_party/rust/rand/src/rngs/small.rs @@ -0,0 +1,117 @@ +// Copyright 2018 Developers of the Rand project. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! A small fast RNG + +use rand_core::{Error, RngCore, SeedableRng}; + +#[cfg(target_pointer_width = "64")] +type Rng = super::xoshiro256plusplus::Xoshiro256PlusPlus; +#[cfg(not(target_pointer_width = "64"))] +type Rng = super::xoshiro128plusplus::Xoshiro128PlusPlus; + +/// A small-state, fast non-crypto PRNG +/// +/// `SmallRng` may be a good choice when a PRNG with small state, cheap +/// initialization, good statistical quality and good performance are required. +/// Note that depending on the application, [`StdRng`] may be faster on many +/// modern platforms while providing higher-quality randomness. Furthermore, +/// `SmallRng` is **not** a good choice when: +/// - Security against prediction is important. Use [`StdRng`] instead. +/// - Seeds with many zeros are provided. In such cases, it takes `SmallRng` +/// about 10 samples to produce 0 and 1 bits with equal probability. Either +/// provide seeds with an approximately equal number of 0 and 1 (for example +/// by using [`SeedableRng::from_entropy`] or [`SeedableRng::seed_from_u64`]), +/// or use [`StdRng`] instead. +/// +/// The algorithm is deterministic but should not be considered reproducible +/// due to dependence on platform and possible replacement in future +/// library versions. For a reproducible generator, use a named PRNG from an +/// external crate, e.g. [rand_xoshiro] or [rand_chacha]. +/// Refer also to [The Book](https://rust-random.github.io/book/guide-rngs.html). +/// +/// The PRNG algorithm in `SmallRng` is chosen to be efficient on the current +/// platform, without consideration for cryptography or security. The size of +/// its state is much smaller than [`StdRng`]. The current algorithm is +/// `Xoshiro256PlusPlus` on 64-bit platforms and `Xoshiro128PlusPlus` on 32-bit +/// platforms. Both are also implemented by the [rand_xoshiro] crate. +/// +/// # Examples +/// +/// Initializing `SmallRng` with a random seed can be done using [`SeedableRng::from_entropy`]: +/// +/// ``` +/// use rand::{Rng, SeedableRng}; +/// use rand::rngs::SmallRng; +/// +/// // Create small, cheap to initialize and fast RNG with a random seed. +/// // The randomness is supplied by the operating system. +/// let mut small_rng = SmallRng::from_entropy(); +/// # let v: u32 = small_rng.gen(); +/// ``` +/// +/// When initializing a lot of `SmallRng`'s, using [`thread_rng`] can be more +/// efficient: +/// +/// ``` +/// use rand::{SeedableRng, thread_rng}; +/// use rand::rngs::SmallRng; +/// +/// // Create a big, expensive to initialize and slower, but unpredictable RNG. +/// // This is cached and done only once per thread. +/// let mut thread_rng = thread_rng(); +/// // Create small, cheap to initialize and fast RNGs with random seeds. +/// // One can generally assume this won't fail. +/// let rngs: Vec<SmallRng> = (0..10) +/// .map(|_| SmallRng::from_rng(&mut thread_rng).unwrap()) +/// .collect(); +/// ``` +/// +/// [`StdRng`]: crate::rngs::StdRng +/// [`thread_rng`]: crate::thread_rng +/// [rand_chacha]: https://crates.io/crates/rand_chacha +/// [rand_xoshiro]: https://crates.io/crates/rand_xoshiro +#[cfg_attr(doc_cfg, doc(cfg(feature = "small_rng")))] +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct SmallRng(Rng); + +impl RngCore for SmallRng { + #[inline(always)] + fn next_u32(&mut self) -> u32 { + self.0.next_u32() + } + + #[inline(always)] + fn next_u64(&mut self) -> u64 { + self.0.next_u64() + } + + #[inline(always)] + fn fill_bytes(&mut self, dest: &mut [u8]) { + self.0.fill_bytes(dest); + } + + #[inline(always)] + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + self.0.try_fill_bytes(dest) + } +} + +impl SeedableRng for SmallRng { + type Seed = <Rng as SeedableRng>::Seed; + + #[inline(always)] + fn from_seed(seed: Self::Seed) -> Self { + SmallRng(Rng::from_seed(seed)) + } + + #[inline(always)] + fn from_rng<R: RngCore>(rng: R) -> Result<Self, Error> { + Rng::from_rng(rng).map(SmallRng) + } +} |