forked from mirror/async-std
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
|
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
|
/// Add additional context to errors
|
||||||
pub(crate) trait Context {
|
pub(crate) trait Context {
|
||||||
fn context(self, message: impl Fn() -> String) -> Self;
|
fn context(self, message: impl Fn() -> String) -> Self;
|
||||||
|
|
Loading…
Reference in a new issue