Skip to content

Commit

Permalink
Use const_generics to impl Fill for array types (feature flag)
Browse files Browse the repository at this point in the history
Uses the experimental nightly feature to produce a more
generic impl.
Note: we cannot yet do the same for Standard (see #939).
  • Loading branch information
dhardy committed Feb 28, 2020
1 parent d66d4d1 commit bb0a356
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 21 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Expand Up @@ -23,7 +23,7 @@ appveyor = { repository = "rust-random/rand" }
[features]
# Meta-features:
default = ["std"] # without "std" rand uses libcore
nightly = ["simd_support"] # enables all features requiring nightly rust
nightly = ["const_generics", "simd_support"] # enables all features requiring nightly rust
serde1 = [] # does nothing, deprecated

# Optional dependencies:
Expand All @@ -37,6 +37,7 @@ stdweb = ["getrandom_package/stdweb"]
getrandom = ["getrandom_package", "rand_core/getrandom"]

# Configuration:
const_generics = [] # nightly feature
simd_support = ["packed_simd"] # enables SIMD support
small_rng = ["rand_pcg"] # enables SmallRng

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Expand Up @@ -50,6 +50,7 @@
#![doc(test(attr(allow(unused_variables), deny(warnings))))]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(all(feature = "simd_support", feature = "nightly"), feature(stdsimd))]
#![cfg_attr(feature = "const_generics", feature(const_generics))]
#![allow(
clippy::excessive_precision,
clippy::unreadable_literal,
Expand Down
52 changes: 32 additions & 20 deletions src/rng.rs
Expand Up @@ -383,28 +383,40 @@ impl_fill!(i8, i16, i32, i64, isize,);
#[cfg(not(target_os = "emscripten"))]
impl_fill!(i128);

macro_rules! impl_fill_arrays {
($n:expr,) => {};
($n:expr, $N:ident) => {
impl<T> Fill for [T; $n] where [T]: Fill {
fn try_fill<R: Rng + ?Sized>(&mut self, rng: &mut R) -> Result<(), Error> {
self[..].try_fill(rng)
}
}
};
($n:expr, $N:ident, $($NN:ident,)*) => {
impl_fill_arrays!($n, $N);
impl_fill_arrays!($n - 1, $($NN,)*);
};
(!div $n:expr,) => {};
(!div $n:expr, $N:ident, $($NN:ident,)*) => {
impl_fill_arrays!($n, $N);
impl_fill_arrays!(!div $n / 2, $($NN,)*);
};
#[cfg(feature = "const_generics")]
impl<T, const N: usize> Fill for [T; N] where [T]: Fill {
fn try_fill<R: Rng + ?Sized>(&mut self, rng: &mut R) -> Result<(), Error> {
self[..].try_fill(rng)
}
}

#[cfg(not(feature = "const_generics"))]
#[rustfmt::skip]
impl_fill_arrays!(32, N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,);
impl_fill_arrays!(!div 4096, N,N,N,N,N,N,N,);
mod impls {
use super::*;

macro_rules! impl_fill_arrays {
($n:expr,) => {};
($n:expr, $N:ident) => {
impl<T> Fill for [T; $n] where [T]: Fill {
fn try_fill<R: Rng + ?Sized>(&mut self, rng: &mut R) -> Result<(), Error> {
self[..].try_fill(rng)
}
}
};
($n:expr, $N:ident, $($NN:ident,)*) => {
impl_fill_arrays!($n, $N);
impl_fill_arrays!($n - 1, $($NN,)*);
};
(!div $n:expr,) => {};
(!div $n:expr, $N:ident, $($NN:ident,)*) => {
impl_fill_arrays!($n, $N);
impl_fill_arrays!(!div $n / 2, $($NN,)*);
};
}
impl_fill_arrays!(32, N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,);
impl_fill_arrays!(!div 4096, N,N,N,N,N,N,N,);
}

#[cfg(test)]
mod test {
Expand Down

0 comments on commit bb0a356

Please sign in to comment.