1#![no_std]
2extern crate alloc;
3
4use alloc::vec::Vec;
5use core::sync::atomic::{AtomicU64, Ordering};
6
7mod fy;
8
9const DEFAULT_INC: u64 = 1442695040888963407;
10const MULTIPLIER: u64 = 6364136223846793005;
11
12pub struct RandGenerator {
13 state: AtomicU64,
14}
15
16impl RandGenerator {
17 pub const fn new() -> Self {
18 Self {
19 state: AtomicU64::new(0),
20 }
21 }
22 pub fn srand(&self, seed: u64) {
23 self.state.store(0, Ordering::Relaxed);
24 self.rand();
25 let oldstate = self.state.load(Ordering::Relaxed);
26 self.state
27 .store(oldstate.wrapping_add(seed), Ordering::Relaxed);
28 self.rand();
29 }
30 pub fn rand(&self) -> u32 {
31 let oldstate: u64 = self.state.load(Ordering::Relaxed);
32 self.state.store(
33 oldstate.wrapping_mul(MULTIPLIER).wrapping_add(DEFAULT_INC),
34 Ordering::Relaxed,
35 );
36 let xorshifted: u32 = (((oldstate >> 18) ^ oldstate) >> 27) as u32;
37 let rot: u32 = (oldstate >> 59) as u32;
38 xorshifted.rotate_right(rot)
39 }
40 #[inline]
41 pub fn gen_range<T>(&self, low: T, high: T) -> T
42 where
43 T: RandomRange,
44 {
45 T::gen_range_with_state(self, low, high)
46 }
47}
48
49static GLOBAL_STATE: RandGenerator = RandGenerator::new();
50
51#[inline]
54pub fn srand(seed: u64) {
55 GLOBAL_STATE.srand(seed);
56}
57
58#[inline]
60pub fn rand() -> u32 {
61 GLOBAL_STATE.rand()
62}
63
64pub trait RandomRange {
65 fn gen_range(low: Self, high: Self) -> Self;
66 fn gen_range_with_state(state: &RandGenerator, low: Self, high: Self) -> Self;
67}
68
69macro_rules! impl_random_range{
70 ($($ty:ty),*,)=>{
71 $(
72 impl RandomRange for $ty{
73 #[inline]
74 fn gen_range(low: Self, high: Self) -> Self{
75 Self::gen_range_with_state(&GLOBAL_STATE, low, high)
76 }
77 #[inline]
78 fn gen_range_with_state(gen: &RandGenerator, low: Self, high: Self) -> Self {
79 let r = gen.rand() as f64 / (u32::MAX as f64 + 1.0);
80 let r = low as f64 + (high as f64 - low as f64) * r;
81 r as Self
82 }
83 }
84 )*
85 }
86}
87impl_random_range!(f32, f64, u8, u16, u32, u64, usize, i8, i16, i32, i64, isize,);
88
89#[inline]
90pub fn gen_range<T>(low: T, high: T) -> T
91where
92 T: RandomRange,
93{
94 GLOBAL_STATE.gen_range(low, high)
95}
96
97pub struct SliceChooseIter<'a, T> {
98 source: &'a [T],
99 indices: alloc::vec::IntoIter<usize>,
100}
101
102impl<'a, T> Iterator for SliceChooseIter<'a, T> {
103 type Item = &'a T;
104
105 #[inline]
106 fn next(&mut self) -> Option<&'a T> {
107 self.indices.next().map(|ix| &self.source[ix])
108 }
109}
110
111pub trait ChooseRandom<T> {
112 #[inline]
113 fn shuffle(&mut self) {
114 self.shuffle_with_state(&GLOBAL_STATE)
115 }
116 #[inline]
117 fn choose(&self) -> Option<&T> {
118 self.choose_with_state(&GLOBAL_STATE)
119 }
120 #[inline]
121 fn choose_mut(&mut self) -> Option<&mut T> {
122 self.choose_mut_with_state(&GLOBAL_STATE)
123 }
124 #[inline]
125 fn choose_multiple(&self, amount: usize) -> SliceChooseIter<T> {
126 self.choose_multiple_with_state(&GLOBAL_STATE, amount)
127 }
128
129 fn shuffle_with_state(&mut self, state: &RandGenerator);
130 fn choose_with_state(&self, state: &RandGenerator) -> Option<&T>;
131 fn choose_mut_with_state(&mut self, state: &RandGenerator) -> Option<&mut T>;
132 fn choose_multiple_with_state(
133 &self,
134 state: &RandGenerator,
135 _amount: usize,
136 ) -> SliceChooseIter<T>;
137}
138
139impl<T> ChooseRandom<T> for [T] {
140 #[inline]
141 fn shuffle_with_state(&mut self, state: &RandGenerator) {
142 let mut fy = fy::FisherYates::default();
143
144 fy.shuffle_with_state(state, self);
145 }
146
147 #[inline]
148 fn choose_with_state(&self, state: &RandGenerator) -> Option<&T> {
149 let ix = state.gen_range(0, self.len());
150 self.get(ix)
151 }
152
153 #[inline]
154 fn choose_mut_with_state(&mut self, state: &RandGenerator) -> Option<&mut T> {
155 let ix = state.gen_range(0, self.len());
156 self.get_mut(ix)
157 }
158
159 #[inline]
160 fn choose_multiple_with_state(
161 &self,
162 state: &RandGenerator,
163 amount: usize,
164 ) -> SliceChooseIter<T> {
165 let mut indices = (0..self.len())
166 .enumerate()
167 .map(|(i, _)| i)
168 .collect::<Vec<usize>>();
169
170 indices.shuffle_with_state(state);
171 indices.resize(amount, 0);
172
173 SliceChooseIter {
174 source: self,
175 indices: indices.into_iter(),
176 }
177 }
178}
179
180#[cfg(feature = "rand")]
181pub mod compat {
182 pub struct QuadRandWithState<'a>(pub &'a crate::RandGenerator);
183
184 impl<'a> rand::RngCore for QuadRandWithState<'a> {
185 #[inline]
186 fn next_u32(&mut self) -> u32 {
187 self.0.gen_range(0, u32::MAX)
188 }
189
190 #[inline]
191 fn next_u64(&mut self) -> u64 {
192 self.0.gen_range(0, u64::MAX)
193 }
194
195 #[inline]
196 fn fill_bytes(&mut self, dest: &mut [u8]) {
197 for i in 0..dest.len() {
198 dest[i] = self.0.gen_range(0, 255)
199 }
200 }
201
202 #[inline]
203 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
204 Ok(self.fill_bytes(dest))
205 }
206 }
207
208 pub struct QuadRand;
209
210 impl rand::RngCore for QuadRand {
211 #[inline]
212 fn next_u32(&mut self) -> u32 {
213 QuadRandWithState(&crate::GLOBAL_STATE).next_u32()
214 }
215
216 #[inline]
217 fn next_u64(&mut self) -> u64 {
218 QuadRandWithState(&crate::GLOBAL_STATE).next_u64()
219 }
220
221 #[inline]
222 fn fill_bytes(&mut self, dest: &mut [u8]) {
223 QuadRandWithState(&crate::GLOBAL_STATE).fill_bytes(dest)
224 }
225
226 #[inline]
227 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
228 QuadRandWithState(&crate::GLOBAL_STATE).try_fill_bytes(dest)
229 }
230 }
231}