@@ -96,3 +96,42 @@ pub use rand_core;
9696pub use self :: pcg64:: { Lcg64Xsh32 , Pcg32 } ;
9797pub use self :: pcg128:: { Lcg128Xsl64 , Mcg128Xsl64 , Pcg64 , Pcg64Mcg } ;
9898pub use self :: pcg128cm:: { Lcg128CmDxsm64 , Pcg64Dxsm } ;
99+
100+ mod macros {
101+ macro_rules! impl_state_stream {
102+ ( $type: ident, $int: ty) => {
103+ impl $type {
104+ /// Current state of the generator
105+ pub fn state( & self ) -> $int {
106+ self . state
107+ }
108+
109+ /// Stream parameter of the generator
110+ ///
111+ /// Note that PCG only stores an increment, which is always odd.
112+ /// [`Self::from_state`] discards the highest bit from the
113+ /// stream by shifting it to the left, so this method shifts the
114+ /// increment by one bit to the right.
115+ pub fn stream( & self ) -> $int {
116+ self . increment >> 1
117+ }
118+
119+ /// Construct an instance using a pre-initialized `state`
120+ ///
121+ /// Unlike [`Self::new`], this method does not mutate `state`.
122+ /// It may therefore be used with [`Self::state`] and
123+ /// [`Self::stream`] to reconstruct an RNG.
124+ ///
125+ /// Note that the highest bit of the `stream` parameter is
126+ /// discarded to simplify upholding internal invariants.
127+ pub fn from_state( state: $int, stream: $int) -> Self {
128+ // The increment must be odd, hence we discard one bit:
129+ let increment = ( stream << 1 ) | 1 ;
130+ $type { state, increment }
131+ }
132+ }
133+ } ;
134+ }
135+
136+ pub ( crate ) use impl_state_stream;
137+ }
0 commit comments