Skip to content

Instantly share code, notes, and snippets.

@bhickey

bhickey/rand.rs Secret

Created July 3, 2017 02:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bhickey/29da5016b3fa7fb416fb280e6175e1fa to your computer and use it in GitHub Desktop.
Save bhickey/29da5016b3fa7fb416fb280e6175e1fa to your computer and use it in GitHub Desktop.
#[derive(Debug)]
pub struct RngFactory {
stack: Vec<XorShiftRng>,
}
#[derive(Debug)]
pub struct RngWrapper {
ptr: Rc<RefCell<RngFactory>>,
rng: XorShiftRng
}
impl Drop for RngWrapper {
fn drop(&mut self) {
let mut factory = self.ptr.borrow_mut();
factory.stack.pop();
}
}
impl Deref for RngWrapper {
type Target = XorShiftRng;
fn deref(&self) -> &XorShiftRng {
&self.rng
}
}
impl DerefMut for RngWrapper {
fn deref_mut(&mut self) -> &mut XorShiftRng {
&mut self.rng
}
}
#[derive(Debug)]
pub struct RngGuard {
ptr: Rc<RefCell<RngFactory>>,
}
impl Drop for RngGuard {
fn drop(&mut self) {
let mut factory = self.ptr.borrow_mut();
factory.stack.pop();
}
}
thread_local!(static RNG_STACK: Rc<RefCell<RngFactory>> = {
let mut r = match StdRng::new() {
Ok(r) => r,
Err(e) => panic!("could not initialize thread_rng: {}", e)
};
let x = r.gen();
let rf = RngFactory { stack: vec![x] };
Rc::new(RefCell::new(rf))
});
pub fn rng_factory() -> RngWrapper {
RNG_STACK.with(|t| {
let mut factory = t.borrow_mut();
let mut hd = factory.stack.pop().unwrap();
let n = hd.gen();
let m = hd.gen();
factory.stack.push(hd);
factory.stack.push(m);
RngWrapper {
ptr: t.clone(),
rng: n,
}
})
}
pub fn seed_rng(seed: [u32; 4]) -> RngGuard {
RNG_STACK.with(|t| {
let mut factory = t.borrow_mut();
factory.stack.push(XorShiftRng::from_seed(seed));
RngGuard {
ptr: t.clone(),
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment