diff --git a/src/distributions/uniform.rs b/src/distributions/uniform.rs index 8fda0319fef..64dd6d4ce93 100644 --- a/src/distributions/uniform.rs +++ b/src/distributions/uniform.rs @@ -99,6 +99,8 @@ #[cfg(feature = "std")] use std::time::Duration; +use core::borrow::Borrow; + use Rng; use distributions::Distribution; @@ -229,12 +231,10 @@ pub trait UniformSampler: Sized { /// sampling only a single value from the specified range. The default /// implementation simply calls `UniformSampler::new` then `sample` on the /// result. - fn sample_single(low: Self::X, high: Self::X, rng: &mut R) + fn sample_single(low: B1, high: B2, rng: &mut R) -> Self::X - { - let uniform: Self = UniformSampler::new(low, high); - uniform.sample(rng) - } + where B1: Borrow + Sized, + B2: Borrow + Sized; } impl From<::core::ops::Range> for Uniform { @@ -362,10 +362,13 @@ macro_rules! uniform_int_impl { } } - fn sample_single(low: Self::X, - high: Self::X, - rng: &mut R) -> Self::X + fn sample_single(low_b: B1, high_b: B2, rng: &mut R) + -> Self::X + where B1: Borrow + Sized, + B2: Borrow + Sized { + let low = *low_b.borrow(); + let high = *high_b.borrow(); assert!(low < high, "Uniform::sample_single called with low >= high"); let range = high.wrapping_sub(low) as $unsigned as $u_large; @@ -565,9 +568,13 @@ macro_rules! uniform_float_impl { value1_2 * self.scale + self.offset } - fn sample_single(low: Self::X, - high: Self::X, - rng: &mut R) -> Self::X { + fn sample_single(low_b: B1, high_b: B2, rng: &mut R) + -> Self::X + where B1: Borrow + Sized, + B2: Borrow + Sized + { + let low = *low_b.borrow(); + let high = *high_b.borrow(); assert!(low < high, "Uniform::sample_single called with low >= high"); let scale = high - low; @@ -679,6 +686,15 @@ impl UniformSampler for UniformDuration { self.offset + d } + + fn sample_single(low: B1, high: B2, rng: &mut R) + -> Self::X + where B1: Borrow + Sized, + B2: Borrow + Sized + { + let uniform: Self = UniformSampler::new(*low.borrow(), *high.borrow()); + uniform.sample(rng) + } } #[cfg(test)] @@ -809,6 +825,7 @@ mod tests { #[test] fn test_custom_uniform() { + use core::borrow::Borrow; #[derive(Clone, Copy, PartialEq, PartialOrd)] struct MyF32 { x: f32, @@ -830,6 +847,13 @@ mod tests { fn sample(&self, rng: &mut R) -> Self::X { MyF32 { x: self.inner.sample(rng) } } + fn sample_single(low: B1, high: B2, rng: &mut R) + -> Self::X + where B1: Borrow + Sized, + B2: Borrow + Sized + { + Self::new(*low.borrow(), *high.borrow()).sample(rng) + } } impl SampleUniform for MyF32 { type Sampler = UniformMyF32; diff --git a/src/lib.rs b/src/lib.rs index 6d6d762b3cb..9f52cc247ef 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -300,10 +300,10 @@ pub mod isaac { use core::{mem, slice}; +use core::borrow::Borrow; use distributions::{Distribution, Standard}; use distributions::uniform::{SampleUniform, UniformSampler}; - /// An automatically-implemented extension trait on [`RngCore`] providing high-level /// generic methods for sampling values and other convenience methods. /// @@ -387,7 +387,9 @@ pub trait Rng: RngCore { /// ``` /// /// [`Uniform`]: distributions/uniform/struct.Uniform.html - fn gen_range(&mut self, low: T, high: T) -> T { + fn gen_range(&mut self, low: B1, high: B2) -> T + where B1: Borrow + Sized, + B2: Borrow + Sized { T::Sampler::sample_single(low, high, self) }