diff options
Diffstat (limited to 'vendor/fastrand/src/global_rng.rs')
-rw-r--r-- | vendor/fastrand/src/global_rng.rs | 218 |
1 files changed, 0 insertions, 218 deletions
diff --git a/vendor/fastrand/src/global_rng.rs b/vendor/fastrand/src/global_rng.rs deleted file mode 100644 index f994902..0000000 --- a/vendor/fastrand/src/global_rng.rs +++ /dev/null @@ -1,218 +0,0 @@ -//! A global, thread-local random number generator. - -use crate::Rng; - -use std::cell::Cell; -use std::ops::RangeBounds; - -// Chosen by fair roll of the dice. -const DEFAULT_RNG_SEED: u64 = 0xef6f79ed30ba75a; - -impl Default for Rng { - /// Initialize the `Rng` from the system's random number generator. - /// - /// This is equivalent to [`Rng::new()`]. - #[inline] - fn default() -> Rng { - Rng::new() - } -} - -impl Rng { - /// Creates a new random number generator. - #[inline] - pub fn new() -> Rng { - try_with_rng(Rng::fork).unwrap_or_else(|_| Rng::with_seed(0x4d595df4d0f33173)) - } -} - -thread_local! { - static RNG: Cell<Rng> = Cell::new(Rng(random_seed().unwrap_or(DEFAULT_RNG_SEED))); -} - -/// Run an operation with the current thread-local generator. -#[inline] -fn with_rng<R>(f: impl FnOnce(&mut Rng) -> R) -> R { - RNG.with(|rng| { - let current = rng.replace(Rng(0)); - - let mut restore = RestoreOnDrop { rng, current }; - - f(&mut restore.current) - }) -} - -/// 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>, - current: Rng, -} - -impl Drop for RestoreOnDrop<'_> { - fn drop(&mut self) { - self.rng.set(Rng(self.current.0)); - } -} - -/// Initializes the thread-local generator with the given seed. -#[inline] -pub fn seed(seed: u64) { - with_rng(|r| r.seed(seed)); -} - -/// Gives back **current** seed that is being held by the thread-local generator. -#[inline] -pub fn get_seed() -> u64 { - with_rng(|r| r.get_seed()) -} - -/// Generates a random `bool`. -#[inline] -pub fn bool() -> bool { - with_rng(|r| r.bool()) -} - -/// Generates a random `char` in ranges a-z and A-Z. -#[inline] -pub fn alphabetic() -> char { - with_rng(|r| r.alphabetic()) -} - -/// Generates a random `char` in ranges a-z, A-Z and 0-9. -#[inline] -pub fn alphanumeric() -> char { - with_rng(|r| r.alphanumeric()) -} - -/// Generates a random `char` in range a-z. -#[inline] -pub fn lowercase() -> char { - with_rng(|r| r.lowercase()) -} - -/// Generates a random `char` in range A-Z. -#[inline] -pub fn uppercase() -> char { - with_rng(|r| r.uppercase()) -} - -/// Choose an item from an iterator at random. -/// -/// This function may have an unexpected result if the `len()` property of the -/// iterator does not match the actual number of items in the iterator. If -/// the iterator is empty, this returns `None`. -#[inline] -pub fn choice<I>(iter: I) -> Option<I::Item> -where - I: IntoIterator, - I::IntoIter: ExactSizeIterator, -{ - with_rng(|r| r.choice(iter)) -} - -/// Generates a random digit in the given `base`. -/// -/// Digits are represented by `char`s in ranges 0-9 and a-z. -/// -/// Panics if the base is zero or greater than 36. -#[inline] -pub fn digit(base: u32) -> char { - with_rng(|r| r.digit(base)) -} - -/// Shuffles a slice randomly. -#[inline] -pub fn shuffle<T>(slice: &mut [T]) { - with_rng(|r| r.shuffle(slice)) -} - -macro_rules! integer { - ($t:tt, $doc:tt) => { - #[doc = $doc] - /// - /// Panics if the range is empty. - #[inline] - pub fn $t(range: impl RangeBounds<$t>) -> $t { - with_rng(|r| r.$t(range)) - } - }; -} - -integer!(u8, "Generates a random `u8` in the given range."); -integer!(i8, "Generates a random `i8` in the given range."); -integer!(u16, "Generates a random `u16` in the given range."); -integer!(i16, "Generates a random `i16` in the given range."); -integer!(u32, "Generates a random `u32` in the given range."); -integer!(i32, "Generates a random `i32` in the given range."); -integer!(u64, "Generates a random `u64` in the given range."); -integer!(i64, "Generates a random `i64` in the given range."); -integer!(u128, "Generates a random `u128` in the given range."); -integer!(i128, "Generates a random `i128` in the given range."); -integer!(usize, "Generates a random `usize` in the given range."); -integer!(isize, "Generates a random `isize` in the given range."); -integer!(char, "Generates a random `char` in the given range."); - -/// Generates a random `f32` in range `0..1`. -pub fn f32() -> f32 { - with_rng(|r| r.f32()) -} - -/// Generates a random `f64` in range `0..1`. -pub fn f64() -> f64 { - with_rng(|r| r.f64()) -} - -/// Collects `amount` values at random from the iterator into a vector. -pub fn choose_multiple<T: Iterator>(source: T, amount: usize) -> Vec<T::Item> { - with_rng(|rng| rng.choose_multiple(source, amount)) -} - -#[cfg(not(all( - any(target_arch = "wasm32", target_arch = "wasm64"), - target_os = "unknown" -)))] -fn random_seed() -> Option<u64> { - use std::collections::hash_map::DefaultHasher; - use std::hash::{Hash, Hasher}; - use std::thread; - use std::time::Instant; - - let mut hasher = DefaultHasher::new(); - Instant::now().hash(&mut hasher); - thread::current().id().hash(&mut hasher); - let hash = hasher.finish(); - Some((hash << 1) | 1) -} - -#[cfg(all( - any(target_arch = "wasm32", target_arch = "wasm64"), - target_os = "unknown", - feature = "js" -))] -fn random_seed() -> Option<u64> { - // TODO(notgull): Failures should be logged somewhere. - let mut seed = [0u8; 8]; - getrandom::getrandom(&mut seed).ok()?; - Some(u64::from_ne_bytes(seed)) -} - -#[cfg(all( - any(target_arch = "wasm32", target_arch = "wasm64"), - target_os = "unknown", - not(feature = "js") -))] -fn random_seed() -> Option<u64> { - None -} |