Skip to main content

rand/distr/
uniform.rs

1// Copyright 2018-2020 Developers of the Rand project.
2// Copyright 2017 The Rust Project Developers.
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9
10//! A distribution uniformly sampling numbers within a given range.
11//!
12//! [`Uniform`] is the standard distribution to sample uniformly from a range;
13//! e.g. `Uniform::new_inclusive(1, 6).unwrap()` can sample integers from 1 to 6, like a
14//! standard die. [`RngExt::random_range`] is implemented over [`Uniform`].
15//!
16//! # Example usage
17//!
18//! ```
19//! use rand::RngExt;
20//! use rand::distr::Uniform;
21//!
22//! let mut rng = rand::rng();
23//! let side = Uniform::new(-10.0, 10.0).unwrap();
24//!
25//! // sample between 1 and 10 points
26//! for _ in 0..rng.random_range(1..=10) {
27//!     // sample a point from the square with sides -10 - 10 in two dimensions
28//!     let (x, y) = (rng.sample(side), rng.sample(side));
29//!     println!("Point: {}, {}", x, y);
30//! }
31//! ```
32//!
33//! # Extending `Uniform` to support a custom type
34//!
35//! To extend [`Uniform`] to support your own types, write a back-end which
36//! implements the [`UniformSampler`] trait, then implement the [`SampleUniform`]
37//! helper trait to "register" your back-end. See the `MyF32` example below.
38//!
39//! At a minimum, the back-end needs to store any parameters needed for sampling
40//! (e.g. the target range) and implement `new`, `new_inclusive` and `sample`.
41//! Those methods should include an assertion to check the range is valid (i.e.
42//! `low < high`). The example below merely wraps another back-end.
43//!
44//! The `new`, `new_inclusive`, `sample_single` and `sample_single_inclusive`
45//! functions use arguments of
46//! type `SampleBorrow<X>` to support passing in values by reference or
47//! by value. In the implementation of these functions, you can choose to
48//! simply use the reference returned by [`SampleBorrow::borrow`], or you can choose
49//! to copy or clone the value, whatever is appropriate for your type.
50//!
51//! ```
52//! use rand::prelude::*;
53//! use rand::distr::uniform::{Uniform, SampleUniform,
54//!         UniformSampler, UniformFloat, SampleBorrow, Error};
55//!
56//! struct MyF32(f32);
57//!
58//! #[derive(Clone, Copy, Debug)]
59//! struct UniformMyF32(UniformFloat<f32>);
60//!
61//! impl UniformSampler for UniformMyF32 {
62//!     type X = MyF32;
63//!
64//!     fn new<B1, B2>(low: B1, high: B2) -> Result<Self, Error>
65//!         where B1: SampleBorrow<Self::X> + Sized,
66//!               B2: SampleBorrow<Self::X> + Sized
67//!     {
68//!         UniformFloat::<f32>::new(low.borrow().0, high.borrow().0).map(UniformMyF32)
69//!     }
70//!     fn new_inclusive<B1, B2>(low: B1, high: B2) -> Result<Self, Error>
71//!         where B1: SampleBorrow<Self::X> + Sized,
72//!               B2: SampleBorrow<Self::X> + Sized
73//!     {
74//!         UniformFloat::<f32>::new_inclusive(low.borrow().0, high.borrow().0).map(UniformMyF32)
75//!     }
76//!     fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
77//!         MyF32(self.0.sample(rng))
78//!     }
79//! }
80//!
81//! impl SampleUniform for MyF32 {
82//!     type Sampler = UniformMyF32;
83//! }
84//!
85//! let (low, high) = (MyF32(17.0f32), MyF32(22.0f32));
86//! let uniform = Uniform::new(low, high).unwrap();
87//! let x = uniform.sample(&mut rand::rng());
88//! ```
89//!
90//! [`SampleUniform`]: crate::distr::uniform::SampleUniform
91//! [`UniformSampler`]: crate::distr::uniform::UniformSampler
92//! [`UniformInt`]: crate::distr::uniform::UniformInt
93//! [`UniformFloat`]: crate::distr::uniform::UniformFloat
94//! [`UniformDuration`]: crate::distr::uniform::UniformDuration
95//! [`SampleBorrow::borrow`]: crate::distr::uniform::SampleBorrow::borrow
96
97#[path = "uniform_float.rs"]
98mod float;
99#[doc(inline)]
100pub use float::UniformFloat;
101
102#[path = "uniform_int.rs"]
103mod int;
104#[doc(inline)]
105pub use int::{UniformInt, UniformUsize};
106
107#[path = "uniform_other.rs"]
108mod other;
109#[doc(inline)]
110pub use other::{UniformChar, UniformDuration};
111
112use core::fmt;
113use core::ops::{Range, RangeInclusive, RangeTo, RangeToInclusive};
114
115use crate::Rng;
116use crate::distr::Distribution;
117
118#[cfg(doc)]
119use crate::RngExt;
120
121/// Error type returned from [`Uniform::new`] and `new_inclusive`.
122#[derive(#[automatically_derived]
impl ::core::clone::Clone for Error {
    #[inline]
    fn clone(&self) -> Error { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Error { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for Error {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                Error::EmptyRange => "EmptyRange",
                Error::NonFinite => "NonFinite",
            })
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for Error {
    #[inline]
    fn eq(&self, other: &Error) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Error {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) {}
}Eq)]
123pub enum Error {
124    /// `low > high`, or equal in case of exclusive range.
125    EmptyRange,
126    /// Input or range `high - low` is non-finite. Not relevant to integer types.
127    NonFinite,
128}
129
130impl fmt::Display for Error {
131    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132        f.write_str(match self {
133            Error::EmptyRange => "low > high (or equal if exclusive) in uniform distribution",
134            Error::NonFinite => "Non-finite range in uniform distribution",
135        })
136    }
137}
138
139impl core::error::Error for Error {}
140
141#[cfg(feature = "serde")]
142use serde::{Deserialize, Serialize};
143
144/// Sample values uniformly between two bounds.
145///
146/// # Construction
147///
148/// [`Uniform::new`] and [`Uniform::new_inclusive`] construct a uniform
149/// distribution sampling from the given `low` and `high` limits. `Uniform` may
150/// also be constructed via [`TryFrom`] as in `Uniform::try_from(1..=6).unwrap()`.
151///
152/// Constructors may do extra work up front to allow faster sampling of multiple
153/// values. Where only a single sample is required it is suggested to use
154/// [`Rng::random_range`] or one of the `sample_single` methods instead.
155///
156/// When sampling from a constant range, many calculations can happen at
157/// compile-time and all methods should be fast; for floating-point ranges and
158/// the full range of integer types, this should have comparable performance to
159/// the [`StandardUniform`](super::StandardUniform) distribution.
160///
161/// # Provided implementations
162///
163/// - `char` ([`UniformChar`]): samples a range over the implementation for `u32`
164/// - `f32`, `f64` ([`UniformFloat`]): samples approximately uniformly within a
165///   range; bias may be present in the least-significant bit of the significand
166///   and the limits of the input range may be sampled even when an open
167///   (exclusive) range is used
168/// - Integer types ([`UniformInt`]) may show a small bias relative to the
169///   expected uniform distribution of output. In the worst case, bias affects
170///   1 in `2^n` samples where n is 56 (`i8` and `u8`), 48 (`i16` and `u16`), 96
171///   (`i32` and `u32`), 64 (`i64` and `u64`), 128 (`i128` and `u128`).
172///   The `unbiased` feature flag fixes this bias.
173/// - `usize` ([`UniformUsize`]) is handled specially, using the `u32`
174///   implementation where possible to enable portable results across 32-bit and
175///   64-bit CPU architectures.
176/// - `Duration` ([`UniformDuration`]): samples a range over the implementation
177///   for `u32` or `u64`
178/// - SIMD types (requires [`simd_support`] feature) like x86's [`__m128i`]
179///   and `std::simd`'s [`u32x4`], [`f32x4`] and [`mask32x4`] types are
180///   effectively arrays of integer or floating-point types. Each lane is
181///   sampled independently from its own range, potentially with more efficient
182///   random-bit-usage than would be achieved with sequential sampling.
183///
184/// # Example
185///
186/// ```
187/// use rand::distr::{Distribution, Uniform};
188///
189/// let between = Uniform::try_from(10..10000).unwrap();
190/// let mut rng = rand::rng();
191/// let mut sum = 0;
192/// for _ in 0..1000 {
193///     sum += between.sample(&mut rng);
194/// }
195/// println!("{}", sum);
196/// ```
197///
198/// For a single sample, [`Rng::random_range`] may be preferred:
199///
200/// ```
201/// use rand::RngExt;
202///
203/// let mut rng = rand::rng();
204/// println!("{}", rng.random_range(0..10));
205/// ```
206///
207/// [`new`]: Uniform::new
208/// [`new_inclusive`]: Uniform::new_inclusive
209/// [`Rng::random_range`]: RngExt::random_range
210/// [`__m128i`]: https://doc.rust-lang.org/core/arch/x86/struct.__m128i.html
211/// [`u32x4`]: std::simd::u32x4
212/// [`f32x4`]: std::simd::f32x4
213/// [`mask32x4`]: std::simd::mask32x4
214/// [`simd_support`]: https://github.com/rust-random/rand#crate-features
215#[derive(#[automatically_derived]
impl<X: ::core::clone::Clone + SampleUniform> ::core::clone::Clone for
    Uniform<X> where X::Sampler: ::core::clone::Clone {
    #[inline]
    fn clone(&self) -> Uniform<X> {
        Uniform(::core::clone::Clone::clone(&self.0))
    }
}Clone, #[automatically_derived]
impl<X: ::core::marker::Copy + SampleUniform> ::core::marker::Copy for
    Uniform<X> where X::Sampler: ::core::marker::Copy {
}Copy, #[automatically_derived]
impl<X: ::core::fmt::Debug + SampleUniform> ::core::fmt::Debug for Uniform<X>
    where X::Sampler: ::core::fmt::Debug {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Uniform",
            &&self.0)
    }
}Debug, #[automatically_derived]
impl<X: ::core::cmp::PartialEq + SampleUniform> ::core::cmp::PartialEq for
    Uniform<X> where X::Sampler: ::core::cmp::PartialEq {
    #[inline]
    fn eq(&self, other: &Uniform<X>) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl<X: ::core::cmp::Eq + SampleUniform> ::core::cmp::Eq for Uniform<X> where
    X::Sampler: ::core::cmp::Eq {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<X::Sampler>;
    }
}Eq)]
216#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
217#[cfg_attr(feature = "serde", serde(bound(serialize = "X::Sampler: Serialize")))]
218#[cfg_attr(
219    feature = "serde",
220    serde(bound(deserialize = "X::Sampler: Deserialize<'de>"))
221)]
222pub struct Uniform<X: SampleUniform>(X::Sampler);
223
224impl<X: SampleUniform> Uniform<X> {
225    /// Create a new `Uniform` instance, which samples uniformly from the half
226    /// open range `[low, high)` (excluding `high`).
227    ///
228    /// For discrete types (e.g. integers), samples will always be strictly less
229    /// than `high`. For (approximations of) continuous types (e.g. `f32`, `f64`),
230    /// samples may equal `high` due to loss of precision but may not be
231    /// greater than `high`.
232    ///
233    /// Fails if `low >= high`, or if `low`, `high` or the range `high - low` is
234    /// non-finite. In release mode, only the range is checked.
235    pub fn new<B1, B2>(low: B1, high: B2) -> Result<Uniform<X>, Error>
236    where
237        B1: SampleBorrow<X> + Sized,
238        B2: SampleBorrow<X> + Sized,
239    {
240        X::Sampler::new(low, high).map(Uniform)
241    }
242
243    /// Create a new `Uniform` instance, which samples uniformly from the closed
244    /// range `[low, high]` (inclusive).
245    ///
246    /// Fails if `low > high`, or if `low`, `high` or the range `high - low` is
247    /// non-finite. In release mode, only the range is checked.
248    pub fn new_inclusive<B1, B2>(low: B1, high: B2) -> Result<Uniform<X>, Error>
249    where
250        B1: SampleBorrow<X> + Sized,
251        B2: SampleBorrow<X> + Sized,
252    {
253        X::Sampler::new_inclusive(low, high).map(Uniform)
254    }
255}
256
257impl<X: SampleUniform> Distribution<X> for Uniform<X> {
258    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> X {
259        self.0.sample(rng)
260    }
261}
262
263/// Helper trait for creating objects using the correct implementation of
264/// [`UniformSampler`] for the sampling type.
265///
266/// See the [module documentation] on how to implement [`Uniform`] range
267/// sampling for a custom type.
268///
269/// [module documentation]: crate::distr::uniform
270pub trait SampleUniform: Sized {
271    /// The `UniformSampler` implementation supporting type `X`.
272    type Sampler: UniformSampler<X = Self>;
273}
274
275/// Helper trait handling actual uniform sampling.
276///
277/// See the [module documentation] on how to implement [`Uniform`] range
278/// sampling for a custom type.
279///
280/// Implementation of [`sample_single`] is optional, and is only useful when
281/// the implementation can be faster than `Self::new(low, high).sample(rng)`.
282///
283/// [module documentation]: crate::distr::uniform
284/// [`sample_single`]: UniformSampler::sample_single
285pub trait UniformSampler: Sized {
286    /// The type sampled by this implementation.
287    type X;
288
289    /// Construct self, with inclusive lower bound and exclusive upper bound `[low, high)`.
290    ///
291    /// For discrete types (e.g. integers), samples will always be strictly less
292    /// than `high`. For (approximations of) continuous types (e.g. `f32`, `f64`),
293    /// samples may equal `high` due to loss of precision but may not be
294    /// greater than `high`.
295    ///
296    /// Usually users should not call this directly but prefer to use
297    /// [`Uniform::new`].
298    fn new<B1, B2>(low: B1, high: B2) -> Result<Self, Error>
299    where
300        B1: SampleBorrow<Self::X> + Sized,
301        B2: SampleBorrow<Self::X> + Sized;
302
303    /// Construct self, with inclusive bounds `[low, high]`.
304    ///
305    /// Usually users should not call this directly but prefer to use
306    /// [`Uniform::new_inclusive`].
307    fn new_inclusive<B1, B2>(low: B1, high: B2) -> Result<Self, Error>
308    where
309        B1: SampleBorrow<Self::X> + Sized,
310        B2: SampleBorrow<Self::X> + Sized;
311
312    /// Sample a value.
313    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X;
314
315    /// Sample a single value uniformly from a range with inclusive lower bound
316    /// and exclusive upper bound `[low, high)`.
317    ///
318    /// For discrete types (e.g. integers), samples will always be strictly less
319    /// than `high`. For (approximations of) continuous types (e.g. `f32`, `f64`),
320    /// samples may equal `high` due to loss of precision but may not be
321    /// greater than `high`.
322    ///
323    /// By default this is implemented using
324    /// `UniformSampler::new(low, high).sample(rng)`. However, for some types
325    /// more optimal implementations for single usage may be provided via this
326    /// method (which is the case for integers and floats).
327    /// Results may not be identical.
328    ///
329    /// Note that to use this method in a generic context, the type needs to be
330    /// retrieved via `SampleUniform::Sampler` as follows:
331    /// ```
332    /// use rand::distr::uniform::{SampleUniform, UniformSampler};
333    /// # #[allow(unused)]
334    /// fn sample_from_range<T: SampleUniform>(lb: T, ub: T) -> T {
335    ///     let mut rng = rand::rng();
336    ///     <T as SampleUniform>::Sampler::sample_single(lb, ub, &mut rng).unwrap()
337    /// }
338    /// ```
339    fn sample_single<R: Rng + ?Sized, B1, B2>(
340        low: B1,
341        high: B2,
342        rng: &mut R,
343    ) -> Result<Self::X, Error>
344    where
345        B1: SampleBorrow<Self::X> + Sized,
346        B2: SampleBorrow<Self::X> + Sized,
347    {
348        let uniform: Self = UniformSampler::new(low, high)?;
349        Ok(uniform.sample(rng))
350    }
351
352    /// Sample a single value uniformly from a range with inclusive lower bound
353    /// and inclusive upper bound `[low, high]`.
354    ///
355    /// By default this is implemented using
356    /// `UniformSampler::new_inclusive(low, high).sample(rng)`. However, for
357    /// some types more optimal implementations for single usage may be provided
358    /// via this method.
359    /// Results may not be identical.
360    fn sample_single_inclusive<R: Rng + ?Sized, B1, B2>(
361        low: B1,
362        high: B2,
363        rng: &mut R,
364    ) -> Result<Self::X, Error>
365    where
366        B1: SampleBorrow<Self::X> + Sized,
367        B2: SampleBorrow<Self::X> + Sized,
368    {
369        let uniform: Self = UniformSampler::new_inclusive(low, high)?;
370        Ok(uniform.sample(rng))
371    }
372}
373
374impl<X: SampleUniform> TryFrom<Range<X>> for Uniform<X> {
375    type Error = Error;
376
377    fn try_from(r: Range<X>) -> Result<Uniform<X>, Error> {
378        Uniform::new(r.start, r.end)
379    }
380}
381
382impl<X: SampleUniform> TryFrom<RangeInclusive<X>> for Uniform<X> {
383    type Error = Error;
384
385    fn try_from(r: ::core::ops::RangeInclusive<X>) -> Result<Uniform<X>, Error> {
386        Uniform::new_inclusive(r.start(), r.end())
387    }
388}
389
390/// Helper trait similar to [`Borrow`] but implemented
391/// only for [`SampleUniform`] and references to [`SampleUniform`]
392/// in order to resolve ambiguity issues.
393///
394/// [`Borrow`]: std::borrow::Borrow
395pub trait SampleBorrow<Borrowed> {
396    /// Immutably borrows from an owned value. See [`Borrow::borrow`]
397    ///
398    /// [`Borrow::borrow`]: std::borrow::Borrow::borrow
399    fn borrow(&self) -> &Borrowed;
400}
401impl<Borrowed> SampleBorrow<Borrowed> for Borrowed
402where
403    Borrowed: SampleUniform,
404{
405    #[inline(always)]
406    fn borrow(&self) -> &Borrowed {
407        self
408    }
409}
410impl<Borrowed> SampleBorrow<Borrowed> for &Borrowed
411where
412    Borrowed: SampleUniform,
413{
414    #[inline(always)]
415    fn borrow(&self) -> &Borrowed {
416        self
417    }
418}
419
420/// Range that supports generating a single sample efficiently.
421///
422/// Any type implementing this trait can be used to specify the sampled range
423/// for `Rng::random_range`.
424pub trait SampleRange<T> {
425    /// Generate a sample from the given range.
426    fn sample_single<R: Rng + ?Sized>(self, rng: &mut R) -> Result<T, Error>;
427
428    /// Check whether the range is empty.
429    fn is_empty(&self) -> bool;
430}
431
432impl<T: SampleUniform + PartialOrd> SampleRange<T> for Range<T> {
433    #[inline]
434    fn sample_single<R: Rng + ?Sized>(self, rng: &mut R) -> Result<T, Error> {
435        T::Sampler::sample_single(self.start, self.end, rng)
436    }
437
438    #[inline]
439    fn is_empty(&self) -> bool {
440        !(self.start < self.end)
441    }
442}
443
444impl<T: SampleUniform + PartialOrd> SampleRange<T> for RangeInclusive<T> {
445    #[inline]
446    fn sample_single<R: Rng + ?Sized>(self, rng: &mut R) -> Result<T, Error> {
447        T::Sampler::sample_single_inclusive(self.start(), self.end(), rng)
448    }
449
450    #[inline]
451    fn is_empty(&self) -> bool {
452        !(self.start() <= self.end())
453    }
454}
455
456macro_rules! impl_sample_range_u {
457    ($t:ty) => {
458        impl SampleRange<$t> for RangeTo<$t> {
459            #[inline]
460            fn sample_single<R: Rng + ?Sized>(self, rng: &mut R) -> Result<$t, Error> {
461                <$t as SampleUniform>::Sampler::sample_single(0, self.end, rng)
462            }
463
464            #[inline]
465            fn is_empty(&self) -> bool {
466                0 == self.end
467            }
468        }
469
470        impl SampleRange<$t> for RangeToInclusive<$t> {
471            #[inline]
472            fn sample_single<R: Rng + ?Sized>(self, rng: &mut R) -> Result<$t, Error> {
473                <$t as SampleUniform>::Sampler::sample_single_inclusive(0, self.end, rng)
474            }
475
476            #[inline]
477            fn is_empty(&self) -> bool {
478                false
479            }
480        }
481    };
482}
483
484impl SampleRange<u8> for RangeTo<u8> {
    #[inline]
    fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
        -> Result<u8, Error> {
        <u8 as SampleUniform>::Sampler::sample_single(0, self.end, rng)
    }
    #[inline]
    fn is_empty(&self) -> bool { 0 == self.end }
}
impl SampleRange<u8> for RangeToInclusive<u8> {
    #[inline]
    fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
        -> Result<u8, Error> {
        <u8 as
                SampleUniform>::Sampler::sample_single_inclusive(0, self.end,
            rng)
    }
    #[inline]
    fn is_empty(&self) -> bool { false }
}impl_sample_range_u!(u8);
485impl SampleRange<u16> for RangeTo<u16> {
    #[inline]
    fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
        -> Result<u16, Error> {
        <u16 as SampleUniform>::Sampler::sample_single(0, self.end, rng)
    }
    #[inline]
    fn is_empty(&self) -> bool { 0 == self.end }
}
impl SampleRange<u16> for RangeToInclusive<u16> {
    #[inline]
    fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
        -> Result<u16, Error> {
        <u16 as
                SampleUniform>::Sampler::sample_single_inclusive(0, self.end,
            rng)
    }
    #[inline]
    fn is_empty(&self) -> bool { false }
}impl_sample_range_u!(u16);
486impl SampleRange<u32> for RangeTo<u32> {
    #[inline]
    fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
        -> Result<u32, Error> {
        <u32 as SampleUniform>::Sampler::sample_single(0, self.end, rng)
    }
    #[inline]
    fn is_empty(&self) -> bool { 0 == self.end }
}
impl SampleRange<u32> for RangeToInclusive<u32> {
    #[inline]
    fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
        -> Result<u32, Error> {
        <u32 as
                SampleUniform>::Sampler::sample_single_inclusive(0, self.end,
            rng)
    }
    #[inline]
    fn is_empty(&self) -> bool { false }
}impl_sample_range_u!(u32);
487impl SampleRange<u64> for RangeTo<u64> {
    #[inline]
    fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
        -> Result<u64, Error> {
        <u64 as SampleUniform>::Sampler::sample_single(0, self.end, rng)
    }
    #[inline]
    fn is_empty(&self) -> bool { 0 == self.end }
}
impl SampleRange<u64> for RangeToInclusive<u64> {
    #[inline]
    fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
        -> Result<u64, Error> {
        <u64 as
                SampleUniform>::Sampler::sample_single_inclusive(0, self.end,
            rng)
    }
    #[inline]
    fn is_empty(&self) -> bool { false }
}impl_sample_range_u!(u64);
488impl SampleRange<u128> for RangeTo<u128> {
    #[inline]
    fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
        -> Result<u128, Error> {
        <u128 as SampleUniform>::Sampler::sample_single(0, self.end, rng)
    }
    #[inline]
    fn is_empty(&self) -> bool { 0 == self.end }
}
impl SampleRange<u128> for RangeToInclusive<u128> {
    #[inline]
    fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
        -> Result<u128, Error> {
        <u128 as
                SampleUniform>::Sampler::sample_single_inclusive(0, self.end,
            rng)
    }
    #[inline]
    fn is_empty(&self) -> bool { false }
}impl_sample_range_u!(u128);
489impl SampleRange<usize> for RangeTo<usize> {
    #[inline]
    fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
        -> Result<usize, Error> {
        <usize as SampleUniform>::Sampler::sample_single(0, self.end, rng)
    }
    #[inline]
    fn is_empty(&self) -> bool { 0 == self.end }
}
impl SampleRange<usize> for RangeToInclusive<usize> {
    #[inline]
    fn sample_single<R: Rng + ?Sized>(self, rng: &mut R)
        -> Result<usize, Error> {
        <usize as
                SampleUniform>::Sampler::sample_single_inclusive(0, self.end,
            rng)
    }
    #[inline]
    fn is_empty(&self) -> bool { false }
}impl_sample_range_u!(usize);
490
491#[cfg(test)]
492mod tests {
493    use super::*;
494    use crate::RngExt;
495    use core::time::Duration;
496
497    #[test]
498    #[cfg(feature = "serde")]
499    fn test_uniform_serialization() {
500        let unit_box: Uniform<i32> = Uniform::new(-1, 1).unwrap();
501        let de_unit_box: Uniform<i32> =
502            postcard::from_bytes(&postcard::to_allocvec(&unit_box).unwrap()).unwrap();
503        assert_eq!(unit_box.0, de_unit_box.0);
504
505        let unit_box: Uniform<f32> = Uniform::new(-1., 1.).unwrap();
506        let de_unit_box: Uniform<f32> =
507            postcard::from_bytes(&postcard::to_allocvec(&unit_box).unwrap()).unwrap();
508        assert_eq!(unit_box.0, de_unit_box.0);
509    }
510
511    #[test]
512    fn test_custom_uniform() {
513        use crate::distr::uniform::{SampleBorrow, SampleUniform, UniformFloat, UniformSampler};
514        #[derive(Clone, Copy, PartialEq, PartialOrd)]
515        struct MyF32 {
516            x: f32,
517        }
518        #[derive(Clone, Copy, Debug)]
519        struct UniformMyF32(UniformFloat<f32>);
520        impl UniformSampler for UniformMyF32 {
521            type X = MyF32;
522
523            fn new<B1, B2>(low: B1, high: B2) -> Result<Self, Error>
524            where
525                B1: SampleBorrow<Self::X> + Sized,
526                B2: SampleBorrow<Self::X> + Sized,
527            {
528                UniformFloat::<f32>::new(low.borrow().x, high.borrow().x).map(UniformMyF32)
529            }
530
531            fn new_inclusive<B1, B2>(low: B1, high: B2) -> Result<Self, Error>
532            where
533                B1: SampleBorrow<Self::X> + Sized,
534                B2: SampleBorrow<Self::X> + Sized,
535            {
536                UniformSampler::new(low, high)
537            }
538
539            fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
540                MyF32 {
541                    x: self.0.sample(rng),
542                }
543            }
544        }
545        impl SampleUniform for MyF32 {
546            type Sampler = UniformMyF32;
547        }
548
549        let (low, high) = (MyF32 { x: 17.0f32 }, MyF32 { x: 22.0f32 });
550        let uniform = Uniform::new(low, high).unwrap();
551        let mut rng = crate::test::rng(804);
552        for _ in 0..100 {
553            let x: MyF32 = rng.sample(uniform);
554            assert!(low <= x && x < high);
555        }
556    }
557
558    #[test]
559    fn value_stability() {
560        fn test_samples<T: SampleUniform + Copy + fmt::Debug + PartialEq>(
561            lb: T,
562            ub: T,
563            expected_single: &[T],
564            expected_multiple: &[T],
565        ) where
566            Uniform<T>: Distribution<T>,
567        {
568            let mut rng = crate::test::rng(897);
569            let mut buf = [lb; 3];
570
571            for x in &mut buf {
572                *x = T::Sampler::sample_single(lb, ub, &mut rng).unwrap();
573            }
574            assert_eq!(&buf, expected_single);
575
576            let distr = Uniform::new(lb, ub).unwrap();
577            for x in &mut buf {
578                *x = rng.sample(&distr);
579            }
580            assert_eq!(&buf, expected_multiple);
581        }
582
583        test_samples(
584            0f32,
585            1e-2f32,
586            &[0.0003070104, 0.0026630748, 0.00979833],
587            &[0.008194133, 0.00398172, 0.007428536],
588        );
589        test_samples(
590            -1e10f64,
591            1e10f64,
592            &[-4673848682.871551, 6388267422.932352, 4857075081.198343],
593            &[1173375212.1808167, 1917642852.109581, 2365076174.3153973],
594        );
595
596        test_samples(
597            Duration::new(2, 0),
598            Duration::new(4, 0),
599            &[
600                Duration::new(2, 532615131),
601                Duration::new(3, 638826742),
602                Duration::new(3, 485707508),
603            ],
604            &[
605                Duration::new(3, 117337521),
606                Duration::new(3, 191764285),
607                Duration::new(3, 236507617),
608            ],
609        );
610    }
611
612    #[test]
613    fn uniform_distributions_can_be_compared() {
614        assert_eq!(
615            Uniform::new(1.0, 2.0).unwrap(),
616            Uniform::new(1.0, 2.0).unwrap()
617        );
618
619        // To cover UniformInt
620        assert_eq!(
621            Uniform::new(1_u32, 2_u32).unwrap(),
622            Uniform::new(1_u32, 2_u32).unwrap()
623        );
624    }
625}