Coverage Report

Created: 2026-11-12 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rand-0.10.1/src/rng.rs
Line
Count
Source
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
//! [`RngExt`] trait
11
12
use crate::distr::uniform::{SampleRange, SampleUniform};
13
use crate::distr::{self, Distribution, StandardUniform};
14
use core::num::Wrapping;
15
use core::{mem, slice};
16
use rand_core::Rng;
17
18
/// User-level interface for RNGs
19
///
20
/// [`Rng`] is the `dyn`-safe implementation-level interface for Random
21
/// (Number) Generators. This trait, `RngExt`, provides a user-level interface
22
/// on RNGs. It is implemented automatically for any <code>R: [Rng][]</code>.
23
///
24
/// This trait must usually be brought into scope via `use rand::RngExt;` or
25
/// `use rand::prelude::*;`.
26
///
27
/// # Generic usage
28
///
29
/// The basic pattern is `fn foo<R: Rng + ?Sized>(rng: &mut R)`. Some
30
/// things are worth noting here:
31
///
32
/// - Since `RngExt: Rng` and every `RngExt` implements `Rng`, it makes no
33
///   difference whether we use `R: Rng` or `R: RngExt` for `R: Sized`.
34
/// - Only `Rng` is dyn safe, supporting `&mut dyn Rng` and `R: Rng + ?Sized`.
35
///
36
/// An alternative pattern is possible: `fn foo<R: Rng>(rng: R)`. This has some
37
/// trade-offs. It allows the argument to be consumed directly without a `&mut`;
38
/// also it still works directly
39
/// on references (including type-erased references). Unfortunately within the
40
/// function `foo` it is not known whether `rng` is a reference type or not,
41
/// hence many uses of `rng` require an extra reference, either explicitly
42
/// (`distr.sample(&mut rng)`) or implicitly (`rng.random()`); one may hope the
43
/// optimiser can remove redundant references later.
44
///
45
/// Example:
46
///
47
/// ```
48
/// use rand::{Rng, RngExt};
49
///
50
/// fn foo<R: Rng + ?Sized>(rng: &mut R) -> f32 {
51
///     rng.random()
52
/// }
53
///
54
/// # let v = foo(&mut rand::rng());
55
/// ```
56
pub trait RngExt: Rng {
57
    /// Return a random value via the [`StandardUniform`] distribution.
58
    ///
59
    /// # Example
60
    ///
61
    /// ```
62
    /// use rand::RngExt;
63
    ///
64
    /// let mut rng = rand::rng();
65
    /// let x: u32 = rng.random();
66
    /// println!("{}", x);
67
    /// println!("{:?}", rng.random::<(f64, bool)>());
68
    /// ```
69
    ///
70
    /// # Arrays and tuples
71
    ///
72
    /// The `rng.random()` method is able to generate arrays
73
    /// and tuples (up to 12 elements), so long as all element types can be
74
    /// generated.
75
    ///
76
    /// For arrays of integers, especially for those with small element types
77
    /// (< 64 bit), it will likely be faster to instead use [`RngExt::fill`],
78
    /// though note that generated values will differ.
79
    ///
80
    /// ```
81
    /// use rand::RngExt;
82
    ///
83
    /// let mut rng = rand::rng();
84
    /// let tuple: (u8, i32, char) = rng.random(); // arbitrary tuple support
85
    ///
86
    /// let arr1: [f32; 32] = rng.random();        // array construction
87
    /// let mut arr2 = [0u8; 128];
88
    /// rng.fill(&mut arr2);                    // array fill
89
    /// ```
90
    ///
91
    /// [`StandardUniform`]: distr::StandardUniform
92
    #[inline]
93
0
    fn random<T>(&mut self) -> T
94
0
    where
95
0
        StandardUniform: Distribution<T>,
96
    {
97
0
        StandardUniform.sample(self)
98
0
    }
99
100
    /// Return an iterator over [`random`](Self::random) variates
101
    ///
102
    /// This is a just a wrapper over [`RngExt::sample_iter`] using
103
    /// [`distr::StandardUniform`].
104
    ///
105
    /// Note: this method consumes its argument. Use
106
    /// `(&mut rng).random_iter()` to avoid consuming the RNG.
107
    ///
108
    /// # Example
109
    ///
110
    /// ```
111
    /// use rand::{rngs::SmallRng, RngExt, SeedableRng};
112
    ///
113
    /// let rng = SmallRng::seed_from_u64(0);
114
    /// let v: Vec<i32> = rng.random_iter().take(5).collect();
115
    /// assert_eq!(v.len(), 5);
116
    /// ```
117
    #[inline]
118
0
    fn random_iter<T>(self) -> distr::Iter<StandardUniform, Self, T>
119
0
    where
120
0
        Self: Sized,
121
0
        StandardUniform: Distribution<T>,
122
    {
123
0
        StandardUniform.sample_iter(self)
124
0
    }
125
126
    /// Generate a random value in the given range.
127
    ///
128
    /// This function is optimised for the case that only a single sample is
129
    /// made from the given range. See also the [`Uniform`] distribution
130
    /// type which may be faster if sampling from the same range repeatedly.
131
    ///
132
    /// All types support `low..high_exclusive` and `low..=high` range syntax.
133
    /// Unsigned integer types also support `..high_exclusive` and `..=high` syntax.
134
    ///
135
    /// # Panics
136
    ///
137
    /// Panics if the range is empty, or if `high - low` overflows for floats.
138
    ///
139
    /// # Example
140
    ///
141
    /// ```
142
    /// use rand::RngExt;
143
    ///
144
    /// let mut rng = rand::rng();
145
    ///
146
    /// // Exclusive range
147
    /// let n: u32 = rng.random_range(..10);
148
    /// println!("{}", n);
149
    /// let m: f64 = rng.random_range(-40.0..1.3e5);
150
    /// println!("{}", m);
151
    ///
152
    /// // Inclusive range
153
    /// let n: u32 = rng.random_range(..=10);
154
    /// println!("{}", n);
155
    /// ```
156
    ///
157
    /// [`Uniform`]: distr::uniform::Uniform
158
    #[track_caller]
159
0
    fn random_range<T, R>(&mut self, range: R) -> T
160
0
    where
161
0
        T: SampleUniform,
162
0
        R: SampleRange<T>,
163
    {
164
0
        assert!(!range.is_empty(), "cannot sample empty range");
165
0
        range.sample_single(self).unwrap()
166
0
    }
167
168
    /// Return a bool with a probability `p` of being true.
169
    ///
170
    /// See also the [`Bernoulli`] distribution, which may be faster if
171
    /// sampling from the same probability repeatedly.
172
    ///
173
    /// # Example
174
    ///
175
    /// ```
176
    /// use rand::RngExt;
177
    ///
178
    /// let mut rng = rand::rng();
179
    /// println!("{}", rng.random_bool(1.0 / 3.0));
180
    /// ```
181
    ///
182
    /// # Panics
183
    ///
184
    /// If `p < 0` or `p > 1`.
185
    ///
186
    /// [`Bernoulli`]: distr::Bernoulli
187
    #[inline]
188
    #[track_caller]
189
0
    fn random_bool(&mut self, p: f64) -> bool {
190
0
        match distr::Bernoulli::new(p) {
191
0
            Ok(d) => self.sample(d),
192
0
            Err(_) => panic!("p={:?} is outside range [0.0, 1.0]", p),
193
        }
194
0
    }
195
196
    /// Return a bool with a probability of `numerator/denominator` of being
197
    /// true.
198
    ///
199
    /// That is, `random_ratio(2, 3)` has chance of 2 in 3, or about 67%, of
200
    /// returning true. If `numerator == denominator`, then the returned value
201
    /// is guaranteed to be `true`. If `numerator == 0`, then the returned
202
    /// value is guaranteed to be `false`.
203
    ///
204
    /// See also the [`Bernoulli`] distribution, which may be faster if
205
    /// sampling from the same `numerator` and `denominator` repeatedly.
206
    ///
207
    /// # Panics
208
    ///
209
    /// If `denominator == 0` or `numerator > denominator`.
210
    ///
211
    /// # Example
212
    ///
213
    /// ```
214
    /// use rand::RngExt;
215
    ///
216
    /// let mut rng = rand::rng();
217
    /// println!("{}", rng.random_ratio(2, 3));
218
    /// ```
219
    ///
220
    /// [`Bernoulli`]: distr::Bernoulli
221
    #[inline]
222
    #[track_caller]
223
0
    fn random_ratio(&mut self, numerator: u32, denominator: u32) -> bool {
224
0
        match distr::Bernoulli::from_ratio(numerator, denominator) {
225
0
            Ok(d) => self.sample(d),
226
0
            Err(_) => panic!(
227
0
                "p={}/{} is outside range [0.0, 1.0]",
228
                numerator, denominator
229
            ),
230
        }
231
0
    }
232
233
    /// Sample a new value, using the given distribution.
234
    ///
235
    /// ### Example
236
    ///
237
    /// ```
238
    /// use rand::RngExt;
239
    /// use rand::distr::Uniform;
240
    ///
241
    /// let mut rng = rand::rng();
242
    /// let x = rng.sample(Uniform::new(10u32, 15).unwrap());
243
    /// // Type annotation requires two types, the type and distribution; the
244
    /// // distribution can be inferred.
245
    /// let y = rng.sample::<u16, _>(Uniform::new(10, 15).unwrap());
246
    /// ```
247
0
    fn sample<T, D: Distribution<T>>(&mut self, distr: D) -> T {
248
0
        distr.sample(self)
249
0
    }
250
251
    /// Create an iterator that generates values using the given distribution.
252
    ///
253
    /// Note: this method consumes its arguments. Use
254
    /// `(&mut rng).sample_iter(..)` to avoid consuming the RNG.
255
    ///
256
    /// # Example
257
    ///
258
    /// ```
259
    /// use rand::RngExt;
260
    /// use rand::distr::{Alphanumeric, Uniform, StandardUniform};
261
    ///
262
    /// let mut rng = rand::rng();
263
    ///
264
    /// // Vec of 16 x f32:
265
    /// let v: Vec<f32> = (&mut rng).sample_iter(StandardUniform).take(16).collect();
266
    ///
267
    /// // String:
268
    /// let s: String = (&mut rng).sample_iter(Alphanumeric)
269
    ///     .take(7)
270
    ///     .map(char::from)
271
    ///     .collect();
272
    ///
273
    /// // Combined values
274
    /// println!("{:?}", (&mut rng).sample_iter(StandardUniform).take(5)
275
    ///                              .collect::<Vec<(f64, bool)>>());
276
    ///
277
    /// // Dice-rolling:
278
    /// let die_range = Uniform::new_inclusive(1, 6).unwrap();
279
    /// let mut roll_die = (&mut rng).sample_iter(die_range);
280
    /// while roll_die.next().unwrap() != 6 {
281
    ///     println!("Not a 6; rolling again!");
282
    /// }
283
    /// ```
284
0
    fn sample_iter<T, D>(self, distr: D) -> distr::Iter<D, Self, T>
285
0
    where
286
0
        D: Distribution<T>,
287
0
        Self: Sized,
288
    {
289
0
        distr.sample_iter(self)
290
0
    }
291
292
    /// Fill any type implementing [`Fill`] with random data
293
    ///
294
    /// This method is implemented for types which may be safely reinterpreted
295
    /// as an (aligned) `[u8]` slice then filled with random data. It is often
296
    /// faster than using [`RngExt::random`] but not value-equivalent.
297
    ///
298
    /// The distribution is expected to be uniform with portable results, but
299
    /// this cannot be guaranteed for third-party implementations.
300
    ///
301
    /// # Example
302
    ///
303
    /// ```
304
    /// use rand::RngExt;
305
    ///
306
    /// let mut arr = [0i8; 20];
307
    /// rand::rng().fill(&mut arr[..]);
308
    /// ```
309
    ///
310
    /// [`fill_bytes`]: Rng::fill_bytes
311
    #[track_caller]
312
0
    fn fill<T: Fill>(&mut self, dest: &mut [T]) {
313
0
        Fill::fill_slice(dest, self)
314
0
    }
315
}
316
317
impl<R: Rng + ?Sized> RngExt for R {}
318
319
/// Support filling a slice with random data
320
///
321
/// This trait allows slices of "plain data" types to be efficiently filled
322
/// with random data.
323
///
324
/// Implementations are expected to be portable across machines unless
325
/// clearly documented otherwise (see the
326
/// [Chapter on Portability](https://rust-random.github.io/book/portability.html)).
327
/// The implementations provided achieve this by byte-swapping on big-endian
328
/// machines.
329
pub trait Fill: Sized {
330
    /// Fill this with random data
331
    fn fill_slice<R: Rng + ?Sized>(this: &mut [Self], rng: &mut R);
332
}
333
334
impl Fill for u8 {
335
0
    fn fill_slice<R: Rng + ?Sized>(this: &mut [Self], rng: &mut R) {
336
0
        rng.fill_bytes(this)
337
0
    }
338
}
339
340
/// Call target for unsafe macros
341
0
const unsafe fn __unsafe() {}
342
343
/// Implement `Fill` for given type `$t`.
344
///
345
/// # Safety
346
/// All bit patterns of `[u8; size_of::<$t>()]` must represent values of `$t`.
347
macro_rules! impl_fill {
348
    () => {};
349
    (to_le! plain $x:ident) => {
350
        $x.to_le()
351
    };
352
    (to_le! wrapping $x:ident) => {
353
        Wrapping($x.0.to_le())
354
    };
355
    (fill_slice! $t:ty, $to_le:tt) => {
356
0
        fn fill_slice<R: Rng + ?Sized>(this: &mut [Self], rng: &mut R) {
357
0
            if this.len() > 0 {
358
0
                let size = mem::size_of_val(this);
359
0
                rng.fill_bytes(
360
                    // SAFETY: `this` non-null and valid for reads and writes within its `size`
361
                    // bytes. `this` meets the alignment requirements of `&mut [u8]`.
362
                    // The contents of `this` are initialized. Both `[u8]` and `[$t]` are valid
363
                    // for all bit-patterns of their contents (note that the SAFETY requirement
364
                    // on callers of this macro). `this` is not borrowed.
365
                    unsafe {
366
0
                        slice::from_raw_parts_mut(this.as_mut_ptr()
367
0
                            as *mut u8,
368
0
                            size
369
0
                        )
370
                    }
371
                );
372
0
                for x in this {
373
0
                    *x = impl_fill!(to_le! $to_le x);
374
0
                }
375
0
            }
376
0
        }
Unexecuted instantiation: <u16 as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <i8 as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <u32 as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <i16 as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <core::num::wrapping::Wrapping<u32> as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <core::num::wrapping::Wrapping<i16> as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <u64 as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <i32 as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <core::num::wrapping::Wrapping<u64> as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <core::num::wrapping::Wrapping<i32> as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <u128 as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <i64 as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <core::num::wrapping::Wrapping<u128> as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <core::num::wrapping::Wrapping<i64> as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <i128 as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <core::num::wrapping::Wrapping<i128> as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <core::num::wrapping::Wrapping<u16> as rand::rng::Fill>::fill_slice::<_>
Unexecuted instantiation: <core::num::wrapping::Wrapping<i8> as rand::rng::Fill>::fill_slice::<_>
377
    };
378
    ($t:ty) => {{
379
        // Force caller to wrap with an `unsafe` block
380
        __unsafe();
381
382
        impl Fill for $t {
383
            impl_fill!(fill_slice! $t, plain);
384
        }
385
386
        impl Fill for Wrapping<$t> {
387
            impl_fill!(fill_slice! $t, wrapping);
388
        }}
389
    };
390
    ($t:ty, $($tt:ty,)*) => {{
391
        impl_fill!($t);
392
        // TODO: this could replace above impl once Rust #32463 is fixed
393
        // impl_fill!(Wrapping<$t>);
394
        impl_fill!($($tt,)*);
395
    }}
396
}
397
398
// SAFETY: All bit patterns of `[u8; size_of::<$t>()]` represent values of `u*`.
399
const _: () = unsafe { impl_fill!(u16, u32, u64, u128,) };
400
// SAFETY: All bit patterns of `[u8; size_of::<$t>()]` represent values of `i*`.
401
const _: () = unsafe { impl_fill!(i8, i16, i32, i64, i128,) };
402
403
#[cfg(test)]
404
mod test {
405
    use super::*;
406
    use crate::test::{const_rng, rng};
407
    #[cfg(feature = "alloc")]
408
    use alloc::boxed::Box;
409
410
    #[test]
411
    fn test_fill_bytes_default() {
412
        let mut r = const_rng(0x11_22_33_44_55_66_77_88);
413
414
        // check every remainder mod 8, both in small and big vectors.
415
        let lengths = [0, 1, 2, 3, 4, 5, 6, 7, 80, 81, 82, 83, 84, 85, 86, 87];
416
        for &n in lengths.iter() {
417
            let mut buffer = [0u8; 87];
418
            let v = &mut buffer[0..n];
419
            r.fill_bytes(v);
420
421
            // use this to get nicer error messages.
422
            for (i, &byte) in v.iter().enumerate() {
423
                if byte == 0 {
424
                    panic!("byte {} of {} is zero", i, n)
425
                }
426
            }
427
        }
428
    }
429
430
    #[test]
431
    fn test_fill() {
432
        let x = 9041086907909331047; // a random u64
433
        let mut rng = const_rng(x);
434
435
        // Convert to byte sequence and back to u64; byte-swap twice if BE.
436
        let mut array = [0u64; 2];
437
        rng.fill(&mut array);
438
        assert_eq!(array, [x, x]);
439
        assert_eq!(rng.next_u64(), x);
440
441
        // Convert to bytes then u32 in LE order
442
        let mut array = [0u32; 2];
443
        rng.fill(&mut array);
444
        assert_eq!(array, [x as u32, (x >> 32) as u32]);
445
        assert_eq!(rng.next_u32(), x as u32);
446
447
        // Check equivalence using wrapped arrays
448
        let mut warray = [Wrapping(0u32); 2];
449
        rng.fill(&mut warray);
450
        assert_eq!(array[0], warray[0].0);
451
        assert_eq!(array[1], warray[1].0);
452
    }
453
454
    #[test]
455
    fn test_fill_empty() {
456
        let mut array = [0u32; 0];
457
        let mut rng = rng(1);
458
        rng.fill(&mut array);
459
        rng.fill(&mut array[..]);
460
    }
461
462
    #[test]
463
    fn test_random_range_int() {
464
        let mut r = rng(101);
465
        for _ in 0..1000 {
466
            let a = r.random_range(-4711..17);
467
            assert!((-4711..17).contains(&a));
468
            let a: i8 = r.random_range(-3..42);
469
            assert!((-3..42).contains(&a));
470
            let a: u16 = r.random_range(10..99);
471
            assert!((10..99).contains(&a));
472
            let a: i32 = r.random_range(-100..2000);
473
            assert!((-100..2000).contains(&a));
474
            let a: u32 = r.random_range(12..=24);
475
            assert!((12..=24).contains(&a));
476
477
            assert_eq!(r.random_range(..1u32), 0u32);
478
            assert_eq!(r.random_range(-12i64..-11), -12i64);
479
            assert_eq!(r.random_range(3_000_000..3_000_001), 3_000_000);
480
        }
481
    }
482
483
    #[test]
484
    fn test_random_range_float() {
485
        let mut r = rng(101);
486
        for _ in 0..1000 {
487
            let a = r.random_range(-4.5..1.7);
488
            assert!((-4.5..1.7).contains(&a));
489
            let a = r.random_range(-1.1..=-0.3);
490
            assert!((-1.1..=-0.3).contains(&a));
491
492
            assert_eq!(r.random_range(0.0f32..=0.0), 0.);
493
            assert_eq!(r.random_range(-11.0..=-11.0), -11.);
494
            assert_eq!(r.random_range(3_000_000.0..=3_000_000.0), 3_000_000.);
495
        }
496
    }
497
498
    #[test]
499
    #[should_panic]
500
    #[allow(clippy::reversed_empty_ranges)]
501
    fn test_random_range_panic_int() {
502
        let mut r = rng(102);
503
        r.random_range(5..-2);
504
    }
505
506
    #[test]
507
    #[should_panic]
508
    #[allow(clippy::reversed_empty_ranges)]
509
    fn test_random_range_panic_usize() {
510
        let mut r = rng(103);
511
        r.random_range(5..2);
512
    }
513
514
    #[test]
515
    #[allow(clippy::bool_assert_comparison)]
516
    fn test_random_bool() {
517
        let mut r = rng(105);
518
        for _ in 0..5 {
519
            assert_eq!(r.random_bool(0.0), false);
520
            assert_eq!(r.random_bool(1.0), true);
521
        }
522
    }
523
524
    #[test]
525
    fn test_rng_mut_ref() {
526
        fn use_rng(mut r: impl RngExt) {
527
            let _ = r.next_u32();
528
        }
529
530
        let mut rng = rng(109);
531
        use_rng(&mut rng);
532
    }
533
534
    #[test]
535
    fn test_rng_trait_object() {
536
        use crate::distr::{Distribution, StandardUniform};
537
        let mut rng = rng(109);
538
        let mut r = &mut rng as &mut dyn Rng;
539
        r.next_u32();
540
        r.random::<i32>();
541
        assert_eq!(r.random_range(0..1), 0);
542
        let _c: u8 = StandardUniform.sample(&mut r);
543
    }
544
545
    #[test]
546
    #[cfg(feature = "alloc")]
547
    fn test_rng_boxed_trait() {
548
        use crate::distr::{Distribution, StandardUniform};
549
        let rng = rng(110);
550
        let mut r = Box::new(rng) as Box<dyn Rng>;
551
        r.next_u32();
552
        r.random::<i32>();
553
        assert_eq!(r.random_range(0..1), 0);
554
        let _c: u8 = StandardUniform.sample(&mut r);
555
    }
556
557
    #[test]
558
    #[cfg_attr(miri, ignore)] // Miri is too slow
559
    fn test_gen_ratio_average() {
560
        const NUM: u32 = 3;
561
        const DENOM: u32 = 10;
562
        const N: u32 = 100_000;
563
564
        let mut sum: u32 = 0;
565
        let mut rng = rng(111);
566
        for _ in 0..N {
567
            if rng.random_ratio(NUM, DENOM) {
568
                sum += 1;
569
            }
570
        }
571
        // Have Binomial(N, NUM/DENOM) distribution
572
        let expected = (NUM * N) / DENOM; // exact integer
573
        assert!(((sum - expected) as i32).abs() < 500);
574
    }
575
}