Skip to content

Commit ca40fe0

Browse files
committed
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?
2 parents 38d81ba + 6ca1f0c commit ca40fe0

File tree

4 files changed

+40
-15
lines changed

4 files changed

+40
-15
lines changed

src/librand/chacha.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
1313
use core::prelude::*;
1414
use core::num::Int;
15-
1615
use {Rng, SeedableRng, Rand};
1716

1817
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
2827
///
2928
/// [1]: D. J. Bernstein, [*ChaCha, a variant of
3029
/// Salsa20*](http://cr.yp.to/chacha.html)
31-
32-
#[derive(Copy)]
30+
#[deriving(Copy, Clone)]
3331
pub struct ChaChaRng {
3432
buffer: [u32; STATE_WORDS], // Internal buffer of output
3533
state: [u32; STATE_WORDS], // Initial state
@@ -283,5 +281,15 @@ mod test {
283281
0x11cfa18e, 0xd3c50049, 0x75c775f6, 0x434c6530,
284282
0x2c5bad8f, 0x898881dc, 0x5f1c86d9, 0xc1f8e7f4));
285283
}
284+
285+
#[test]
286+
fn test_rng_clone() {
287+
let seed : &[_] = &[0u32, ..8];
288+
let mut rng: ChaChaRng = SeedableRng::from_seed(seed);
289+
let mut clone = rng.clone();
290+
for _ in range(0u, 16) {
291+
assert_eq!(rng.next_u64(), clone.next_u64());
292+
}
293+
}
286294
}
287295

src/librand/isaac.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,13 @@ impl IsaacRng {
179179
}
180180
}
181181

182+
// Cannot be derived because [u32; 256] does not implement Clone
183+
impl Clone for IsaacRng {
184+
fn clone(&self) -> IsaacRng {
185+
*self
186+
}
187+
}
188+
182189
impl Rng for IsaacRng {
183190
#[inline]
184191
fn next_u32(&mut self) -> u32 {
@@ -415,6 +422,13 @@ impl Isaac64Rng {
415422
}
416423
}
417424

425+
// Cannot be derived because [u32; 256] does not implement Clone
426+
impl Clone for Isaac64Rng {
427+
fn clone(&self) -> Isaac64Rng {
428+
*self
429+
}
430+
}
431+
418432
impl Rng for Isaac64Rng {
419433
// FIXME #7771: having next_u32 like this should be unnecessary
420434
#[inline]
@@ -485,6 +499,7 @@ impl Rand for Isaac64Rng {
485499
}
486500
}
487501

502+
488503
#[cfg(test)]
489504
mod test {
490505
use std::prelude::v1::*;
@@ -594,4 +609,14 @@ mod test {
594609
596345674630742204, 9947027391921273664, 11788097613744130851,
595610
10391409374914919106));
596611
}
612+
613+
#[test]
614+
fn test_rng_clone() {
615+
let seed: &[_] = &[1, 23, 456, 7890, 12345];
616+
let mut rng: Isaac64Rng = SeedableRng::from_seed(seed);
617+
let mut clone = rng.clone();
618+
for _ in range(0u, 16) {
619+
assert_eq!(rng.next_u64(), clone.next_u64());
620+
}
621+
}
597622
}

src/librand/lib.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -385,24 +385,14 @@ pub trait SeedableRng<Seed>: Rng {
385385
/// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
386386
/// Statistical Software*. Vol. 8 (Issue 14).
387387
#[allow(missing_copy_implementations)]
388+
#[deriving(Clone)]
388389
pub struct XorShiftRng {
389390
x: u32,
390391
y: u32,
391392
z: u32,
392393
w: u32,
393394
}
394395

395-
impl Clone for XorShiftRng {
396-
fn clone(&self) -> XorShiftRng {
397-
XorShiftRng {
398-
x: self.x,
399-
y: self.y,
400-
z: self.z,
401-
w: self.w,
402-
}
403-
}
404-
}
405-
406396
impl XorShiftRng {
407397
/// Creates a new XorShiftRng instance which is not seeded.
408398
///
@@ -507,6 +497,7 @@ pub struct Closed01<F>(pub F);
507497
#[cfg(not(test))]
508498
mod std {
509499
pub use core::{option, fmt}; // panic!()
500+
pub use core::clone; // derive Clone
510501
pub use core::kinds;
511502
}
512503

src/libstd/rand/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ pub mod reader;
245245

246246
/// The standard RNG. This is designed to be efficient on the current
247247
/// platform.
248-
#[derive(Copy)]
248+
#[deriving(Copy, Clone)]
249249
pub struct StdRng {
250250
rng: IsaacWordRng,
251251
}
@@ -322,6 +322,7 @@ static THREAD_RNG_RESEED_THRESHOLD: uint = 32_768;
322322
type ThreadRngInner = reseeding::ReseedingRng<StdRng, ThreadRngReseeder>;
323323

324324
/// The thread-local RNG.
325+
#[deriving(Clone)]
325326
pub struct ThreadRng {
326327
rng: Rc<RefCell<ThreadRngInner>>,
327328
}

0 commit comments

Comments
 (0)