@@ -92,6 +92,7 @@ pub mod seq;
92
92
93
93
94
94
use core:: { mem, slice} ;
95
+ use core:: num:: Wrapping ;
95
96
use distributions:: { Distribution , Standard } ;
96
97
use distributions:: uniform:: { SampleUniform , UniformSampler , SampleBorrow } ;
97
98
@@ -135,8 +136,6 @@ use distributions::uniform::{SampleUniform, UniformSampler, SampleBorrow};
135
136
pub trait Rng : RngCore {
136
137
/// Return a random value supporting the [`Standard`] distribution.
137
138
///
138
- /// [`Standard`]: distributions::Standard
139
- ///
140
139
/// # Example
141
140
///
142
141
/// ```
@@ -147,6 +146,28 @@ pub trait Rng: RngCore {
147
146
/// println!("{}", x);
148
147
/// println!("{:?}", rng.gen::<(f64, bool)>());
149
148
/// ```
149
+ ///
150
+ /// # Arrays and tuples
151
+ ///
152
+ /// The `rng.gen()` method is able to generate arrays (up to 32 elements)
153
+ /// and tuples (up to 12 elements), so long as all element types can be
154
+ /// generated.
155
+ ///
156
+ /// For arrays of integers, especially for those with small element types
157
+ /// (< 64 bit), it will likely be faster to instead use [`Rng::fill`].
158
+ ///
159
+ /// ```
160
+ /// use rand::{thread_rng, Rng};
161
+ ///
162
+ /// let mut rng = thread_rng();
163
+ /// let tuple: (u8, i32, char) = rng.gen(); // arbitrary tuple support
164
+ ///
165
+ /// let arr1: [f32; 32] = rng.gen(); // array construction
166
+ /// let mut arr2 = [0u8; 128];
167
+ /// rng.fill(&mut arr2); // array fill
168
+ /// ```
169
+ ///
170
+ /// [`Standard`]: distributions::Standard
150
171
#[ inline]
151
172
fn gen < T > ( & mut self ) -> T
152
173
where Standard : Distribution < T > {
@@ -378,6 +399,7 @@ impl AsByteSliceMut for [u8] {
378
399
}
379
400
380
401
macro_rules! impl_as_byte_slice {
402
+ ( ) => { } ;
381
403
( $t: ty) => {
382
404
impl AsByteSliceMut for [ $t] {
383
405
fn as_byte_slice_mut( & mut self ) -> & mut [ u8 ] {
@@ -402,26 +424,47 @@ macro_rules! impl_as_byte_slice {
402
424
}
403
425
}
404
426
}
427
+
428
+ impl AsByteSliceMut for [ Wrapping <$t>] {
429
+ fn as_byte_slice_mut( & mut self ) -> & mut [ u8 ] {
430
+ if self . len( ) == 0 {
431
+ unsafe {
432
+ // must not use null pointer
433
+ slice:: from_raw_parts_mut( 0x1 as * mut u8 , 0 )
434
+ }
435
+ } else {
436
+ unsafe {
437
+ slice:: from_raw_parts_mut( self . as_mut_ptr( )
438
+ as * mut u8 ,
439
+ self . len( ) * mem:: size_of:: <$t>( )
440
+ )
441
+ }
442
+ }
443
+ }
444
+
445
+ fn to_le( & mut self ) {
446
+ for x in self {
447
+ * x = Wrapping ( x. 0 . to_le( ) ) ;
448
+ }
449
+ }
450
+ }
451
+ } ;
452
+ ( $t: ty, $( $tt: ty, ) * ) => {
453
+ impl_as_byte_slice!( $t) ;
454
+ // TODO: this could replace above impl once Rust #32463 is fixed
455
+ // impl_as_byte_slice!(Wrapping<$t>);
456
+ impl_as_byte_slice!( $( $tt, ) * ) ;
405
457
}
406
458
}
407
459
408
- impl_as_byte_slice ! ( u16 ) ;
409
- impl_as_byte_slice ! ( u32 ) ;
410
- impl_as_byte_slice ! ( u64 ) ;
460
+ impl_as_byte_slice ! ( u16 , u32 , u64 , usize , ) ;
411
461
#[ cfg( all( rustc_1_26, not( target_os = "emscripten" ) ) ) ] impl_as_byte_slice ! ( u128 ) ;
412
- impl_as_byte_slice ! ( usize ) ;
413
- impl_as_byte_slice ! ( i8 ) ;
414
- impl_as_byte_slice ! ( i16 ) ;
415
- impl_as_byte_slice ! ( i32 ) ;
416
- impl_as_byte_slice ! ( i64 ) ;
462
+ impl_as_byte_slice ! ( i8 , i16 , i32 , i64 , isize , ) ;
417
463
#[ cfg( all( rustc_1_26, not( target_os = "emscripten" ) ) ) ] impl_as_byte_slice ! ( i128 ) ;
418
- impl_as_byte_slice ! ( isize ) ;
419
464
420
465
macro_rules! impl_as_byte_slice_arrays {
421
466
( $n: expr, ) => { } ;
422
- ( $n: expr, $N: ident, $( $NN: ident, ) * ) => {
423
- impl_as_byte_slice_arrays!( $n - 1 , $( $NN, ) * ) ;
424
-
467
+ ( $n: expr, $N: ident) => {
425
468
impl <T > AsByteSliceMut for [ T ; $n] where [ T ] : AsByteSliceMut {
426
469
fn as_byte_slice_mut( & mut self ) -> & mut [ u8 ] {
427
470
self [ ..] . as_byte_slice_mut( )
@@ -432,25 +475,19 @@ macro_rules! impl_as_byte_slice_arrays {
432
475
}
433
476
}
434
477
} ;
478
+ ( $n: expr, $N: ident, $( $NN: ident, ) * ) => {
479
+ impl_as_byte_slice_arrays!( $n, $N) ;
480
+ impl_as_byte_slice_arrays!( $n - 1 , $( $NN, ) * ) ;
481
+ } ;
435
482
( !div $n: expr, ) => { } ;
436
483
( !div $n: expr, $N: ident, $( $NN: ident, ) * ) => {
484
+ impl_as_byte_slice_arrays!( $n, $N) ;
437
485
impl_as_byte_slice_arrays!( !div $n / 2 , $( $NN, ) * ) ;
438
-
439
- impl <T > AsByteSliceMut for [ T ; $n] where [ T ] : AsByteSliceMut {
440
- fn as_byte_slice_mut( & mut self ) -> & mut [ u8 ] {
441
- self [ ..] . as_byte_slice_mut( )
442
- }
443
-
444
- fn to_le( & mut self ) {
445
- self [ ..] . to_le( )
446
- }
447
- }
448
486
} ;
449
487
}
450
488
impl_as_byte_slice_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 , ) ;
451
489
impl_as_byte_slice_arrays ! ( !div 4096 , N , N , N , N , N , N , N , ) ;
452
490
453
-
454
491
/// Generates a random value using the thread-local random number generator.
455
492
///
456
493
/// This is simply a shortcut for `thread_rng().gen()`. See [`thread_rng`] for
@@ -548,6 +585,12 @@ mod test {
548
585
rng. fill ( & mut array[ ..] ) ;
549
586
assert_eq ! ( array, [ x as u32 , ( x >> 32 ) as u32 ] ) ;
550
587
assert_eq ! ( rng. next_u32( ) , x as u32 ) ;
588
+
589
+ // Check equivalence using wrapped arrays
590
+ let mut warray = [ Wrapping ( 0u32 ) ; 2 ] ;
591
+ rng. fill ( & mut warray[ ..] ) ;
592
+ assert_eq ! ( array[ 0 ] , warray[ 0 ] . 0 ) ;
593
+ assert_eq ! ( array[ 1 ] , warray[ 1 ] . 0 ) ;
551
594
}
552
595
553
596
#[ test]
0 commit comments