about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-01-05 18:37:18 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-01-05 18:37:18 -0800
commitca40fe0f5e8085070f1bb678cba1ea85a09942b1 (patch)
tree29b7ce86a3c8734e3d70b08694dc1a54033447fa
parent38d81baec8c02847526f5c440434b59b22ebeaa5 (diff)
parent6ca1f0c6ea61760138c7e3cb4c14fa3be71c7414 (diff)
rollup merge of #20483: nagisa/rng-copy
* Implement (derive) `Clone` for `ChaChaRng`, `Isaac*Rng`, `StdRng` and `ThreadRng`;
* Derive `XorShiftRng` `Clone` implementation instead of implementing it explicitly.

`OsRng` is the only Rng which does not implement `Clone` or `Copy` after this patch because of its dependence on `Reader`.

r? @huonw I guess?
-rw-r--r--src/librand/chacha.rs14
-rw-r--r--src/librand/isaac.rs25
-rw-r--r--src/librand/lib.rs13
-rw-r--r--src/libstd/rand/mod.rs3
4 files changed, 40 insertions, 15 deletions
diff --git a/src/librand/chacha.rs b/src/librand/chacha.rs
index 71ce882e98c..ce055a84d3f 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
@@ -283,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 53ae242c5e2..03b56963ba9 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::*;
@@ -594,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());
+        }
+    }
 }
diff --git a/src/librand/lib.rs b/src/librand/lib.rs
index 1d37b061c97..9f44b7438ae 100644
--- a/src/librand/lib.rs
+++ b/src/librand/lib.rs
@@ -385,6 +385,7 @@ pub trait SeedableRng<Seed>: 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<F>(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<StdRng, ThreadRngReseeder>;
 
 /// The thread-local RNG.
+#[deriving(Clone)]
 pub struct ThreadRng {
     rng: Rc<RefCell<ThreadRngInner>>,
 }