Skip to content

Commit 4da919d

Browse files
authored
Merge pull request #382 from vks/from-range
Implement From<std::ops::Range> for Range
2 parents 95ea68c + 3756720 commit 4da919d

File tree

1 file changed

+29
-4
lines changed

1 file changed

+29
-4
lines changed

src/distributions/range.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use distributions::float::IntoFloat;
4242
/// use rand::distributions::{Distribution, Range};
4343
///
4444
/// fn main() {
45-
/// let between = Range::new(10, 10000);
45+
/// let between = Range::from(10..10000);
4646
/// let mut rng = rand::thread_rng();
4747
/// let mut sum = 0;
4848
/// for _ in 0..1000 {
@@ -173,6 +173,9 @@ pub trait RangeImpl: Sized {
173173
}
174174

175175
/// Implementation of `RangeImpl` for integer types.
176+
///
177+
/// Unless you are implementing `RangeImpl` for your own type, this type should
178+
/// not be used directly, use `Range` instead.
176179
#[derive(Clone, Copy, Debug)]
177180
pub struct RangeInt<X> {
178181
low: X,
@@ -317,6 +320,12 @@ macro_rules! range_int_impl {
317320
}
318321
}
319322

323+
impl<X: SampleRange> From<::core::ops::Range<X>> for Range<X> {
324+
fn from(r: ::core::ops::Range<X>) -> Range<X> {
325+
Range::new(r.start, r.end)
326+
}
327+
}
328+
320329
range_int_impl! { i8, i8, u8, i32, u32 }
321330
range_int_impl! { i16, i16, u16, i32, u32 }
322331
range_int_impl! { i32, i32, u32, i32, u32 }
@@ -420,6 +429,9 @@ wmul_impl_usize! { u64 }
420429

421430

422431
/// Implementation of `RangeImpl` for float types.
432+
///
433+
/// Unless you are implementing `RangeImpl` for your own type, this type should
434+
/// not be used directly, use `Range` instead.
423435
#[derive(Clone, Copy, Debug)]
424436
pub struct RangeFloat<X> {
425437
scale: X,
@@ -454,8 +466,11 @@ macro_rules! range_float_impl {
454466
// Generate a value in the range [1, 2)
455467
let value1_2 = (rng.$next_u() >> $bits_to_discard)
456468
.into_float_with_exponent(0);
457-
// Doing multiply before addition allows some architectures to
458-
// use a single instruction.
469+
// We don't use `f64::mul_add`, because it is not available with
470+
// `no_std`. Furthermore, it is slower for some targets (but
471+
// faster for others). However, the order of multiplication and
472+
// addition is important, because on some platforms (e.g. ARM)
473+
// it will be optimized to a single (non-FMA) instruction.
459474
value1_2 * self.scale + self.offset
460475
}
461476
}
@@ -469,7 +484,7 @@ range_float_impl! { f64, 64 - 52, next_u64 }
469484
#[cfg(test)]
470485
mod tests {
471486
use Rng;
472-
use distributions::range::{Range, RangeImpl, RangeFloat, SampleRange};
487+
use distributions::range::{Range, RangeImpl, RangeInt, RangeFloat, SampleRange};
473488

474489
#[should_panic]
475490
#[test]
@@ -578,4 +593,14 @@ mod tests {
578593
assert!(low <= x && x < high);
579594
}
580595
}
596+
597+
#[test]
598+
fn test_range_from_std_range() {
599+
let r = Range::from(2u32..7);
600+
assert_eq!(r.inner.low, 2);
601+
assert_eq!(r.inner.range, 5);
602+
let r = Range::from(2.0f64..7.0);
603+
assert_eq!(r.inner.offset, -3.0);
604+
assert_eq!(r.inner.scale, 5.0);
605+
}
581606
}

0 commit comments

Comments
 (0)