mirror of https://github.com/smol-rs/fastrand
parent
0e0209a77c
commit
61adc59cc6
48
src/lib.rs
48
src/lib.rs
|
@ -255,15 +255,7 @@ impl Rng {
|
|||
/// Creates a new random number generator.
|
||||
#[inline]
|
||||
pub fn new() -> Rng {
|
||||
Rng::with_seed({
|
||||
RNG.try_with(|rng| {
|
||||
let current = rng.replace(Rng(0));
|
||||
let mut restore = RestoreOnDrop { rng, current };
|
||||
|
||||
restore.current.gen_u64()
|
||||
})
|
||||
.unwrap_or(0x4d595df4d0f33173)
|
||||
})
|
||||
try_with_rng(Rng::fork).unwrap_or_else(|_| Rng::with_seed(0x4d595df4d0f33173))
|
||||
}
|
||||
|
||||
/// Creates a new random number generator with the initial seed.
|
||||
|
@ -276,6 +268,32 @@ impl Rng {
|
|||
rng
|
||||
}
|
||||
|
||||
/// Clones the generator by deterministically deriving a new generator based on the initial
|
||||
/// seed.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// // Seed two generators equally, and clone both of them.
|
||||
/// let mut base1 = fastrand::Rng::new();
|
||||
/// base1.seed(0x4d595df4d0f33173);
|
||||
/// base1.bool(); // Use the generator once.
|
||||
///
|
||||
/// let mut base2 = fastrand::Rng::new();
|
||||
/// base2.seed(0x4d595df4d0f33173);
|
||||
/// base2.bool(); // Use the generator once.
|
||||
///
|
||||
/// let mut rng1 = base1.clone();
|
||||
/// let mut rng2 = base2.clone();
|
||||
///
|
||||
/// assert_eq!(rng1.u64(..), rng2.u64(..), "the cloned generators are identical");
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use = "this creates a new instance of `Rng`"]
|
||||
pub fn fork(&mut self) -> Self {
|
||||
Rng::with_seed(self.gen_u64())
|
||||
}
|
||||
|
||||
/// Generates a random `char` in ranges a-z and A-Z.
|
||||
#[inline]
|
||||
pub fn alphabetic(&mut self) -> char {
|
||||
|
@ -609,6 +627,18 @@ fn with_rng<R>(f: impl FnOnce(&mut Rng) -> R) -> R {
|
|||
})
|
||||
}
|
||||
|
||||
/// Try to run an operation with the current thread-local generator.
|
||||
#[inline]
|
||||
fn try_with_rng<R>(f: impl FnOnce(&mut Rng) -> R) -> Result<R, std::thread::AccessError> {
|
||||
RNG.try_with(|rng| {
|
||||
let current = rng.replace(Rng(0));
|
||||
|
||||
let mut restore = RestoreOnDrop { rng, current };
|
||||
|
||||
f(&mut restore.current)
|
||||
})
|
||||
}
|
||||
|
||||
/// Make sure the original RNG is restored even on panic.
|
||||
struct RestoreOnDrop<'a> {
|
||||
rng: &'a Cell<Rng>,
|
||||
|
|
Loading…
Reference in New Issue