Skip to content

Commit c8745e7

Browse files
committed
Let gen_range support ..len and ..=len for unsigned ints
1 parent 4ce677e commit c8745e7

File tree

6 files changed

+50
-14
lines changed

6 files changed

+50
-14
lines changed

src/distr/uniform.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ mod other;
120120
pub use other::{UniformChar, UniformDuration};
121121

122122
use core::fmt;
123-
use core::ops::{Range, RangeInclusive};
123+
use core::ops::{Range, RangeInclusive, RangeTo, RangeToInclusive};
124124

125125
use crate::distr::Distribution;
126126
use crate::{Rng, RngCore};
@@ -439,6 +439,41 @@ impl<T: SampleUniform + PartialOrd> SampleRange<T> for RangeInclusive<T> {
439439
}
440440
}
441441

442+
macro_rules! impl_sample_range_u {
443+
($t:ty) => {
444+
impl SampleRange<$t> for RangeTo<$t> {
445+
#[inline]
446+
fn sample_single<R: RngCore + ?Sized>(self, rng: &mut R) -> Result<$t, Error> {
447+
<$t as SampleUniform>::Sampler::sample_single(0, self.end, rng)
448+
}
449+
450+
#[inline]
451+
fn is_empty(&self) -> bool {
452+
0 == self.end
453+
}
454+
}
455+
456+
impl SampleRange<$t> for RangeToInclusive<$t> {
457+
#[inline]
458+
fn sample_single<R: RngCore + ?Sized>(self, rng: &mut R) -> Result<$t, Error> {
459+
<$t as SampleUniform>::Sampler::sample_single_inclusive(0, self.end, rng)
460+
}
461+
462+
#[inline]
463+
fn is_empty(&self) -> bool {
464+
false
465+
}
466+
}
467+
};
468+
}
469+
470+
impl_sample_range_u!(u8);
471+
impl_sample_range_u!(u16);
472+
impl_sample_range_u!(u32);
473+
impl_sample_range_u!(u64);
474+
impl_sample_range_u!(u128);
475+
impl_sample_range_u!(usize);
476+
442477
#[cfg(test)]
443478
mod tests {
444479
use super::*;

src/rng.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ pub trait Rng: RngCore {
102102
/// made from the given range. See also the [`Uniform`] distribution
103103
/// type which may be faster if sampling from the same range repeatedly.
104104
///
105-
/// Only `gen_range(low..high)` and `gen_range(low..=high)` are supported.
105+
/// All types support `low..high_exclusive` and `low..=high` range syntax.
106+
/// Unsigned integer types also support `..high_exclusive` and `..=high` syntax.
106107
///
107108
/// # Panics
108109
///
@@ -116,13 +117,13 @@ pub trait Rng: RngCore {
116117
/// let mut rng = thread_rng();
117118
///
118119
/// // Exclusive range
119-
/// let n: u32 = rng.gen_range(0..10);
120+
/// let n: u32 = rng.gen_range(..10);
120121
/// println!("{}", n);
121122
/// let m: f64 = rng.gen_range(-40.0..1.3e5);
122123
/// println!("{}", m);
123124
///
124125
/// // Inclusive range
125-
/// let n: u32 = rng.gen_range(0..=10);
126+
/// let n: u32 = rng.gen_range(..=10);
126127
/// println!("{}", n);
127128
/// ```
128129
///
@@ -500,7 +501,7 @@ mod test {
500501
let a: u32 = r.gen_range(12..=24);
501502
assert!((12..=24).contains(&a));
502503

503-
assert_eq!(r.gen_range(0u32..1), 0u32);
504+
assert_eq!(r.gen_range(..1u32), 0u32);
504505
assert_eq!(r.gen_range(-12i64..-11), -12i64);
505506
assert_eq!(r.gen_range(3_000_000..3_000_001), 3_000_000);
506507
}

src/seq/index.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ where
434434
debug_assert!(amount <= length);
435435
let mut indices = Vec::with_capacity(amount as usize);
436436
for j in length - amount..length {
437-
let t = rng.gen_range(0..=j);
437+
let t = rng.gen_range(..=j);
438438
if let Some(pos) = indices.iter().position(|&x| x == t) {
439439
indices[pos] = j;
440440
}

src/seq/iterator.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub trait IteratorRandom: Iterator + Sized {
7070
return match lower {
7171
0 => None,
7272
1 => self.next(),
73-
_ => self.nth(rng.gen_range(0..lower)),
73+
_ => self.nth(rng.gen_range(..lower)),
7474
};
7575
}
7676

@@ -80,7 +80,7 @@ pub trait IteratorRandom: Iterator + Sized {
8080
// Continue until the iterator is exhausted
8181
loop {
8282
if lower > 1 {
83-
let ix = coin_flipper.rng.gen_range(0..lower + consumed);
83+
let ix = coin_flipper.rng.gen_range(..lower + consumed);
8484
let skip = if ix < lower {
8585
result = self.nth(ix);
8686
lower - (ix + 1)
@@ -203,7 +203,7 @@ pub trait IteratorRandom: Iterator + Sized {
203203

204204
// Continue, since the iterator was not exhausted
205205
for (i, elem) in self.enumerate() {
206-
let k = rng.gen_range(0..i + 1 + amount);
206+
let k = rng.gen_range(..i + 1 + amount);
207207
if let Some(slot) = buf.get_mut(k) {
208208
*slot = elem;
209209
}
@@ -239,7 +239,7 @@ pub trait IteratorRandom: Iterator + Sized {
239239
// If the iterator stops once, then so do we.
240240
if reservoir.len() == amount {
241241
for (i, elem) in self.enumerate() {
242-
let k = rng.gen_range(0..i + 1 + amount);
242+
let k = rng.gen_range(..i + 1 + amount);
243243
if let Some(slot) = reservoir.get_mut(k) {
244244
*slot = elem;
245245
}

src/seq/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub mod index {
6969
// Floyd's algorithm
7070
let mut indices = [0; N];
7171
for (i, j) in (len - N..len).enumerate() {
72-
let t = rng.gen_range(0..j + 1);
72+
let t = rng.gen_range(..j + 1);
7373
if let Some(pos) = indices[0..i].iter().position(|&x| x == t) {
7474
indices[pos] = j;
7575
}

src/seq/slice.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub trait IndexedRandom: Index<usize> {
5757
if self.is_empty() {
5858
None
5959
} else {
60-
Some(&self[rng.gen_range(0..self.len())])
60+
Some(&self[rng.gen_range(..self.len())])
6161
}
6262
}
6363

@@ -259,7 +259,7 @@ pub trait IndexedMutRandom: IndexedRandom + IndexMut<usize> {
259259
None
260260
} else {
261261
let len = self.len();
262-
Some(&mut self[rng.gen_range(0..len)])
262+
Some(&mut self[rng.gen_range(..len)])
263263
}
264264
}
265265

@@ -410,7 +410,7 @@ impl<T> SliceRandom for [T] {
410410
}
411411
} else {
412412
for i in m..self.len() {
413-
let index = rng.gen_range(0..i + 1);
413+
let index = rng.gen_range(..i + 1);
414414
self.swap(i, index);
415415
}
416416
}

0 commit comments

Comments
 (0)