We already support generating [T; N] for Standard where T supports Standard and N ≤ 32 via a macro. It would be nice to replace this with a more generic implementation using const_generics.
There is a catch: our macro generates arrays via this syntax: [_rng.gen::<$t>(), $(_rng.gen::<$ts>()),*], but there is no equivalent const-generics literal. This leaves only a couple of options:
Use std::mem::MaybeUninit. This should work with code like this; currently it doesn't (I believe because of const_generics bugs):
#[cfg(feature = "const_generics")]impl<T,constN:usize>Distribution<[T;N]>forStandardwhereStandard:Distribution<T>{#[inline]fnsample<R:Rng + ?Sized>(&self,rng:&mutR) -> [T;N]{// We cannot have a safe implementation without some extra bound// allowing construction, e.g. `T: Default`, thus we use MaybeUninit.use core::mem::{MaybeUninit, transmute};// Use MaybeUninit as in element-by-element array example:// https://doc.rust-lang.org/std/mem/union.MaybeUninit.html#initializing-an-array-element-by-elementletmut r:[MaybeUninit<T>;N] = unsafe{MaybeUninit::uninit().assume_init()};for elem in&mut r[..]{*elem = MaybeUninit::new(rng.gen::<T>());}unsafe{transmute::<[MaybeUninit<T>;N],[T;N]>(r)}}}Use an extra bound like T: Default to allow construction of a temporary, then generate elt-by-elt.
If somehow Rust were to support FromIterator for array types, we could use iter::repeat(...).take(N).collect() — but I don't expect to see this happen any time soon (if ever).
Probably eventually we'll go for option (1), though it's a shame we'll need the unsafe code. For now, we do nothing.
We already support generating
[T; N]forStandardwhereTsupportsStandardandN ≤ 32via a macro. It would be nice to replace this with a more generic implementation usingconst_generics.There is a catch: our macro generates arrays via this syntax:
[_rng.gen::<$t>(), $(_rng.gen::<$ts>()),*], but there is no equivalent const-generics literal. This leaves only a couple of options:Use
std::mem::MaybeUninit. This should work with code like this; currently it doesn't (I believe because ofconst_genericsbugs):Use an extra bound like
T: Defaultto allow construction of a temporary, then generate elt-by-elt.If somehow Rust were to support
FromIteratorfor array types, we could useiter::repeat(...).take(N).collect()— but I don't expect to see this happen any time soon (if ever).Probably eventually we'll go for option (1), though it's a shame we'll need the
unsafecode. For now, we do nothing.