|
39 | 39 | //! fn from_seed(seed: Self::Seed) -> Self { |
40 | 40 | //! let core = MyRngCore { |
41 | 41 | //! // ... |
42 | | -//! # state: { |
43 | | -//! # let mut buf = [0u32; 8]; |
44 | | -//! # rand_core::le::read_u32_into(&seed, &mut buf); |
45 | | -//! # buf |
46 | | -//! # } |
| 42 | +//! # state: rand_core::utils::read_words(&seed), |
47 | 43 | //! }; |
48 | 44 | //! MyRng(BlockRng::new(core)) |
49 | 45 | //! } |
|
85 | 81 | //! [`SeedableRng`]: crate::SeedableRng |
86 | 82 | //! [`rand::rngs::ReseedingRng`]: https://docs.rs/rand/latest/rand/rngs/struct.ReseedingRng.html |
87 | 83 |
|
88 | | -use crate::le::{Word, fill_via_chunks}; |
| 84 | +use crate::utils::Word; |
89 | 85 | use core::fmt; |
90 | 86 |
|
91 | 87 | /// A random (block) generator |
@@ -141,15 +137,14 @@ pub struct BlockRng<G: Generator> { |
141 | 137 | } |
142 | 138 |
|
143 | 139 | // Custom Debug implementation that does not expose the contents of `results`. |
144 | | -impl<W: Word, const N: usize, G> fmt::Debug for BlockRng<G> |
| 140 | +impl<G> fmt::Debug for BlockRng<G> |
145 | 141 | where |
146 | | - G: Generator<Output = [W; N]> + fmt::Debug, |
| 142 | + G: Generator + fmt::Debug, |
147 | 143 | { |
148 | 144 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
149 | 145 | fmt.debug_struct("BlockRng") |
150 | 146 | .field("core", &self.core) |
151 | | - .field("index", &self.index()) |
152 | | - .finish() |
| 147 | + .finish_non_exhaustive() |
153 | 148 | } |
154 | 149 | } |
155 | 150 |
|
@@ -296,11 +291,29 @@ impl<W: Word, const N: usize, G: Generator<Output = [W; N]>> BlockRng<G> { |
296 | 291 | self.core.generate(&mut self.results); |
297 | 292 | index = 0; |
298 | 293 | } |
299 | | - let (consumed_u32, filled_u8) = |
300 | | - fill_via_chunks(&self.results[index..], &mut dest[read_len..]); |
301 | 294 |
|
302 | | - self.set_index(index + consumed_u32); |
303 | | - read_len += filled_u8; |
| 295 | + let size = core::mem::size_of::<W>(); |
| 296 | + let mut chunks = dest[read_len..].chunks_exact_mut(size); |
| 297 | + let mut src = self.results[index..].iter(); |
| 298 | + |
| 299 | + let zipped = chunks.by_ref().zip(src.by_ref()); |
| 300 | + let num_chunks = zipped.len(); |
| 301 | + zipped.for_each(|(chunk, src)| chunk.copy_from_slice(src.to_le_bytes().as_ref())); |
| 302 | + index += num_chunks; |
| 303 | + read_len += num_chunks * size; |
| 304 | + |
| 305 | + if let Some(src) = src.next() { |
| 306 | + // We have consumed all full chunks of dest, but not src. |
| 307 | + let dest = chunks.into_remainder(); |
| 308 | + let n = dest.len(); |
| 309 | + if n > 0 { |
| 310 | + dest.copy_from_slice(&src.to_le_bytes().as_ref()[..n]); |
| 311 | + index += 1; |
| 312 | + read_len += n; |
| 313 | + } |
| 314 | + } |
| 315 | + |
| 316 | + self.set_index(index); |
304 | 317 | } |
305 | 318 | } |
306 | 319 | } |
|
0 commit comments