@@ -222,6 +222,89 @@ macro_rules! impl_xoshiro_large {
222222 } ;
223223}
224224
225+ /// Implement `state` for an RNG with two word-sized fields `s0` and `s1`.
226+ macro_rules! impl_state_pair {
227+ ( $type: ident, $word: ty) => {
228+ impl $type {
229+ /// Return the internal state of the generator as little-endian
230+ /// bytes that can be passed to [`SeedableRng::from_seed`] to
231+ /// reconstruct an identical generator.
232+ ///
233+ /// The all-zero state is unreachable from any non-zero seed, so
234+ /// the round-trip is exact for any generator obtained via the
235+ /// usual constructors. (An all-zero input to `from_seed` is
236+ /// remapped to `seed_from_u64(0)`.)
237+ ///
238+ /// [`SeedableRng::from_seed`]: rand_core::SeedableRng::from_seed
239+ pub fn state( & self ) -> [ u8 ; 2 * core:: mem:: size_of:: <$word>( ) ] {
240+ const N : usize = core:: mem:: size_of:: <$word>( ) ;
241+ const {
242+ assert!( core:: mem:: size_of:: <Self >( ) == 2 * N ) ;
243+ }
244+ let mut out = [ 0u8 ; 2 * N ] ;
245+ out[ ..N ] . copy_from_slice( & self . s0. to_le_bytes( ) ) ;
246+ out[ N ..] . copy_from_slice( & self . s1. to_le_bytes( ) ) ;
247+ out
248+ }
249+ }
250+ } ;
251+ }
252+
253+ /// Implement `state` for an RNG with an `s: [WORD; 4]` field.
254+ macro_rules! impl_state_array_of_four {
255+ ( $type: ident, $word: ty) => {
256+ impl $type {
257+ /// Return the internal state of the generator as little-endian
258+ /// bytes that can be passed to [`SeedableRng::from_seed`] to
259+ /// reconstruct an identical generator.
260+ ///
261+ /// The all-zero state is unreachable from any non-zero seed, so
262+ /// the round-trip is exact for any generator obtained via the
263+ /// usual constructors. (An all-zero input to `from_seed` is
264+ /// remapped to `seed_from_u64(0)`.)
265+ ///
266+ /// [`SeedableRng::from_seed`]: rand_core::SeedableRng::from_seed
267+ pub fn state( & self ) -> [ u8 ; 4 * core:: mem:: size_of:: <$word>( ) ] {
268+ const N : usize = core:: mem:: size_of:: <$word>( ) ;
269+ const {
270+ assert!( core:: mem:: size_of:: <Self >( ) == 4 * N ) ;
271+ }
272+ let mut out = [ 0u8 ; 4 * N ] ;
273+ out[ ..N ] . copy_from_slice( & self . s[ 0 ] . to_le_bytes( ) ) ;
274+ out[ N ..2 * N ] . copy_from_slice( & self . s[ 1 ] . to_le_bytes( ) ) ;
275+ out[ 2 * N ..3 * N ] . copy_from_slice( & self . s[ 2 ] . to_le_bytes( ) ) ;
276+ out[ 3 * N ..] . copy_from_slice( & self . s[ 3 ] . to_le_bytes( ) ) ;
277+ out
278+ }
279+ }
280+ } ;
281+ }
282+
283+ /// Implement `state` for a 512-bit RNG (`s: [u64; 8]`), returning a [`Seed512`].
284+ macro_rules! impl_state_seed512 {
285+ ( $type: ident) => {
286+ impl $type {
287+ /// Return the internal state of the generator as a [`Seed512`]
288+ /// that can be passed to [`SeedableRng::from_seed`] to reconstruct
289+ /// an identical generator.
290+ ///
291+ /// The all-zero state is unreachable from any non-zero seed, so
292+ /// the round-trip is exact for any generator obtained via the
293+ /// usual constructors. (An all-zero input to `from_seed` is
294+ /// remapped to `seed_from_u64(0)`.)
295+ ///
296+ /// [`SeedableRng::from_seed`]: rand_core::SeedableRng::from_seed
297+ pub fn state( & self ) -> crate :: Seed512 {
298+ let mut out = [ 0u8 ; 64 ] ;
299+ for ( i, word) in self . s. iter( ) . enumerate( ) {
300+ out[ i * 8 ..( i + 1 ) * 8 ] . copy_from_slice( & word. to_le_bytes( ) ) ;
301+ }
302+ crate :: Seed512 ( out)
303+ }
304+ }
305+ } ;
306+ }
307+
225308/// Fallback seed used when `from_seed` is called with an all-zero input.
226309///
227310/// Equal to the first 64 bytes of `SplitMix64::seed_from_u64(0)`'s output.
0 commit comments