Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions rand_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ impl<'a, R: CryptoRng + ?Sized> CryptoRng for &'a mut R {}

// Implement `CryptoRng` for boxed references to a `CryptoRng`.
#[cfg(feature = "alloc")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
impl<R: CryptoRng + ?Sized> CryptoRng for Box<R> {}

#[cfg(test)]
Expand Down
1 change: 1 addition & 0 deletions src/distributions/distribution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ where
/// Sampling a `String` of random characters is not quite the same as collecting
/// a sequence of chars. This trait contains some helpers.
#[cfg(feature = "alloc")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
pub trait DistString {
/// Append `len` random chars to `string`
fn append_string<R: Rng + ?Sized>(&self, rng: &mut R, string: &mut String, len: usize);
Expand Down
26 changes: 22 additions & 4 deletions src/distributions/integer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,11 @@ impl_nzint!(NonZeroI128, NonZeroI128::new);
impl_nzint!(NonZeroIsize, NonZeroIsize::new);

macro_rules! x86_intrinsic_impl {
($($intrinsic:ident),+) => {$(
/// Available only on x86/64 platforms
($meta:meta, $doc:literal, $($intrinsic:ident),+) => {$(
#[doc = $doc]
#[cfg($meta)]
// TODO: as doc_cfg/doc_auto_cfg mature ensure they catch this
#[cfg_attr(doc_cfg, doc(cfg($meta)))]
Comment thread
dhardy marked this conversation as resolved.
Outdated
impl Distribution<$intrinsic> for Standard {
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> $intrinsic {
Expand All @@ -146,6 +149,9 @@ macro_rules! simd_impl {
/// Requires nightly Rust and the [`simd_support`] feature
///
/// [`simd_support`]: https://github.com/rust-random/rand#crate-features
#[cfg(feature = "simd_support")]
// TODO: as doc_cfg/doc_auto_cfg mature ensure they catch this
#[cfg_attr(doc_cfg, doc(cfg(feature = "simd_support")))]
impl<const LANES: usize> Distribution<Simd<$ty, LANES>> for Standard
where
LaneCount<LANES>: SupportedLaneCount,
Expand All @@ -164,12 +170,24 @@ macro_rules! simd_impl {
simd_impl!(u8, i8, u16, i16, u32, i32, u64, i64, usize, isize);

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
x86_intrinsic_impl!(__m128i, __m256i);
x86_intrinsic_impl!(
any(target_arch = "x86", target_arch = "x86_64"),
"Requires x86/64",
__m128i,
__m256i
);
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
feature = "simd_support"
))]
x86_intrinsic_impl!(__m512i);
x86_intrinsic_impl!(
all(
any(target_arch = "x86", target_arch = "x86_64"),
feature = "simd_support"
),
"Requires x86/64 and `simd_support`",
__m512i
);

#[cfg(test)]
mod tests {
Expand Down
1 change: 1 addition & 0 deletions src/distributions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ pub mod uniform;
pub use self::bernoulli::{Bernoulli, BernoulliError};
pub use self::distribution::{Distribution, DistIter, DistMap};
#[cfg(feature = "alloc")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
pub use self::distribution::DistString;
pub use self::float::{Open01, OpenClosed01};
pub use self::other::Alphanumeric;
Expand Down
3 changes: 3 additions & 0 deletions src/distributions/other.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ impl Distribution<char> for Standard {
/// Note: the `String` is potentially left with excess capacity; optionally the
/// user may call `string.shrink_to_fit()` afterwards.
#[cfg(feature = "alloc")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
impl DistString for Standard {
fn append_string<R: Rng + ?Sized>(&self, rng: &mut R, s: &mut String, len: usize) {
// A char is encoded with at most four bytes, thus this reservation is
Expand Down Expand Up @@ -128,6 +129,7 @@ impl Distribution<u8> for Alphanumeric {
}

#[cfg(feature = "alloc")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
impl DistString for Alphanumeric {
fn append_string<R: Rng + ?Sized>(&self, rng: &mut R, string: &mut String, len: usize) {
unsafe {
Expand Down Expand Up @@ -177,6 +179,7 @@ impl Distribution<bool> for Standard {
/// [`_mm_blendv_epi8`]: https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_blendv_epi8&ig_expand=514/
/// [`simd_support`]: https://github.com/rust-random/rand#crate-features
#[cfg(feature = "simd_support")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "simd_support")))]
impl<T, const LANES: usize> Distribution<Mask<T, LANES>> for Standard
where
T: MaskElement + Default,
Expand Down
1 change: 1 addition & 0 deletions src/distributions/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ impl std::error::Error for EmptySlice {}
/// Note: the `String` is potentially left with excess capacity; optionally the
/// user may call `string.shrink_to_fit()` afterwards.
#[cfg(feature = "alloc")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
impl<'a> super::DistString for Slice<'a, char> {
fn append_string<R: crate::Rng + ?Sized>(&self, rng: &mut R, string: &mut String, len: usize) {
// Get the max char length to minimize extra space.
Expand Down
50 changes: 36 additions & 14 deletions src/distributions/uniform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ macro_rules! uniform_int_impl {

let (mut result, mut lo) = rng.gen::<$sample_ty>().wmul(range);

// In constrast to the biased sampler, we use a loop:
// In contrast to the biased sampler, we use a loop:
while lo > range.wrapping_neg() {
let (new_hi, new_lo) = (rng.gen::<$sample_ty>()).wmul(range);
match lo.checked_add(new_hi) {
Expand Down Expand Up @@ -652,6 +652,13 @@ macro_rules! uniform_simd_int_impl {
// know the PRNG's minimal output size, and casting to a larger vector
// is generally a bad idea for SIMD performance. The user can still
// implement it manually.

/// Requires nightly Rust and the [`simd_support`] feature
///
/// [`simd_support`]: https://github.com/rust-random/rand#crate-features
#[cfg(feature = "simd_support")]
// TODO: as doc_cfg/doc_auto_cfg mature ensure they catch this
#[cfg_attr(doc_cfg, doc(cfg(feature = "simd_support")))]
impl<const LANES: usize> SampleUniform for Simd<$ty, LANES>
where
LaneCount<LANES>: SupportedLaneCount,
Expand All @@ -662,6 +669,12 @@ macro_rules! uniform_simd_int_impl {
type Sampler = UniformInt<Simd<$ty, LANES>>;
}

/// Requires nightly Rust and the [`simd_support`] feature
///
/// [`simd_support`]: https://github.com/rust-random/rand#crate-features
#[cfg(feature = "simd_support")]
// TODO: as doc_cfg/doc_auto_cfg mature ensure they catch this
#[cfg_attr(doc_cfg, doc(cfg(feature = "simd_support")))]
impl<const LANES: usize> UniformSampler for UniformInt<Simd<$ty, LANES>>
where
LaneCount<LANES>: SupportedLaneCount,
Expand Down Expand Up @@ -839,11 +852,12 @@ impl UniformSampler for UniformChar {
}
}

/// Note: the `String` is potentially left with excess capacity if the range
/// includes non ascii chars; optionally the user may call
/// Note: the `String` is potentially left with excess capacity if the range
/// includes non ascii chars; optionally the user may call
/// `string.shrink_to_fit()` afterwards.
#[cfg(feature = "alloc")]
impl super::DistString for Uniform<char>{
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
impl super::DistString for Uniform<char> {
fn append_string<R: Rng + ?Sized>(&self, rng: &mut R, string: &mut alloc::string::String, len: usize) {
// Getting the hi value to assume the required length to reserve in string.
let mut hi = self.0.sampler.low + self.0.sampler.range - 1;
Expand Down Expand Up @@ -884,11 +898,19 @@ pub struct UniformFloat<X> {
}

macro_rules! uniform_float_impl {
($ty:ty, $uty:ident, $f_scalar:ident, $u_scalar:ident, $bits_to_discard:expr) => {
($($meta:meta, $doc:literal)?, $ty:ty, $uty:ident, $f_scalar:ident, $u_scalar:ident, $bits_to_discard:expr) => {
$(#[doc = $doc]
#[cfg(feature = "simd_support")]
// TODO: as doc_cfg/doc_auto_cfg mature ensure they catch this
#[cfg_attr(doc_cfg, doc(cfg(feature = "simd_support")))])?
impl SampleUniform for $ty {
type Sampler = UniformFloat<$ty>;
}

$(#[doc = $doc]
#[cfg(feature = "simd_support")]
// TODO: as doc_cfg/doc_auto_cfg mature ensure they catch this
#[cfg_attr(doc_cfg, doc(cfg(feature = "simd_support")))])?
Comment thread
dhardy marked this conversation as resolved.
Outdated
impl UniformSampler for UniformFloat<$ty> {
type X = $ty;

Expand Down Expand Up @@ -1088,24 +1110,24 @@ macro_rules! uniform_float_impl {
};
}

uniform_float_impl! { f32, u32, f32, u32, 32 - 23 }
uniform_float_impl! { f64, u64, f64, u64, 64 - 52 }
uniform_float_impl! { , f32, u32, f32, u32, 32 - 23 }
uniform_float_impl! { , f64, u64, f64, u64, 64 - 52 }

#[cfg(feature = "simd_support")]
uniform_float_impl! { f32x2, u32x2, f32, u32, 32 - 23 }
uniform_float_impl! { feature = "simd_support", "Requires `simd_support`", f32x2, u32x2, f32, u32, 32 - 23 }
#[cfg(feature = "simd_support")]
uniform_float_impl! { f32x4, u32x4, f32, u32, 32 - 23 }
uniform_float_impl! { feature = "simd_support", "Requires `simd_support`", f32x4, u32x4, f32, u32, 32 - 23 }
#[cfg(feature = "simd_support")]
uniform_float_impl! { f32x8, u32x8, f32, u32, 32 - 23 }
uniform_float_impl! { feature = "simd_support", "Requires `simd_support`", f32x8, u32x8, f32, u32, 32 - 23 }
#[cfg(feature = "simd_support")]
uniform_float_impl! { f32x16, u32x16, f32, u32, 32 - 23 }
uniform_float_impl! { feature = "simd_support", "Requires `simd_support`", f32x16, u32x16, f32, u32, 32 - 23 }

#[cfg(feature = "simd_support")]
uniform_float_impl! { f64x2, u64x2, f64, u64, 64 - 52 }
uniform_float_impl! { feature = "simd_support", "Requires `simd_support`", f64x2, u64x2, f64, u64, 64 - 52 }
#[cfg(feature = "simd_support")]
uniform_float_impl! { f64x4, u64x4, f64, u64, 64 - 52 }
uniform_float_impl! { feature = "simd_support", "Requires `simd_support`", f64x4, u64x4, f64, u64, 64 - 52 }
#[cfg(feature = "simd_support")]
uniform_float_impl! { f64x8, u64x8, f64, u64, 64 - 52 }
uniform_float_impl! { feature = "simd_support", "Requires `simd_support`", f64x8, u64x8, f64, u64, 64 - 52 }


/// The back-end implementing [`UniformSampler`] for `Duration`.
Expand Down
13 changes: 7 additions & 6 deletions src/seq/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -637,17 +637,17 @@ impl<T> SliceRandom for [T] {
// for an unbiased permutation.
// It ensures that the last `amount` elements of the slice
// are randomly selected from the whole slice.
//`IncreasingUniform::next_index()` is faster than `gen_index`
//but only works for 32 bit integers
//So we must use the slow method if the slice is longer than that.

// `IncreasingUniform::next_index()` is faster than `gen_index`
// but only works for 32 bit integers
// So we must use the slow method if the slice is longer than that.
if self.len() < (u32::MAX as usize) {
let mut chooser = IncreasingUniform::new(rng, m as u32);
for i in m..self.len() {
let index = chooser.next_index();
self.swap(i, index);
}
} else {
} else {
for i in m..self.len() {
let index = gen_index(rng, i + 1);
self.swap(i, index);
Expand All @@ -674,6 +674,7 @@ pub struct SliceChooseIter<'a, S: ?Sized + 'a, T: 'a> {
}

#[cfg(feature = "alloc")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
impl<'a, S: Index<usize, Output = T> + ?Sized + 'a, T: 'a> Iterator for SliceChooseIter<'a, S, T> {
Comment on lines 676 to 678

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't show up anywhere because SliceChooseIter is already cfg(feature = "alloc") and Iterator is not a local trait.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth leaving it here in case rustdoc picks it up later?

type Item = &'a T;

Expand All @@ -688,6 +689,7 @@ impl<'a, S: Index<usize, Output = T> + ?Sized + 'a, T: 'a> Iterator for SliceCho
}

#[cfg(feature = "alloc")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
impl<'a, S: Index<usize, Output = T> + ?Sized + 'a, T: 'a> ExactSizeIterator
for SliceChooseIter<'a, S, T>
{
Expand All @@ -701,7 +703,6 @@ impl<'a, S: Index<usize, Output = T> + ?Sized + 'a, T: 'a> ExactSizeIterator
// platforms.
#[inline]
fn gen_index<R: Rng + ?Sized>(rng: &mut R, ubound: usize) -> usize {

if ubound <= (core::u32::MAX as usize) {
rng.gen_range(0..ubound as u32) as usize
} else {
Expand Down