pcg_random/
lib.rs

1use std::marker::PhantomData;
2
3use self::{
4	lcg::{Integer, Lcg, Parameters},
5	output::Output
6};
7
8pub mod lcg;
9pub mod output;
10pub mod variants;
11
12#[cfg(feature = "rand")]
13mod rand;
14
15#[derive(Clone, Debug, Eq, Hash, PartialEq)]
16pub struct Pcg<L, P, S, O> {
17	pub lcg: Lcg<L, S>,
18	pub permutation: PhantomData<(P, O)>
19}
20
21impl<L, P, S, O> Pcg<L, P, S, O>
22where
23	L: Copy + Into<Parameters<S>>,
24	P: Output<S, O>,
25	S: Integer
26{
27	pub fn current(&self) -> O {
28		P::output(self.lcg.current())
29	}
30
31	pub fn generate(&mut self) -> O {
32		P::output(self.lcg.generate())
33	}
34
35	pub fn jump_forward(&mut self, steps: S) -> O {
36		P::output(self.lcg.jump_forward(steps))
37	}
38
39	pub fn jump_backward(&mut self, steps: S) -> O {
40		P::output(self.lcg.jump_backward(steps))
41	}
42}
43
44#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
45pub struct DefaultLcgParameters<S>(PhantomData<S>);
46
47#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
48pub struct DefaultCheapLcgParameters<S>(PhantomData<S>);
49
50#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
51pub struct DefaultMcgParameters<S>(PhantomData<S>);
52
53#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
54pub struct DefaultCheapMcgParameters<S>(PhantomData<S>);
55
56macro_rules! impl_default_parameters {
57	($ty:ty, $mul:literal, $inc:literal) => {
58		impl_default_parameters!($ty, $mul, $inc, cheap_mul: $mul);
59	};
60
61	($ty:ty, $mul:literal, $inc:literal, cheap_mul: $cheap_mul:literal) => {
62		impl DefaultLcgParameters<$ty> {
63			#[inline]
64			pub const fn multiplier() -> $ty {
65				$mul
66			}
67
68			#[inline]
69			pub const fn increment() -> $ty {
70				$inc
71			}
72		}
73
74		impl From<DefaultLcgParameters<$ty>> for Parameters<$ty> {
75			#[inline]
76			fn from(_: DefaultLcgParameters<$ty>) -> Parameters<$ty> {
77				Parameters { multiplier: $mul, increment: $inc }
78			}
79		}
80
81		impl DefaultCheapLcgParameters<$ty> {
82			#[inline]
83			pub const fn multiplier() -> $ty {
84				$cheap_mul
85			}
86
87			#[inline]
88			pub const fn increment() -> $ty {
89				$inc
90			}
91		}
92
93		impl From<DefaultCheapLcgParameters<$ty>> for Parameters<$ty> {
94			#[inline]
95			fn from(_: DefaultCheapLcgParameters<$ty>) -> Parameters<$ty> {
96				Parameters { multiplier: $cheap_mul, increment: $inc }
97			}
98		}
99
100		impl DefaultMcgParameters<$ty> {
101			#[inline]
102			pub const fn multiplier() -> $ty {
103				$mul
104			}
105		}
106
107		impl From<DefaultMcgParameters<$ty>> for Parameters<$ty> {
108			#[inline]
109			fn from(_: DefaultMcgParameters<$ty>) -> Parameters<$ty> {
110				Parameters { multiplier: $mul, increment: 0 }
111			}
112		}
113
114		impl DefaultCheapMcgParameters<$ty> {
115			#[inline]
116			pub const fn multiplier() -> $ty {
117				$cheap_mul
118			}
119		}
120
121		impl From<DefaultCheapMcgParameters<$ty>> for Parameters<$ty> {
122			#[inline]
123			fn from(_: DefaultCheapMcgParameters<$ty>) -> Parameters<$ty> {
124				Parameters { multiplier: $cheap_mul, increment: 0 }
125			}
126		}
127	};
128}
129
130impl_default_parameters!(u8, 0x8d, 0x4d);
131impl_default_parameters!(u16, 0x321d, 0xbb75);
132impl_default_parameters!(u32, 0x2c9277b5, 0xac564b05);
133impl_default_parameters!(u64, 0x5851f42d4c957f2d, 0x14057b7ef767814f);
134
135impl_default_parameters!(
136	u128,
137	0x2360ed051fc65da44385df649fccf645,
138	0x5851f42d4c957f2d14057b7ef767814f,
139	cheap_mul: 0xda942042e4dd58b5
140);