@@ -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
451458impl < 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) ]
497553mod 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