use crate::distributions::{Distribution, Standard};
use crate::Rng;
use core::num::{NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
NonZeroU128};
impl Distribution<u8> for Standard {
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u8 {
rng.next_u32() as u8
}
}
impl Distribution<u16> for Standard {
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u16 {
rng.next_u32() as u16
}
}
impl Distribution<u32> for Standard {
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u32 {
rng.next_u32()
}
}
impl Distribution<u64> for Standard {
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u64 {
rng.next_u64()
}
}
impl Distribution<u128> for Standard {
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u128 {
let x = u128::from(rng.next_u64());
let y = u128::from(rng.next_u64());
(y << 64) | x
}
}
impl Distribution<usize> for Standard {
#[inline]
#[cfg(any(target_pointer_width = "32", target_pointer_width = "16"))]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> usize {
rng.next_u32() as usize
}
#[inline]
#[cfg(target_pointer_width = "64")]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> usize {
rng.next_u64() as usize
}
}
macro_rules! impl_int_from_uint {
($ty:ty, $uty:ty) => {
impl Distribution<$ty> for Standard {
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $ty {
rng.gen::<$uty>() as $ty
}
}
};
}
impl_int_from_uint! { i8, u8 }
impl_int_from_uint! { i16, u16 }
impl_int_from_uint! { i32, u32 }
impl_int_from_uint! { i64, u64 }
impl_int_from_uint! { i128, u128 }
impl_int_from_uint! { isize, usize }
macro_rules! impl_nzint {
($ty:ty, $new:path) => {
impl Distribution<$ty> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $ty {
loop {
if let Some(nz) = $new(rng.gen()) {
break nz;
}
}
}
}
};
}
impl_nzint!(NonZeroU8, NonZeroU8::new);
impl_nzint!(NonZeroU16, NonZeroU16::new);
impl_nzint!(NonZeroU32, NonZeroU32::new);
impl_nzint!(NonZeroU64, NonZeroU64::new);
impl_nzint!(NonZeroU128, NonZeroU128::new);
impl_nzint!(NonZeroUsize, NonZeroUsize::new);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_integers() {
let mut rng = crate::test::rng(806);
rng.sample::<isize, _>(Standard);
rng.sample::<i8, _>(Standard);
rng.sample::<i16, _>(Standard);
rng.sample::<i32, _>(Standard);
rng.sample::<i64, _>(Standard);
rng.sample::<i128, _>(Standard);
rng.sample::<usize, _>(Standard);
rng.sample::<u8, _>(Standard);
rng.sample::<u16, _>(Standard);
rng.sample::<u32, _>(Standard);
rng.sample::<u64, _>(Standard);
rng.sample::<u128, _>(Standard);
}
#[test]
fn value_stability() {
fn test_samples<T: Copy + core::fmt::Debug + PartialEq>(zero: T, expected: &[T])
where Standard: Distribution<T> {
let mut rng = crate::test::rng(807);
let mut buf = [zero; 3];
for x in &mut buf {
*x = rng.sample(Standard);
}
assert_eq!(&buf, expected);
}
test_samples(0u8, &[9, 247, 111]);
test_samples(0u16, &[32265, 42999, 38255]);
test_samples(0u32, &[2220326409, 2575017975, 2018088303]);
test_samples(0u64, &[
11059617991457472009,
16096616328739788143,
1487364411147516184,
]);
test_samples(0u128, &[
296930161868957086625409848350820761097,
145644820879247630242265036535529306392,
111087889832015897993126088499035356354,
]);
#[cfg(any(target_pointer_width = "32", target_pointer_width = "16"))]
test_samples(0usize, &[2220326409, 2575017975, 2018088303]);
#[cfg(target_pointer_width = "64")]
test_samples(0usize, &[
11059617991457472009,
16096616328739788143,
1487364411147516184,
]);
test_samples(0i8, &[9, -9, 111]);
}
}