Skip to content

Commit 8113b3e

Browse files
committed
Move asserts from Uniform to UniformSampler
1 parent 0541239 commit 8113b3e

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

src/distributions/uniform.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@
5050
//!
5151
//! At a minimum, the back-end needs to store any parameters needed for sampling
5252
//! (e.g. the target range) and implement `new`, `new_inclusive` and `sample`.
53-
//! The example below merely wraps another back-end.
53+
//! Those methods should include an assert to check the range is valid (i.e.
54+
//! `low < high`). The example below merely wraps another back-end.
5455
//!
5556
//! ```
5657
//! use rand::{Rng, thread_rng};
@@ -163,21 +164,18 @@ impl<X: SampleUniform> Uniform<X> {
163164
/// Create a new `Uniform` instance which samples uniformly from the half
164165
/// open range `[low, high)` (excluding `high`). Panics if `low >= high`.
165166
pub fn new(low: X, high: X) -> Uniform<X> {
166-
assert!(low < high, "Uniform::new called with `low >= high`");
167167
Uniform { inner: X::Sampler::new(low, high) }
168168
}
169169

170170
/// Create a new `Uniform` instance which samples uniformly from the closed
171171
/// range `[low, high]` (inclusive). Panics if `low > high`.
172172
pub fn new_inclusive(low: X, high: X) -> Uniform<X> {
173-
assert!(low <= high, "Uniform::new_inclusive called with `low > high`");
174173
Uniform { inner: X::Sampler::new_inclusive(low, high) }
175174
}
176175

177176
/// Sample a single value uniformly from `[low, high)`.
178177
/// Panics if `low >= high`.
179178
pub fn sample_single<R: Rng + ?Sized>(low: X, high: X, rng: &mut R) -> X {
180-
assert!(low < high, "Uniform::sample_single called with low >= high");
181179
X::Sampler::sample_single(low, high, rng)
182180
}
183181
}
@@ -197,7 +195,7 @@ impl<X: SampleUniform> Distribution<X> for Uniform<X> {
197195
/// [`UniformSampler`]: trait.UniformSampler.html
198196
/// [module documentation]: index.html
199197
/// [`Uniform`]: struct.Uniform.html
200-
pub trait SampleUniform: PartialOrd+Sized {
198+
pub trait SampleUniform: Sized {
201199
/// The `UniformSampler` implementation supporting type `X`.
202200
type Sampler: UniformSampler<X = Self>;
203201
}
@@ -215,7 +213,7 @@ pub trait SampleUniform: PartialOrd+Sized {
215213
/// [`sample_single`]: trait.UniformSampler.html#method.sample_single
216214
pub trait UniformSampler: Sized {
217215
/// The type sampled by this implementation.
218-
type X: PartialOrd;
216+
type X;
219217

220218
/// Construct self, with inclusive lower bound and exclusive upper bound
221219
/// `[low, high)`.
@@ -322,12 +320,16 @@ macro_rules! uniform_int_impl {
322320
#[inline] // if the range is constant, this helps LLVM to do the
323321
// calculations at compile-time.
324322
fn new(low: Self::X, high: Self::X) -> Self {
323+
assert!(low < high,
324+
"Uniform::new_inclusive called with `low >= high`");
325325
UniformSampler::new_inclusive(low, high - 1)
326326
}
327327

328328
#[inline] // if the range is constant, this helps LLVM to do the
329329
// calculations at compile-time.
330330
fn new_inclusive(low: Self::X, high: Self::X) -> Self {
331+
assert!(low <= high,
332+
"Uniform::new_inclusive called with `low > high`");
331333
let unsigned_max: $u_large = ::core::$u_large::MAX;
332334

333335
let range = (high as $u_large)
@@ -375,6 +377,8 @@ macro_rules! uniform_int_impl {
375377
high: Self::X,
376378
rng: &mut R) -> Self::X
377379
{
380+
assert!(low < high,
381+
"Uniform::sample_single called with low >= high");
378382
let range = (high as $u_large)
379383
.wrapping_sub(low as $u_large);
380384
let zone =
@@ -551,6 +555,7 @@ macro_rules! uniform_float_impl {
551555
type X = $ty;
552556

553557
fn new(low: Self::X, high: Self::X) -> Self {
558+
assert!(low < high, "Uniform::new called with `low >= high`");
554559
let scale = high - low;
555560
let offset = low - scale;
556561
UniformFloat {
@@ -560,7 +565,13 @@ macro_rules! uniform_float_impl {
560565
}
561566

562567
fn new_inclusive(low: Self::X, high: Self::X) -> Self {
563-
UniformSampler::new(low, high)
568+
assert!(low <= high, "Uniform::new called with `low > high`");
569+
let scale = high - low;
570+
let offset = low - scale;
571+
UniformFloat {
572+
scale: scale,
573+
offset: offset,
574+
}
564575
}
565576

566577
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
@@ -578,6 +589,8 @@ macro_rules! uniform_float_impl {
578589
fn sample_single<R: Rng + ?Sized>(low: Self::X,
579590
high: Self::X,
580591
rng: &mut R) -> Self::X {
592+
assert!(low < high,
593+
"Uniform::sample_single called with low >= high");
581594
let scale = high - low;
582595
let offset = low - scale;
583596
// Generate a value in the range [1, 2)
@@ -631,11 +644,13 @@ impl UniformSampler for UniformDuration {
631644

632645
#[inline]
633646
fn new(low: Duration, high: Duration) -> UniformDuration {
647+
assert!(low < high, "Uniform::new called with `low >= high`");
634648
UniformDuration::new_inclusive(low, high - Duration::new(0, 1))
635649
}
636650

637651
#[inline]
638652
fn new_inclusive(low: Duration, high: Duration) -> UniformDuration {
653+
assert!(low <= high, "Uniform::new called with `low > high`");
639654
let size = high - low;
640655
let nanos = size
641656
.as_secs()

0 commit comments

Comments
 (0)