mirror of
https://github.com/async-rs/async-std.git
synced 2025-01-16 10:49:55 +00:00
bring back random
This commit is contained in:
parent
e082634b5e
commit
75ab7219df
1 changed files with 34 additions and 0 deletions
34
src/utils.rs
34
src/utils.rs
|
@ -20,6 +20,40 @@ pub fn abort_on_panic<T>(f: impl FnOnce() -> T) -> T {
|
|||
t
|
||||
}
|
||||
|
||||
/// Generates a random number in `0..n`.
|
||||
#[cfg(feature = "unstable")]
|
||||
pub fn random(n: u32) -> u32 {
|
||||
use std::cell::Cell;
|
||||
use std::num::Wrapping;
|
||||
|
||||
thread_local! {
|
||||
static RNG: Cell<Wrapping<u32>> = {
|
||||
// Take the address of a local value as seed.
|
||||
let mut x = 0i32;
|
||||
let r = &mut x;
|
||||
let addr = r as *mut i32 as usize;
|
||||
Cell::new(Wrapping(addr as u32))
|
||||
}
|
||||
}
|
||||
|
||||
RNG.with(|rng| {
|
||||
// This is the 32-bit variant of Xorshift.
|
||||
//
|
||||
// Source: https://en.wikipedia.org/wiki/Xorshift
|
||||
let mut x = rng.get();
|
||||
x ^= x << 13;
|
||||
x ^= x >> 17;
|
||||
x ^= x << 5;
|
||||
rng.set(x);
|
||||
|
||||
// This is a fast alternative to `x % n`.
|
||||
//
|
||||
// Author: Daniel Lemire
|
||||
// Source: https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
|
||||
((u64::from(x.0)).wrapping_mul(u64::from(n)) >> 32) as u32
|
||||
})
|
||||
}
|
||||
|
||||
/// Add additional context to errors
|
||||
pub(crate) trait Context {
|
||||
fn context(self, message: impl Fn() -> String) -> Self;
|
||||
|
|
Loading…
Reference in a new issue