@@ -200,13 +200,13 @@ pub trait IteratorRandom: Iterator + Sized {
200
200
let mut result = None ;
201
201
202
202
if upper == Some ( lower) {
203
- return if lower == 0 { None } else { self . nth ( rng . gen_range ( 0 , lower) ) } ;
203
+ return if lower == 0 { None } else { self . nth ( gen_index ( rng , lower) ) } ;
204
204
}
205
205
206
206
// Continue until the iterator is exhausted
207
207
loop {
208
208
if lower > 1 {
209
- let ix = rng . gen_range ( 0 , lower + consumed) ;
209
+ let ix = gen_index ( rng , lower + consumed) ;
210
210
let skip;
211
211
if ix < lower {
212
212
result = self . nth ( ix) ;
@@ -267,7 +267,7 @@ pub trait IteratorRandom: Iterator + Sized {
267
267
268
268
// Continue, since the iterator was not exhausted
269
269
for ( i, elem) in self . enumerate ( ) {
270
- let k = rng . gen_range ( 0 , i + 1 + amount) ;
270
+ let k = gen_index ( rng , i + 1 + amount) ;
271
271
if let Some ( slot) = buf. get_mut ( k) {
272
272
* slot = elem;
273
273
}
@@ -300,7 +300,7 @@ pub trait IteratorRandom: Iterator + Sized {
300
300
// If the iterator stops once, then so do we.
301
301
if reservoir. len ( ) == amount {
302
302
for ( i, elem) in self . enumerate ( ) {
303
- let k = rng . gen_range ( 0 , i + 1 + amount) ;
303
+ let k = gen_index ( rng , i + 1 + amount) ;
304
304
if let Some ( slot) = reservoir. get_mut ( k) {
305
305
* slot = elem;
306
306
}
@@ -323,7 +323,7 @@ impl<T> SliceRandom for [T] {
323
323
if self . is_empty ( ) {
324
324
None
325
325
} else {
326
- Some ( & self [ rng . gen_range ( 0 , self . len ( ) ) ] )
326
+ Some ( & self [ gen_index ( rng , self . len ( ) ) ] )
327
327
}
328
328
}
329
329
@@ -333,7 +333,7 @@ impl<T> SliceRandom for [T] {
333
333
None
334
334
} else {
335
335
let len = self . len ( ) ;
336
- Some ( & mut self [ rng . gen_range ( 0 , len) ] )
336
+ Some ( & mut self [ gen_index ( rng , len) ] )
337
337
}
338
338
}
339
339
@@ -390,7 +390,7 @@ impl<T> SliceRandom for [T] {
390
390
where R : Rng + ?Sized {
391
391
for i in ( 1 ..self . len ( ) ) . rev ( ) {
392
392
// invariant: elements with index > i have been locked in place.
393
- self . swap ( i, rng . gen_range ( 0 , i + 1 ) ) ;
393
+ self . swap ( i, gen_index ( rng , i + 1 ) ) ;
394
394
}
395
395
}
396
396
@@ -408,7 +408,7 @@ impl<T> SliceRandom for [T] {
408
408
409
409
for i in ( end..len) . rev ( ) {
410
410
// invariant: elements with index > i have been locked in place.
411
- self . swap ( i, rng . gen_range ( 0 , i + 1 ) ) ;
411
+ self . swap ( i, gen_index ( rng , i + 1 ) ) ;
412
412
}
413
413
let r = self . split_at_mut ( end) ;
414
414
( r. 1 , r. 0 )
@@ -451,6 +451,19 @@ impl<'a, S: Index<usize, Output = T> + ?Sized + 'a, T: 'a> ExactSizeIterator
451
451
}
452
452
453
453
454
+ // Sample a number uniformly between 0 and `ubound`. Uses 32-bit sampling where
455
+ // possible, primarily in order to produce the same output on 32-bit and 64-bit
456
+ // platforms.
457
+ #[ inline]
458
+ fn gen_index < R : Rng + ?Sized > ( rng : & mut R , ubound : usize ) -> usize {
459
+ if ubound <= ( core:: u32:: MAX as usize ) {
460
+ rng. gen_range ( 0 , ubound as u32 ) as usize
461
+ } else {
462
+ rng. gen_range ( 0 , ubound)
463
+ }
464
+ }
465
+
466
+
454
467
#[ cfg( test) ]
455
468
mod test {
456
469
use super :: * ;
0 commit comments