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);