-
-
Notifications
You must be signed in to change notification settings - Fork 464
gen_range(a, b)
-> gen_range(a..b)
and gen_range(a..=b)
#1003
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Conversation
gen_range(a, b)
-> gen_range(a..b)
and gen_range(a..=b)
The only failure is a spurious network error. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha, shouldn't have tried reviewing this commit-by-commit!
src/rng.rs
Outdated
fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T | ||
fn gen_range<T, R>(&mut self, range: R) -> T | ||
where | ||
B1: SampleBorrow<T> + Sized, | ||
B2: SampleBorrow<T> + Sized, | ||
T: SampleUniform, | ||
R: RangeBounds<T> | ||
{ | ||
T::Sampler::sample_single(low, high, self) | ||
use core::ops::Bound; | ||
if let Bound::Included(low) = range.start_bound() { | ||
match range.end_bound() { | ||
Bound::Excluded(high) => T::Sampler::sample_single(low, high, self), | ||
Bound::Included(high) => T::Sampler::sample_single_inclusive(low, high, self), | ||
Bound::Unbounded => panic!("invalid upper bound"), | ||
} | ||
} else { | ||
panic!("invalid lower bound"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't have to use run-time look-ups and panics. Can we do something like: where R: Into<Uniform<T>>
?
No, really we need a specific trait for "sample single":
trait SampleSingle<X> {
fn sample_single(self) -> X;
}
impl<X: SampleUniform> SampleSingle<X> for Range<X> { .. }
impl<X: SampleUniform> SampleSingle<X> for RangeInclusive<X> { .. }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we would have to define such a trait if we want to avoid the lookup. Alternatively, we could inline gen_range
and hope the lookup gets optimized away. What do you prefer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added an implementation using static dispatch in the last commit. It required a new public trait that we may want to hide with #[doc(hidden)]
to avoid users implementing it to add support for other range types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think @newpavlov? Overall it seems more useful to expose the trait (sometimes users do want to extend generic APIs).
Sorry, this should probably be rebased and squashed. |
I'm not sure how to work around |
I think that's probably fine. Anyone who knows of the |
This includes a specialized implementation for integers.
This adds support for `Rng::range(a..b)` and `Rng::range(a..=b)`, replacing `Rng::range(a, b)`. `a` and `b` must now implement `PartialEq`. This is a breaking change. In most cases, replacing `Rng::gen_range(a, b)` with `Rng::gen_range(a..b)` should be enough, however type annotations may be necessary, and `a` and `b` can no longer be references or SIMD types. SIMD types are still supported by `UniformSampler::sample_single`. Some clippy warnings were fixed as well.
Replaces and closes #821.