Skip to content

Commit

Permalink
Merge pull request #227 from pitdicker/no_std_alloc
Browse files Browse the repository at this point in the history
 Implement Rng for Box with alloc feature
  • Loading branch information
dhardy authored Jan 11, 2018
2 parents 2b53718 + fafc472 commit f090aa0
Show file tree
Hide file tree
Showing 12 changed files with 259 additions and 289 deletions.
2 changes: 1 addition & 1 deletion src/distributions/exponential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ mod test {
#[test]
fn test_exp() {
let mut exp = Exp::new(10.0);
let mut rng = ::test::rng();
let mut rng = ::test::rng(221);
for _ in 0..1000 {
assert!(exp.sample(&mut rng) >= 0.0);
assert!(exp.ind_sample(&mut rng) >= 0.0);
Expand Down
10 changes: 5 additions & 5 deletions src/distributions/gamma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ mod test {
#[test]
fn test_chi_squared_one() {
let mut chi = ChiSquared::new(1.0);
let mut rng = ::test::rng();
let mut rng = ::test::rng(201);
for _ in 0..1000 {
chi.sample(&mut rng);
chi.ind_sample(&mut rng);
Expand All @@ -343,7 +343,7 @@ mod test {
#[test]
fn test_chi_squared_small() {
let mut chi = ChiSquared::new(0.5);
let mut rng = ::test::rng();
let mut rng = ::test::rng(202);
for _ in 0..1000 {
chi.sample(&mut rng);
chi.ind_sample(&mut rng);
Expand All @@ -352,7 +352,7 @@ mod test {
#[test]
fn test_chi_squared_large() {
let mut chi = ChiSquared::new(30.0);
let mut rng = ::test::rng();
let mut rng = ::test::rng(203);
for _ in 0..1000 {
chi.sample(&mut rng);
chi.ind_sample(&mut rng);
Expand All @@ -367,7 +367,7 @@ mod test {
#[test]
fn test_f() {
let mut f = FisherF::new(2.0, 32.0);
let mut rng = ::test::rng();
let mut rng = ::test::rng(204);
for _ in 0..1000 {
f.sample(&mut rng);
f.ind_sample(&mut rng);
Expand All @@ -377,7 +377,7 @@ mod test {
#[test]
fn test_t() {
let mut t = StudentT::new(11.0);
let mut rng = ::test::rng();
let mut rng = ::test::rng(205);
for _ in 0..1000 {
t.sample(&mut rng);
t.ind_sample(&mut rng);
Expand Down
45 changes: 23 additions & 22 deletions src/distributions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,9 +311,10 @@ mod tests {
fn test_rand_sample() {
let mut rand_sample = RandSample::<ConstRand>::new();

assert_eq!(rand_sample.sample(&mut ::test::rng()), ConstRand(0));
assert_eq!(rand_sample.ind_sample(&mut ::test::rng()), ConstRand(0));
assert_eq!(rand_sample.sample(&mut ::test::rng(231)), ConstRand(0));
assert_eq!(rand_sample.ind_sample(&mut ::test::rng(232)), ConstRand(0));
}

#[test]
fn test_weighted_choice() {
// this makes assumptions about the internal implementation of
Expand All @@ -335,36 +336,36 @@ mod tests {
}}
}

t!(vec!(Weighted { weight: 1, item: 10}), [10]);
t!([Weighted { weight: 1, item: 10}], [10]);

// skip some
t!(vec!(Weighted { weight: 0, item: 20},
Weighted { weight: 2, item: 21},
Weighted { weight: 0, item: 22},
Weighted { weight: 1, item: 23}),
t!([Weighted { weight: 0, item: 20},
Weighted { weight: 2, item: 21},
Weighted { weight: 0, item: 22},
Weighted { weight: 1, item: 23}],
[21,21, 23]);

// different weights
t!(vec!(Weighted { weight: 4, item: 30},
Weighted { weight: 3, item: 31}),
t!([Weighted { weight: 4, item: 30},
Weighted { weight: 3, item: 31}],
[30,30,30,30, 31,31,31]);

// check that we're binary searching
// correctly with some vectors of odd
// length.
t!(vec!(Weighted { weight: 1, item: 40},
Weighted { weight: 1, item: 41},
Weighted { weight: 1, item: 42},
Weighted { weight: 1, item: 43},
Weighted { weight: 1, item: 44}),
t!([Weighted { weight: 1, item: 40},
Weighted { weight: 1, item: 41},
Weighted { weight: 1, item: 42},
Weighted { weight: 1, item: 43},
Weighted { weight: 1, item: 44}],
[40, 41, 42, 43, 44]);
t!(vec!(Weighted { weight: 1, item: 50},
Weighted { weight: 1, item: 51},
Weighted { weight: 1, item: 52},
Weighted { weight: 1, item: 53},
Weighted { weight: 1, item: 54},
Weighted { weight: 1, item: 55},
Weighted { weight: 1, item: 56}),
t!([Weighted { weight: 1, item: 50},
Weighted { weight: 1, item: 51},
Weighted { weight: 1, item: 52},
Weighted { weight: 1, item: 53},
Weighted { weight: 1, item: 54},
Weighted { weight: 1, item: 55},
Weighted { weight: 1, item: 56}],
[50, 51, 52, 53, 54, 55, 56]);
}

Expand Down Expand Up @@ -404,7 +405,7 @@ mod tests {
}
#[test] #[should_panic]
fn test_weighted_choice_weight_overflows() {
let x = ::std::u32::MAX / 2; // x + x + 2 is the overflow
let x = ::core::u32::MAX / 2; // x + x + 2 is the overflow
WeightedChoice::new(&mut [Weighted { weight: x, item: 0 },
Weighted { weight: 1, item: 1 },
Weighted { weight: x, item: 2 },
Expand Down
4 changes: 2 additions & 2 deletions src/distributions/normal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ mod tests {
#[test]
fn test_normal() {
let mut norm = Normal::new(10.0, 10.0);
let mut rng = ::test::rng();
let mut rng = ::test::rng(210);
for _ in 0..1000 {
norm.sample(&mut rng);
norm.ind_sample(&mut rng);
Expand All @@ -187,7 +187,7 @@ mod tests {
#[test]
fn test_log_normal() {
let mut lnorm = LogNormal::new(10.0, 10.0);
let mut rng = ::test::rng();
let mut rng = ::test::rng(211);
for _ in 0..1000 {
lnorm.sample(&mut rng);
lnorm.ind_sample(&mut rng);
Expand Down
5 changes: 2 additions & 3 deletions src/distributions/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ mod tests {

#[test]
fn test_integers() {
let mut rng = ::test::rng();
let mut rng = ::test::rng(251);
macro_rules! t {
($($ty:ident),*) => {{
$(
Expand Down Expand Up @@ -214,7 +214,7 @@ mod tests {

#[test]
fn test_floats() {
let mut rng = ::test::rng();
let mut rng = ::test::rng(252);
macro_rules! t {
($($ty:ty),*) => {{
$(
Expand All @@ -237,5 +237,4 @@ mod tests {

t!(f32, f64)
}

}
82 changes: 48 additions & 34 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ use core::marker;
use core::mem;
#[cfg(feature="std")] use std::cell::RefCell;
#[cfg(feature="std")] use std::rc::Rc;
#[cfg(all(feature="alloc", not(feature="std")))] use alloc::boxed::Box;

// external rngs
pub use jitter::JitterRng;
Expand Down Expand Up @@ -654,7 +655,7 @@ impl<'a, R: ?Sized> Rng for &'a mut R where R: Rng {
}
}

#[cfg(feature="std")]
#[cfg(any(feature="std", feature="alloc"))]
impl<R: ?Sized> Rng for Box<R> where R: Rng {
#[inline]
fn next_u32(&mut self) -> u32 {
Expand Down Expand Up @@ -1034,12 +1035,15 @@ pub fn sample<T, I, R>(rng: &mut R, iterable: I, amount: usize) -> Vec<T>
#[cfg(test)]
mod test {
use impls;
use super::{Rng, thread_rng, random, SeedableRng, StdRng, weak_rng};
use std::iter::repeat;
#[cfg(feature="std")]
use super::{random, thread_rng, weak_rng};
use super::{Rng, SeedableRng, StdRng};
#[cfg(feature="alloc")]
use alloc::boxed::Box;

pub struct MyRng<R> { inner: R }
pub struct TestRng<R> { inner: R }

impl<R: Rng> Rng for MyRng<R> {
impl<R: Rng> Rng for TestRng<R> {
fn next_u32(&mut self) -> u32 {
self.inner.next_u32()
}
Expand All @@ -1051,8 +1055,9 @@ mod test {
}
}

pub fn rng() -> MyRng<::ThreadRng> {
MyRng { inner: ::thread_rng() }
pub fn rng(seed: u64) -> TestRng<StdRng> {
let seed = [seed as usize];
TestRng { inner: StdRng::from_seed(&seed) }
}

struct ConstRng { i: u64 }
Expand Down Expand Up @@ -1090,8 +1095,9 @@ mod test {
let lengths = [0, 1, 2, 3, 4, 5, 6, 7,
80, 81, 82, 83, 84, 85, 86, 87];
for &n in lengths.iter() {
let mut v = repeat(0u8).take(n).collect::<Vec<_>>();
r.fill_bytes(&mut v);
let mut buffer = [0u8; 87];
let mut v = &mut buffer[0..n];
r.fill_bytes(v);

// use this to get nicer error messages.
for (i, &byte) in v.iter().enumerate() {
Expand All @@ -1104,7 +1110,7 @@ mod test {

#[test]
fn test_gen_range() {
let mut r = thread_rng();
let mut r = rng(101);
for _ in 0..1000 {
let a = r.gen_range(-3, 42);
assert!(a >= -3 && a < 42);
Expand All @@ -1124,43 +1130,43 @@ mod test {
#[test]
#[should_panic]
fn test_gen_range_panic_int() {
let mut r = thread_rng();
let mut r = rng(102);
r.gen_range(5, -2);
}

#[test]
#[should_panic]
fn test_gen_range_panic_usize() {
let mut r = thread_rng();
let mut r = rng(103);
r.gen_range(5, 2);
}

#[test]
fn test_gen_weighted_bool() {
let mut r = thread_rng();
let mut r = rng(104);
assert_eq!(r.gen_weighted_bool(0), true);
assert_eq!(r.gen_weighted_bool(1), true);
}

#[test]
fn test_gen_ascii_str() {
let mut r = thread_rng();
let mut r = rng(105);
assert_eq!(r.gen_ascii_chars().take(0).count(), 0);
assert_eq!(r.gen_ascii_chars().take(10).count(), 10);
assert_eq!(r.gen_ascii_chars().take(16).count(), 16);
}

#[test]
fn test_gen_vec() {
let mut r = thread_rng();
let mut r = rng(106);
assert_eq!(r.gen_iter::<u8>().take(0).count(), 0);
assert_eq!(r.gen_iter::<u8>().take(10).count(), 10);
assert_eq!(r.gen_iter::<f64>().take(16).count(), 16);
}

#[test]
fn test_choose() {
let mut r = thread_rng();
let mut r = rng(107);
assert_eq!(r.choose(&[1, 1, 1]).map(|&x|x), Some(1));

let v: &[isize] = &[];
Expand All @@ -1169,7 +1175,7 @@ mod test {

#[test]
fn test_shuffle() {
let mut r = thread_rng();
let mut r = rng(108);
let empty: &mut [isize] = &mut [];
r.shuffle(empty);
let mut one = [1];
Expand All @@ -1188,6 +1194,7 @@ mod test {
}

#[test]
#[cfg(feature="std")]
fn test_thread_rng() {
let mut r = thread_rng();
r.gen::<i32>();
Expand All @@ -1199,8 +1206,9 @@ mod test {
}

#[test]
#[cfg(any(feature="std", feature="alloc"))]
fn test_rng_trait_object() {
let mut rng = thread_rng();
let mut rng = rng(109);
{
let mut r = &mut rng as &mut Rng;
r.next_u32();
Expand All @@ -1224,6 +1232,7 @@ mod test {
}

#[test]
#[cfg(feature="std")]
fn test_random() {
// not sure how to test this aside from just getting some values
let _n : usize = random();
Expand All @@ -1238,27 +1247,32 @@ mod test {
}

#[test]
fn test_std_rng_seeded() {
let s = thread_rng().gen_iter::<usize>().take(256).collect::<Vec<usize>>();
let mut ra: StdRng = SeedableRng::from_seed(&s[..]);
let mut rb: StdRng = SeedableRng::from_seed(&s[..]);
assert!(iter_eq(ra.gen_ascii_chars().take(100),
rb.gen_ascii_chars().take(100)));
#[cfg(target_pointer_width = "32")]
fn test_stdrng_construction() {
let seed = [1, 23, 456, 7890, 0, 0, 0, 0];
let mut rng1 = StdRng::from_seed(&seed);
assert_eq!(rng1.next_u32(), 2869442790);

/* FIXME: enable once `from_rng` has landed
let mut rng2 = StdRng::from_rng(&mut rng1).unwrap();
assert_eq!(rng1.next_u32(), 3094074039);
*/
}

#[test]
fn test_std_rng_reseed() {
let s = thread_rng().gen_iter::<usize>().take(256).collect::<Vec<usize>>();
let mut r: StdRng = SeedableRng::from_seed(&s[..]);
let string1 = r.gen_ascii_chars().take(100).collect::<String>();

r.reseed(&s);

let string2 = r.gen_ascii_chars().take(100).collect::<String>();
assert_eq!(string1, string2);
#[cfg(target_pointer_width = "64")]
fn test_stdrng_construction() {
let seed = [1, 23, 456, 7890, 0, 0, 0, 0];
let mut rng1 = StdRng::from_seed(&seed);
assert_eq!(rng1.next_u32(), 3477963620);

/* FIXME: enable once `from_rng` has landed
let mut rng2 = StdRng::from_rng(&mut rng1).unwrap();
assert_eq!(rng1.next_u32(), 3094074039);
*/
}

#[test]
#[cfg(feature="std")]
fn test_weak_rng() {
let s = weak_rng().gen_iter::<usize>().take(256).collect::<Vec<usize>>();
let mut ra: StdRng = SeedableRng::from_seed(&s[..]);
Expand Down
Loading

0 comments on commit f090aa0

Please sign in to comment.