Skip to content

Commit bd44cd2

Browse files
committed
WIP
1 parent 1f9ce3a commit bd44cd2

File tree

1 file changed

+66
-1
lines changed

1 file changed

+66
-1
lines changed

src/lib.rs

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,13 @@ pub trait Sample: Rng {
446446
fn iter<'a>(&'a mut self) -> iter::Iter<'a, Self> {
447447
iter(self)
448448
}
449+
450+
fn fill_slice<T>(&mut self, slice: &mut [T])
451+
where [T]: FillSlice<T> + AsMut<[T]>,
452+
Default: Distribution<T>,
453+
Self: ::core::marker::Sized {
454+
FillSlice::fill_slice(self, slice.as_mut());
455+
}
449456
}
450457

451458
impl<R: Rng+?Sized> Sample for R {
@@ -493,10 +500,59 @@ impl SeedableRng for StdRng {
493500
}
494501

495502

503+
504+
pub trait FillSlice<T>: AsMut<[T]>
505+
where Default: Distribution<T> {
506+
fn fill_slice<R: Rng>(rng: &mut R, slice: &mut Self) {
507+
for i in slice.as_mut().iter_mut() {
508+
*i = rng.gen()
509+
}
510+
}
511+
}
512+
513+
macro_rules! impl_fill_slice {
514+
($ty:ty) => {
515+
impl FillSlice<$ty> for [$ty] {
516+
fn fill_slice<R: Rng>(rng: &mut R, slice: &mut Self) {
517+
// Fill as if this is an `u8` array.
518+
unsafe {
519+
// FIXME: are we violating pointer aliasing rules here?
520+
let len = slice.len() * ::core::mem::size_of::<$ty>();
521+
let ptr = slice.as_mut_ptr() as *mut u8;
522+
let slice_u8 = ::core::slice::from_raw_parts_mut(ptr, len);
523+
rng.fill_bytes(slice_u8);
524+
}
525+
// Fix endianness on Big-Endian architectures.
526+
for i in slice.iter_mut() {
527+
*i = i.to_le();
528+
}
529+
}
530+
}
531+
}
532+
}
533+
534+
impl_fill_slice! { i8 }
535+
impl_fill_slice! { i16 }
536+
impl_fill_slice! { i32 }
537+
impl_fill_slice! { i64 }
538+
#[cfg(feature = "i128_support")]
539+
impl_fill_slice! { i128 }
540+
impl_fill_slice! { isize }
541+
impl_fill_slice! { u8 }
542+
impl_fill_slice! { u16 }
543+
impl_fill_slice! { u32 }
544+
impl_fill_slice! { u64 }
545+
#[cfg(feature = "i128_support")]
546+
impl_fill_slice! { u128 }
547+
impl_fill_slice! { usize }
548+
549+
550+
551+
496552
#[cfg(test)]
497553
mod test {
498554
use {Rng, thread_rng, Sample, Error};
499-
use mock::MockAddRng;
555+
use mock::MockAddRng;
500556
use distributions::{Uniform, Range, Exp};
501557
use sequences::Shuffle;
502558
use std::iter::repeat;
@@ -613,4 +669,13 @@ mod test {
613669

614670
let _c = rng.sample(Exp::new(2.0));
615671
}
672+
673+
#[test]
674+
fn test_fill_slice() {
675+
use super::FillSlice;
676+
let mut rng = thread_rng();
677+
let mut array = [0u32; 100];
678+
rng.fill_slice(&mut array[..]);
679+
assert!(!array.iter().all(|&x| x == 0));
680+
}
616681
}

0 commit comments

Comments
 (0)