@@ -165,18 +165,28 @@ pub fn next_u64_via_fill<R: RngCore + ?Sized>(rng: &mut R) -> u64 {
165
165
impl_uint_from_fill ! ( rng, u64 , 8 )
166
166
}
167
167
168
- /// Wrapper around PRNGs that implement [`BlockRngCore`] to keep a results
169
- /// buffer and offer the methods from [`RngCore`].
168
+ /// A wrapper type implementing [`RngCore`] for some type implementing
169
+ /// [`BlockRngCore`] with `u32` array buffer; i.e. this can be used to implement
170
+ /// a full RNG from just a `generate` function.
171
+ ///
172
+ /// The `core` field may be accessed directly but the results buffer may not.
173
+ /// PRNG implementations can simply use a type alias
174
+ /// (`pub type MyRng = BlockRng<MyRngCore>;`) but might prefer to use a
175
+ /// wrapper type (`pub struct MyRng(BlockRng<MyRngCore>);`); the latter must
176
+ /// re-implement `RngCore` but hides the implementation details and allows
177
+ /// extra functionality to be defined on the RNG
178
+ /// (e.g. `impl MyRng { fn set_stream(...){...} }`).
170
179
///
171
180
/// `BlockRng` has heavily optimized implementations of the [`RngCore`] methods
172
181
/// reading values from the results buffer, as well as
173
182
/// calling `BlockRngCore::generate` directly on the output array when
174
183
/// `fill_bytes` / `try_fill_bytes` is called on a large array. These methods
175
184
/// also handle the bookkeeping of when to generate a new batch of values.
176
- /// No generated values are ever thown away.
185
+ /// No generated values are ever thown away and all values are consumed
186
+ /// in-order (this may be important for reproducibility).
177
187
///
178
- /// Currently `BlockRng` only implements `RngCore` for buffers which are slices
179
- /// of `u32` elements; this may be extended to other types in the future .
188
+ /// See also [`BlockRng64`] which uses `u64` array buffers. Currently there is
189
+ /// no direct support for other buffer types .
180
190
///
181
191
/// For easy initialization `BlockRng` also implements [`SeedableRng`].
182
192
///
@@ -188,7 +198,8 @@ pub fn next_u64_via_fill<R: RngCore + ?Sized>(rng: &mut R) -> u64 {
188
198
pub struct BlockRng < R : BlockRngCore + ?Sized > {
189
199
results : R :: Results ,
190
200
index : usize ,
191
- core : R ,
201
+ /// The *core* part of the RNG, implementing the `generate` function.
202
+ pub core : R ,
192
203
}
193
204
194
205
// Custom Debug implementation that does not expose the contents of `results`.
@@ -214,16 +225,6 @@ impl<R: BlockRngCore> BlockRng<R> {
214
225
}
215
226
}
216
227
217
- /// Return a reference the wrapped `BlockRngCore`.
218
- pub fn inner ( & self ) -> & R {
219
- & self . core
220
- }
221
-
222
- /// Return a mutable reference the wrapped `BlockRngCore`.
223
- pub fn inner_mut ( & mut self ) -> & mut R {
224
- & mut self . core
225
- }
226
-
227
228
/// Get the index into the result buffer.
228
229
///
229
230
/// If this is equal to or larger than the size of the result buffer then
@@ -370,12 +371,20 @@ impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng<R> {
370
371
371
372
372
373
373
- /// Wrapper around PRNGs that implement [`BlockRngCore`] to keep a results
374
- /// buffer and offer the methods from [`RngCore`].
374
+ /// A wrapper type implementing [`RngCore`] for some type implementing
375
+ /// [`BlockRngCore`] with `u64` array buffer; i.e. this can be used to implement
376
+ /// a full RNG from just a `generate` function.
375
377
///
376
378
/// This is similar to [`BlockRng`], but specialized for algorithms that operate
377
379
/// on `u64` values.
378
380
///
381
+ /// Like [`BlockRng`], this wrapper does not throw away whole results and does
382
+ /// use all generated values in-order. The behaviour of `next_u32` is however
383
+ /// a bit special: half of a `u64` is consumed, leaving the other half in the
384
+ /// buffer. If the next function called is `next_u32` then the other half is
385
+ /// then consumed, however both `next_u64` and `fill_bytes` discard any
386
+ /// half-consumed `u64`s when called.
387
+ ///
379
388
/// [`BlockRngCore`]: ../BlockRngCore.t.html
380
389
/// [`RngCore`]: ../RngCore.t.html
381
390
/// [`BlockRng`]: struct.BlockRng.html
@@ -385,7 +394,8 @@ pub struct BlockRng64<R: BlockRngCore + ?Sized> {
385
394
results : R :: Results ,
386
395
index : usize ,
387
396
half_used : bool , // true if only half of the previous result is used
388
- core : R ,
397
+ /// The *core* part of the RNG, implementing the `generate` function.
398
+ pub core : R ,
389
399
}
390
400
391
401
// Custom Debug implementation that does not expose the contents of `results`.
@@ -413,16 +423,6 @@ impl<R: BlockRngCore> BlockRng64<R> {
413
423
}
414
424
}
415
425
416
- /// Return a reference the wrapped `BlockRngCore`.
417
- pub fn inner ( & self ) -> & R {
418
- & self . core
419
- }
420
-
421
- /// Return a mutable reference the wrapped `BlockRngCore`.
422
- pub fn inner_mut ( & mut self ) -> & mut R {
423
- & mut self . core
424
- }
425
-
426
426
/// Get the index into the result buffer.
427
427
///
428
428
/// If this is equal to or larger than the size of the result buffer then
@@ -436,6 +436,7 @@ impl<R: BlockRngCore> BlockRng64<R> {
436
436
/// This will force a new set of results to be generated on next use.
437
437
pub fn reset ( & mut self ) {
438
438
self . index = self . results . as_ref ( ) . len ( ) ;
439
+ self . half_used = false ;
439
440
}
440
441
441
442
/// Generate a new set of results immediately, setting the index to the
@@ -444,6 +445,7 @@ impl<R: BlockRngCore> BlockRng64<R> {
444
445
assert ! ( index < self . results. as_ref( ) . len( ) ) ;
445
446
self . core . generate ( & mut self . results ) ;
446
447
self . index = index;
448
+ self . half_used = false ;
447
449
}
448
450
}
449
451
0 commit comments