common_traits/rnd.rs
1/// A generic Random number generator
2///
3/// # Example
4///
5/// ```rust
6/// use common_traits::{Rng, RngNext};
7///
8/// pub struct Xorshift64(u64);
9///
10/// impl Rng for Xorshift64 {
11/// type Seed = u64;
12///
13/// fn new(seed: u64) -> Self {
14/// Self(seed.saturating_add(1))
15/// }
16/// }
17///
18/// impl RngNext<u64> for Xorshift64 {
19/// fn next_inner(&mut self) -> u64 {
20/// self.0 ^= self.0 << 13;
21/// self.0 ^= self.0 >> 7;
22/// self.0 ^= self.0 << 17;
23/// self.0
24/// }
25/// }
26///
27/// impl RngNext<f64> for Xorshift64 {
28/// fn next_inner(&mut self) -> f64 {
29/// let v: u64 = (self.next::<u64>() >> 11) | (1023 << 52);
30/// let r: f64 = f64::from_le_bytes(v.to_le_bytes());
31/// r - 1f64
32/// }
33/// }
34/// ```
35pub trait Rng {
36 type Seed;
37
38 /// Instantiate a new Rng making no assumptions on its seed.
39 fn new(seed: Self::Seed) -> Self;
40
41 /// automatic dispatching of the implementation, no need to re-implement
42 #[inline(always)]
43 fn next<T>(&mut self) -> T
44 where
45 Self: RngNext<T>,
46 {
47 <Self as RngNext<T>>::next_inner(self)
48 }
49}
50
51/// Implementation of a specific type generation for a Rng
52///
53/// # Example
54///
55/// ```rust
56/// use common_traits::{Rng, RngNext};
57///
58/// pub struct Xorshift64(u64);
59///
60/// impl Rng for Xorshift64 {
61/// type Seed = u64;
62/// fn new(seed: u64) -> Self {
63/// Self(seed.saturating_add(1))
64/// }
65/// }
66///
67/// impl RngNext<u64> for Xorshift64 {
68/// fn next_inner(&mut self) -> u64 {
69/// self.0 ^= self.0 << 13;
70/// self.0 ^= self.0 >> 7;
71/// self.0 ^= self.0 << 17;
72/// self.0
73/// }
74/// }
75///
76/// impl RngNext<f64> for Xorshift64 {
77/// fn next_inner(&mut self) -> f64 {
78/// let v: u64 = (self.next::<u64>() >> 11) | (1023 << 52);
79/// let r: f64 = f64::from_le_bytes(v.to_le_bytes());
80/// r - 1f64
81/// }
82/// }
83/// ```
84pub trait RngNext<T> {
85 fn next_inner(&mut self) -> T;
86}