From f677deeab397c8672c74fa134978df9aa10e0ff3 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Tue, 23 Dec 2014 13:55:12 +0200 Subject: [PATCH 1/2] Implement Clone for PRNGs --- src/librand/chacha.rs | 4 +--- src/librand/isaac.rs | 15 +++++++++++++++ src/librand/lib.rs | 13 ++----------- src/libstd/rand/mod.rs | 3 ++- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/librand/chacha.rs b/src/librand/chacha.rs index 71ce882e98c..79d836baece 100644 --- a/src/librand/chacha.rs +++ b/src/librand/chacha.rs @@ -12,7 +12,6 @@ use core::prelude::*; use core::num::Int; - use {Rng, SeedableRng, Rand}; const KEY_WORDS : uint = 8; // 8 words for the 256-bit key @@ -28,8 +27,7 @@ const CHACHA_ROUNDS: uint = 20; // Cryptographically secure from 8 upwards as of /// /// [1]: D. J. Bernstein, [*ChaCha, a variant of /// Salsa20*](http://cr.yp.to/chacha.html) - -#[derive(Copy)] +#[deriving(Copy, Clone)] pub struct ChaChaRng { buffer: [u32; STATE_WORDS], // Internal buffer of output state: [u32; STATE_WORDS], // Initial state diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs index 53ae242c5e2..c8a8da0818d 100644 --- a/src/librand/isaac.rs +++ b/src/librand/isaac.rs @@ -179,6 +179,13 @@ impl IsaacRng { } } +// Cannot be derived because [u32; 256] does not implement Clone +impl Clone for IsaacRng { + fn clone(&self) -> IsaacRng { + *self + } +} + impl Rng for IsaacRng { #[inline] fn next_u32(&mut self) -> u32 { @@ -415,6 +422,13 @@ impl Isaac64Rng { } } +// Cannot be derived because [u32; 256] does not implement Clone +impl Clone for Isaac64Rng { + fn clone(&self) -> Isaac64Rng { + *self + } +} + impl Rng for Isaac64Rng { // FIXME #7771: having next_u32 like this should be unnecessary #[inline] @@ -485,6 +499,7 @@ impl Rand for Isaac64Rng { } } + #[cfg(test)] mod test { use std::prelude::v1::*; diff --git a/src/librand/lib.rs b/src/librand/lib.rs index 0f8dbc78cde..d459bb83e98 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -385,6 +385,7 @@ pub trait SeedableRng: Rng { /// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of /// Statistical Software*. Vol. 8 (Issue 14). #[allow(missing_copy_implementations)] +#[deriving(Clone)] pub struct XorShiftRng { x: u32, y: u32, @@ -392,17 +393,6 @@ pub struct XorShiftRng { w: u32, } -impl Clone for XorShiftRng { - fn clone(&self) -> XorShiftRng { - XorShiftRng { - x: self.x, - y: self.y, - z: self.z, - w: self.w, - } - } -} - impl XorShiftRng { /// Creates a new XorShiftRng instance which is not seeded. /// @@ -507,6 +497,7 @@ pub struct Closed01(pub F); #[cfg(not(test))] mod std { pub use core::{option, fmt}; // panic!() + pub use core::clone; // derive Clone pub use core::kinds; } diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs index aa28c8266d1..cadaae5de5c 100644 --- a/src/libstd/rand/mod.rs +++ b/src/libstd/rand/mod.rs @@ -245,7 +245,7 @@ pub mod reader; /// The standard RNG. This is designed to be efficient on the current /// platform. -#[derive(Copy)] +#[deriving(Copy, Clone)] pub struct StdRng { rng: IsaacWordRng, } @@ -322,6 +322,7 @@ static THREAD_RNG_RESEED_THRESHOLD: uint = 32_768; type ThreadRngInner = reseeding::ReseedingRng; /// The thread-local RNG. +#[deriving(Clone)] pub struct ThreadRng { rng: Rc>, } From 6ca1f0c6ea61760138c7e3cb4c14fa3be71c7414 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sat, 3 Jan 2015 21:58:20 +0200 Subject: [PATCH 2/2] Add tests for ChaCha and Isaac Clone impls --- src/librand/chacha.rs | 10 ++++++++++ src/librand/isaac.rs | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/librand/chacha.rs b/src/librand/chacha.rs index 79d836baece..ce055a84d3f 100644 --- a/src/librand/chacha.rs +++ b/src/librand/chacha.rs @@ -281,5 +281,15 @@ mod test { 0x11cfa18e, 0xd3c50049, 0x75c775f6, 0x434c6530, 0x2c5bad8f, 0x898881dc, 0x5f1c86d9, 0xc1f8e7f4)); } + + #[test] + fn test_rng_clone() { + let seed : &[_] = &[0u32, ..8]; + let mut rng: ChaChaRng = SeedableRng::from_seed(seed); + let mut clone = rng.clone(); + for _ in range(0u, 16) { + assert_eq!(rng.next_u64(), clone.next_u64()); + } + } } diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs index c8a8da0818d..03b56963ba9 100644 --- a/src/librand/isaac.rs +++ b/src/librand/isaac.rs @@ -609,4 +609,14 @@ mod test { 596345674630742204, 9947027391921273664, 11788097613744130851, 10391409374914919106)); } + + #[test] + fn test_rng_clone() { + let seed: &[_] = &[1, 23, 456, 7890, 12345]; + let mut rng: Isaac64Rng = SeedableRng::from_seed(seed); + let mut clone = rng.clone(); + for _ in range(0u, 16) { + assert_eq!(rng.next_u64(), clone.next_u64()); + } + } }