1 // Copyright 2018 Developers of the Rand project.
2 // Copyright 2013-2017 The Rust Project Developers.
3 //
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
9
10 //! Utilities for random number generation
11 //!
12 //! Rand provides utilities to generate random numbers, to convert them to
13 //! useful types and distributions, and some randomness-related algorithms.
14 //!
15 //! # Quick Start
16 //!
17 //! To get you started quickly, the easiest and highest-level way to get
18 //! a random value is to use [`random()`]; alternatively you can use
19 //! [`thread_rng()`]. The [`Rng`] trait provides a useful API on all RNGs, while
20 //! the [`distributions`] and [`seq`] modules provide further
21 //! functionality on top of RNGs.
22 //!
23 //! ```
24 //! use rand::prelude::*;
25 //!
26 //! if rand::random() { // generates a boolean
27 //! // Try printing a random unicode code point (probably a bad idea)!
28 //! println!("char: {}", rand::random::<char>());
29 //! }
30 //!
31 //! let mut rng = rand::thread_rng();
32 //! let y: f64 = rng.gen(); // generates a float between 0 and 1
33 //!
34 //! let mut nums: Vec<i32> = (1..100).collect();
35 //! nums.shuffle(&mut rng);
36 //! ```
37 //!
38 //! # The Book
39 //!
40 //! For the user guide and further documentation, please read
41 //! [The Rust Rand Book](https://rust-random.github.io/book).
42
43 #![doc(
44 html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
45 html_favicon_url = "https://www.rust-lang.org/favicon.ico",
46 html_root_url = "https://rust-random.github.io/rand/"
47 )]
48 #![deny(missing_docs)]
49 #![deny(missing_debug_implementations)]
50 #![doc(test(attr(allow(unused_variables), deny(warnings))))]
51 #![no_std]
52 #![cfg_attr(feature = "simd_support", feature(stdsimd))]
53 #![cfg_attr(feature = "nightly", feature(slice_partition_at_index))]
54 #![cfg_attr(doc_cfg, feature(doc_cfg))]
55 #![allow(
56 clippy::float_cmp,
57 clippy::neg_cmp_op_on_partial_ord,
58 )]
59
60 #[cfg(feature = "std")] extern crate std;
61 #[cfg(feature = "alloc")] extern crate alloc;
62
63 #[allow(unused)]
64 macro_rules! trace { ($($x:tt)*) => (
65 #[cfg(feature = "log")] {
66 log::trace!($($x)*)
67 }
68 ) }
69 #[allow(unused)]
70 macro_rules! debug { ($($x:tt)*) => (
71 #[cfg(feature = "log")] {
72 log::debug!($($x)*)
73 }
74 ) }
75 #[allow(unused)]
76 macro_rules! info { ($($x:tt)*) => (
77 #[cfg(feature = "log")] {
78 log::info!($($x)*)
79 }
80 ) }
81 #[allow(unused)]
82 macro_rules! warn { ($($x:tt)*) => (
83 #[cfg(feature = "log")] {
84 log::warn!($($x)*)
85 }
86 ) }
87 #[allow(unused)]
88 macro_rules! error { ($($x:tt)*) => (
89 #[cfg(feature = "log")] {
90 log::error!($($x)*)
91 }
92 ) }
93
94 // Re-exports from rand_core
95 pub use rand_core::{CryptoRng, Error, RngCore, SeedableRng};
96
97 // Public modules
98 pub mod distributions;
99 pub mod prelude;
100 mod rng;
101 pub mod rngs;
102 pub mod seq;
103
104 // Public exports
105 #[cfg(all(feature = "std", feature = "std_rng"))]
106 pub use crate::rngs::thread::thread_rng;
107 pub use rng::{Fill, Rng};
108
109 #[cfg(all(feature = "std", feature = "std_rng"))]
110 use crate::distributions::{Distribution, Standard};
111
112 /// Generates a random value using the thread-local random number generator.
113 ///
114 /// This is simply a shortcut for `thread_rng().gen()`. See [`thread_rng`] for
115 /// documentation of the entropy source and [`Standard`] for documentation of
116 /// distributions and type-specific generation.
117 ///
118 /// # Provided implementations
119 ///
120 /// The following types have provided implementations that
121 /// generate values with the following ranges and distributions:
122 ///
123 /// * Integers (`i32`, `u32`, `isize`, `usize`, etc.): Uniformly distributed
124 /// over all values of the type.
125 /// * `char`: Uniformly distributed over all Unicode scalar values, i.e. all
126 /// code points in the range `0...0x10_FFFF`, except for the range
127 /// `0xD800...0xDFFF` (the surrogate code points). This includes
128 /// unassigned/reserved code points.
129 /// * `bool`: Generates `false` or `true`, each with probability 0.5.
130 /// * Floating point types (`f32` and `f64`): Uniformly distributed in the
131 /// half-open range `[0, 1)`. See notes below.
132 /// * Wrapping integers (`Wrapping<T>`), besides the type identical to their
133 /// normal integer variants.
134 ///
135 /// Also supported is the generation of the following
136 /// compound types where all component types are supported:
137 ///
138 /// * Tuples (up to 12 elements): each element is generated sequentially.
139 /// * Arrays (up to 32 elements): each element is generated sequentially;
140 /// see also [`Rng::fill`] which supports arbitrary array length for integer
141 /// types and tends to be faster for `u32` and smaller types.
142 /// * `Option<T>` first generates a `bool`, and if true generates and returns
143 /// `Some(value)` where `value: T`, otherwise returning `None`.
144 ///
145 /// # Examples
146 ///
147 /// ```
148 /// let x = rand::random::<u8>();
149 /// println!("{}", x);
150 ///
151 /// let y = rand::random::<f64>();
152 /// println!("{}", y);
153 ///
154 /// if rand::random() { // generates a boolean
155 /// println!("Better lucky than good!");
156 /// }
157 /// ```
158 ///
159 /// If you're calling `random()` in a loop, caching the generator as in the
160 /// following example can increase performance.
161 ///
162 /// ```
163 /// use rand::Rng;
164 ///
165 /// let mut v = vec![1, 2, 3];
166 ///
167 /// for x in v.iter_mut() {
168 /// *x = rand::random()
169 /// }
170 ///
171 /// // can be made faster by caching thread_rng
172 ///
173 /// let mut rng = rand::thread_rng();
174 ///
175 /// for x in v.iter_mut() {
176 /// *x = rng.gen();
177 /// }
178 /// ```
179 ///
180 /// [`Standard`]: distributions::Standard
181 #[cfg(all(feature = "std", feature = "std_rng"))]
182 #[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", feature = "std_rng"))))]
183 #[inline]
random<T>() -> T where Standard: Distribution<T>184 pub fn random<T>() -> T
185 where Standard: Distribution<T> {
186 thread_rng().gen()
187 }
188
189 #[cfg(test)]
190 mod test {
191 use super::*;
192
193 /// Construct a deterministic RNG with the given seed
rng(seed: u64) -> impl RngCore194 pub fn rng(seed: u64) -> impl RngCore {
195 // For tests, we want a statistically good, fast, reproducible RNG.
196 // PCG32 will do fine, and will be easy to embed if we ever need to.
197 const INC: u64 = 11634580027462260723;
198 rand_pcg::Pcg32::new(seed, INC)
199 }
200
201 #[test]
202 #[cfg(all(feature = "std", feature = "std_rng"))]
test_random()203 fn test_random() {
204 let _n: usize = random();
205 let _f: f32 = random();
206 let _o: Option<Option<i8>> = random();
207 #[allow(clippy::type_complexity)]
208 let _many: (
209 (),
210 (usize, isize, Option<(u32, (bool,))>),
211 (u8, i8, u16, i16, u32, i32, u64, i64),
212 (f32, (f64, (f64,))),
213 ) = random();
214 }
215 }
216