summaryrefslogtreecommitdiffstats
path: root/third_party/rust/rand/src/rngs/small.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/rand/src/rngs/small.rs')
-rw-r--r--third_party/rust/rand/src/rngs/small.rs117
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)
+ }
+}