Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No usize except uniform #1487

Merged
merged 13 commits into from
Sep 9, 2024
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.
- Rename `rand::distributions` to `rand::distr` (#1470)
- The `serde1` feature has been renamed `serde` (#1477)
- Mark `WeightError`, `PoissonError`, `BinomialError` as `#[non_exhaustive]` (#1480).
- Add `UniformUsize` and use to make `Uniform` for `usize` portable (#1487)
- Remove support for generating `isize` and `usize` values with `Standard`, `Uniform` and `Fill` and usage as a `WeightedAliasIndex` weight (#1487)
- Require `Clone` and `AsRef` bound for `SeedableRng::Seed`. (#1491)

## [0.9.0-alpha.1] - 2024-03-18
Expand Down
2 changes: 1 addition & 1 deletion benches/benches/standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub fn bench(c: &mut Criterion) {
};
}

do_ty!(i8, i16, i32, i64, i128, isize);
do_ty!(i8, i16, i32, i64, i128);
do_ty!(f32, f64);
do_ty!(char);

Expand Down
1 change: 0 additions & 1 deletion rand_distr/src/weighted_alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,6 @@ impl_weight_for_int!(u64);
impl_weight_for_int!(u32);
impl_weight_for_int!(u16);
impl_weight_for_int!(u8);
impl_weight_for_int!(isize);
impl_weight_for_int!(i128);
impl_weight_for_int!(i64);
impl_weight_for_int!(i32);
Expand Down
36 changes: 3 additions & 33 deletions src/distr/integer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ use core::arch::x86_64::__m512i;
#[cfg(target_arch = "x86_64")]
use core::arch::x86_64::{__m128i, __m256i};
use core::num::{
NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU128, NonZeroU16,
NonZeroU32, NonZeroU64, NonZeroU8,
};
#[cfg(feature = "simd_support")]
use core::simd::*;
Expand Down Expand Up @@ -63,20 +63,6 @@ impl Distribution<u128> for Standard {
}
}

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 {
Expand All @@ -93,7 +79,6 @@ 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) => {
Expand All @@ -114,14 +99,12 @@ 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);

impl_nzint!(NonZeroI8, NonZeroI8::new);
impl_nzint!(NonZeroI16, NonZeroI16::new);
impl_nzint!(NonZeroI32, NonZeroI32::new);
impl_nzint!(NonZeroI64, NonZeroI64::new);
impl_nzint!(NonZeroI128, NonZeroI128::new);
impl_nzint!(NonZeroIsize, NonZeroIsize::new);

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
macro_rules! x86_intrinsic_impl {
Expand Down Expand Up @@ -163,7 +146,7 @@ macro_rules! simd_impl {
}

#[cfg(feature = "simd_support")]
simd_impl!(u8, i8, u16, i16, u32, i32, u64, i64, usize, isize);
simd_impl!(u8, i8, u16, i16, u32, i32, u64, i64);

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
x86_intrinsic_impl!(
Expand Down Expand Up @@ -191,14 +174,12 @@ mod tests {
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);
Expand Down Expand Up @@ -239,17 +220,6 @@ mod tests {
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]);
// Skip further i* types: they are simple reinterpretation of u* samples
Expand Down
35 changes: 3 additions & 32 deletions src/distr/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,11 @@

use core::num::NonZeroUsize;

use crate::distr::{Distribution, Uniform};
use crate::Rng;
use crate::distr::uniform::{UniformSampler, UniformUsize};
use crate::distr::Distribution;
#[cfg(feature = "alloc")]
use alloc::string::String;

#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
compile_error!("unsupported pointer width");

#[derive(Debug, Clone, Copy)]
enum UniformUsize {
U32(Uniform<u32>),
#[cfg(target_pointer_width = "64")]
U64(Uniform<u64>),
}

impl UniformUsize {
pub fn new(ubound: usize) -> Result<Self, super::uniform::Error> {
#[cfg(target_pointer_width = "64")]
if ubound > (u32::MAX as usize) {
return Uniform::new(0, ubound as u64).map(UniformUsize::U64);
}

Uniform::new(0, ubound as u32).map(UniformUsize::U32)
}

pub fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> usize {
match self {
UniformUsize::U32(uu) => uu.sample(rng) as usize,
#[cfg(target_pointer_width = "64")]
UniformUsize::U64(uu) => uu.sample(rng) as usize,
}
}
}

/// A distribution to sample items uniformly from a slice.
///
/// [`Slice::new`] constructs a distribution referencing a slice and uniformly
Expand Down Expand Up @@ -110,7 +81,7 @@ impl<'a, T> Slice<'a, T> {

Ok(Self {
slice,
range: UniformUsize::new(num_choices.get()).unwrap(),
range: UniformUsize::new(0, num_choices.get()).unwrap(),
num_choices,
})
}
Expand Down
45 changes: 37 additions & 8 deletions src/distr/uniform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,15 @@ pub use float::UniformFloat;
#[path = "uniform_int.rs"]
mod int;
#[doc(inline)]
pub use int::UniformInt;
pub use int::{UniformInt, UniformUsize};

#[path = "uniform_other.rs"]
mod other;
#[doc(inline)]
pub use other::{UniformChar, UniformDuration};

use core::fmt;
use core::ops::{Range, RangeInclusive};
use core::ops::{Range, RangeInclusive, RangeTo, RangeToInclusive};

use crate::distr::Distribution;
use crate::{Rng, RngCore};
Expand Down Expand Up @@ -439,6 +439,41 @@ impl<T: SampleUniform + PartialOrd> SampleRange<T> for RangeInclusive<T> {
}
}

macro_rules! impl_sample_range_u {
($t:ty) => {
impl SampleRange<$t> for RangeTo<$t> {
#[inline]
fn sample_single<R: RngCore + ?Sized>(self, rng: &mut R) -> Result<$t, Error> {
<$t as SampleUniform>::Sampler::sample_single(0, self.end, rng)
}

#[inline]
fn is_empty(&self) -> bool {
0 == self.end
}
}

impl SampleRange<$t> for RangeToInclusive<$t> {
#[inline]
fn sample_single<R: RngCore + ?Sized>(self, rng: &mut R) -> Result<$t, Error> {
<$t as SampleUniform>::Sampler::sample_single_inclusive(0, self.end, rng)
}

#[inline]
fn is_empty(&self) -> bool {
false
}
}
};
}

impl_sample_range_u!(u8);
impl_sample_range_u!(u16);
impl_sample_range_u!(u32);
impl_sample_range_u!(u64);
impl_sample_range_u!(u128);
impl_sample_range_u!(usize);

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -530,12 +565,6 @@ mod tests {
assert_eq!(&buf, expected_multiple);
}

// We test on a sub-set of types; possibly we should do more.
// TODO: SIMD types

test_samples(11u8, 219, &[17, 66, 214], &[181, 93, 165]);
test_samples(11u32, 219, &[17, 66, 214], &[181, 93, 165]);

test_samples(
0f32,
1e-2f32,
Expand Down
Loading