Skip to content

Commit

Permalink
Upgrade to experimental version of rand crate
Browse files Browse the repository at this point in the history
* Fixes unable to use Rng trait object with range::sample

  rust-random/rand#190

* Adds support for inclusive range

  Replace rvs's own RangeInclusive with rand's new Range::new_inclusive

  rust-random/rand#188
  • Loading branch information
rfdonnelly committed Nov 11, 2017
1 parent e6bc2e6 commit bb85765
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 86 deletions.
21 changes: 14 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ build = "build.rs"
peg = { version = "0.5" }

[dependencies]
rand = "0.3"
rand = { git = "https://github.com/dhardy/rand" }
libc = "0.2"

[lib]
Expand Down
2 changes: 1 addition & 1 deletion src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub mod range;

use rand::Rng;
use rand::SeedableRng;
use rand::chacha::ChaChaRng;
use rand::prng::ChaChaRng;
use std::collections::HashMap;

use ast::Node;
Expand Down
82 changes: 5 additions & 77 deletions src/types/range.rs
Original file line number Diff line number Diff line change
@@ -1,86 +1,14 @@
use rand::Rng;
use rand::distributions::Range;
use rand::distributions::Sample;
use rand::distributions::IndependentSample;
use rand::distributions::range::RangeInt;
use rand::distributions::Distribution;

use types::Rv;
use types::RvData;

pub struct RangeSequence {
data: RvData,
range: RangeInclusive,
}

pub struct RangeInclusive {
range: Range<u32>,
use_range: bool,
offset: bool,
}

impl RangeInclusive {
fn new(low: u32, high: u32) -> RangeInclusive {
// Implement the inclusive range [x, y] using the exlusive range [x, y + 1) by handling
// three different cases:
//
// * The range [::std::u32::MIN, ::std::u32::MAX]
//
// Cannot use rand::distributions::Range. Use RNG directly.
//
// [x, y] => [x, y]
//
// * The range [x, ::std::u32::MAX]
//
// Can use rand::distributions::Range but must adjust the range down artifically, then
// re-adjust up after sampling.
//
// [x, y] => [x - 1, y) + 1
//
// * All other ranges
//
// Use rand::distributions::Range normally.
//
// [x, y] => [x, y + 1)
let (x, y, use_range, offset) = match (low, high) {
// Sample directly from RNG w/o Range
(::std::u32::MIN, ::std::u32::MAX) => (::std::u32::MIN, ::std::u32::MAX, false, false),
// Sample with Range + offset
(x, ::std::u32::MAX) => (x - 1, ::std::u32::MAX, true, true),
// Sample with Range normally
(x, y) => (x, y + 1, true, false)
};

RangeInclusive {
offset: offset,
use_range: use_range,
range: Range::new(x, y),
}
}
}

impl IndependentSample<u32> for RangeInclusive {
fn ind_sample<R: Rng>(&self, rng: &mut R) -> u32 {
// Should never see this case. Could cause a panic due to overflow.
assert!(!(self.use_range == false && self.offset == true));

let sample =
if self.use_range {
self.range.ind_sample(rng)
} else {
rng.gen()
};

if self.offset {
sample + 1
} else {
sample
}
}
}

impl Sample<u32> for RangeInclusive {
fn sample<R: Rng>(&mut self, rng: &mut R) -> u32 {
self.ind_sample(rng)
}
range: Range<RangeInt<u32>>,
}

impl RangeSequence {
Expand All @@ -91,14 +19,14 @@ impl RangeSequence {
prev: 0,
done: false,
},
range: RangeInclusive::new(l, r),
range: Range::new_inclusive(l, r),
}
}
}

impl Rv for RangeSequence {
fn next(&mut self, rng: &mut Rng) -> u32 {
self.data.prev = self.range.ind_sample(rng);
self.data.prev = self.range.sample(rng);

self.data.prev
}
Expand Down

0 comments on commit bb85765

Please sign in to comment.