1#![cfg_attr(not(feature = "std"), no_std)]
102#![cfg_attr(docsrs, feature(doc_cfg))]
103#![forbid(unsafe_code)]
104#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
105#![doc(
106 html_favicon_url = "https://raw.githubusercontent.com/smol-rs/smol/master/assets/images/logo_fullsize_transparent.png"
107)]
108#![doc(
109 html_logo_url = "https://raw.githubusercontent.com/smol-rs/smol/master/assets/images/logo_fullsize_transparent.png"
110)]
111
112#[cfg(feature = "alloc")]
113extern crate alloc;
114
115use core::convert::{TryFrom, TryInto};
116use core::ops::{Bound, RangeBounds};
117
118#[cfg(feature = "alloc")]
119use alloc::vec::Vec;
120
121#[cfg(feature = "std")]
122#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
123mod global_rng;
124
125#[cfg(feature = "std")]
126pub use global_rng::*;
127
128#[derive(Debug, PartialEq, Eq)]
130pub struct Rng(u64);
131
132impl Clone for Rng {
133 fn clone(&self) -> Rng {
135 Rng::with_seed(self.0)
136 }
137}
138
139impl Rng {
140 #[inline]
142 fn gen_u32(&mut self) -> u32 {
143 self.gen_u64() as u32
144 }
145
146 #[inline]
148 fn gen_u64(&mut self) -> u64 {
149 let s = self.0.wrapping_add(0xA0761D6478BD642F);
150 self.0 = s;
151 let t = u128::from(s) * u128::from(s ^ 0xE7037ED1A0B428DB);
152 (t as u64) ^ (t >> 64) as u64
153 }
154
155 #[inline]
157 fn gen_u128(&mut self) -> u128 {
158 (u128::from(self.gen_u64()) << 64) | u128::from(self.gen_u64())
159 }
160
161 #[inline]
163 fn gen_mod_u32(&mut self, n: u32) -> u32 {
164 let mut r = self.gen_u32();
166 let mut hi = mul_high_u32(r, n);
167 let mut lo = r.wrapping_mul(n);
168 if lo < n {
169 let t = n.wrapping_neg() % n;
170 while lo < t {
171 r = self.gen_u32();
172 hi = mul_high_u32(r, n);
173 lo = r.wrapping_mul(n);
174 }
175 }
176 hi
177 }
178
179 #[inline]
181 fn gen_mod_u64(&mut self, n: u64) -> u64 {
182 let mut r = self.gen_u64();
184 let mut hi = mul_high_u64(r, n);
185 let mut lo = r.wrapping_mul(n);
186 if lo < n {
187 let t = n.wrapping_neg() % n;
188 while lo < t {
189 r = self.gen_u64();
190 hi = mul_high_u64(r, n);
191 lo = r.wrapping_mul(n);
192 }
193 }
194 hi
195 }
196
197 #[inline]
199 fn gen_mod_u128(&mut self, n: u128) -> u128 {
200 let mut r = self.gen_u128();
202 let mut hi = mul_high_u128(r, n);
203 let mut lo = r.wrapping_mul(n);
204 if lo < n {
205 let t = n.wrapping_neg() % n;
206 while lo < t {
207 r = self.gen_u128();
208 hi = mul_high_u128(r, n);
209 lo = r.wrapping_mul(n);
210 }
211 }
212 hi
213 }
214}
215
216#[inline]
218fn mul_high_u32(a: u32, b: u32) -> u32 {
219 (((a as u64) * (b as u64)) >> 32) as u32
220}
221
222#[inline]
224fn mul_high_u64(a: u64, b: u64) -> u64 {
225 (((a as u128) * (b as u128)) >> 64) as u64
226}
227
228#[inline]
230fn mul_high_u128(a: u128, b: u128) -> u128 {
231 let a_lo = a as u64 as u128;
233 let a_hi = (a >> 64) as u64 as u128;
234 let b_lo = b as u64 as u128;
235 let b_hi = (b >> 64) as u64 as u128;
236 let carry = (a_lo * b_lo) >> 64;
237 let carry = ((a_hi * b_lo) as u64 as u128 + (a_lo * b_hi) as u64 as u128 + carry) >> 64;
238 a_hi * b_hi + ((a_hi * b_lo) >> 64) + ((a_lo * b_hi) >> 64) + carry
239}
240
241macro_rules! rng_integer {
242 ($t:tt, $unsigned_t:tt, $gen:tt, $mod:tt, $doc:tt) => {
243 #[doc = $doc]
244 #[inline]
247 pub fn $t(&mut self, range: impl RangeBounds<$t>) -> $t {
248 let panic_empty_range = || {
249 panic!(
250 "empty range: {:?}..{:?}",
251 range.start_bound(),
252 range.end_bound()
253 )
254 };
255
256 let low = match range.start_bound() {
257 Bound::Unbounded => core::$t::MIN,
258 Bound::Included(&x) => x,
259 Bound::Excluded(&x) => x.checked_add(1).unwrap_or_else(panic_empty_range),
260 };
261
262 let high = match range.end_bound() {
263 Bound::Unbounded => core::$t::MAX,
264 Bound::Included(&x) => x,
265 Bound::Excluded(&x) => x.checked_sub(1).unwrap_or_else(panic_empty_range),
266 };
267
268 if low > high {
269 panic_empty_range();
270 }
271
272 if low == core::$t::MIN && high == core::$t::MAX {
273 self.$gen() as $t
274 } else {
275 let len = high.wrapping_sub(low).wrapping_add(1);
276 low.wrapping_add(self.$mod(len as $unsigned_t as _) as $t)
277 }
278 }
279 };
280}
281
282impl Rng {
283 #[inline]
285 #[must_use = "this creates a new instance of `Rng`; if you want to initialize the thread-local generator, use `fastrand::seed()` instead"]
286 pub fn with_seed(seed: u64) -> Self {
287 let mut rng = Rng(0);
288
289 rng.seed(seed);
290 rng
291 }
292
293 #[inline]
317 #[must_use = "this creates a new instance of `Rng`"]
318 pub fn fork(&mut self) -> Self {
319 Rng::with_seed(self.gen_u64())
320 }
321
322 #[inline]
324 pub fn alphabetic(&mut self) -> char {
325 const CHARS: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
326 *self.choice(CHARS).unwrap() as char
327 }
328
329 #[inline]
331 pub fn alphanumeric(&mut self) -> char {
332 const CHARS: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
333 *self.choice(CHARS).unwrap() as char
334 }
335
336 #[inline]
338 pub fn bool(&mut self) -> bool {
339 self.u8(..) % 2 == 0
340 }
341
342 #[inline]
348 pub fn digit(&mut self, base: u32) -> char {
349 if base == 0 {
350 panic!("base cannot be zero");
351 }
352 if base > 36 {
353 panic!("base cannot be larger than 36");
354 }
355 let num = self.u8(..base as u8);
356 if num < 10 {
357 (b'0' + num) as char
358 } else {
359 (b'a' + num - 10) as char
360 }
361 }
362
363 pub fn f32(&mut self) -> f32 {
365 let b = 32;
366 let f = core::f32::MANTISSA_DIGITS - 1;
367 f32::from_bits((1 << (b - 2)) - (1 << f) + (self.u32(..) >> (b - f))) - 1.0
368 }
369
370 pub fn f64(&mut self) -> f64 {
372 let b = 64;
373 let f = core::f64::MANTISSA_DIGITS - 1;
374 f64::from_bits((1 << (b - 2)) - (1 << f) + (self.u64(..) >> (b - f))) - 1.0
375 }
376
377 #[cfg(feature = "alloc")]
385 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
386 pub fn choose_multiple<T: Iterator>(&mut self, mut source: T, amount: usize) -> Vec<T::Item> {
387 let mut reservoir = Vec::with_capacity(amount);
389
390 reservoir.extend(source.by_ref().take(amount));
391
392 if reservoir.len() == amount {
397 for (i, elem) in source.enumerate() {
398 let end = i + 1 + amount;
399 let k = self.usize(0..end);
400 if let Some(slot) = reservoir.get_mut(k) {
401 *slot = elem;
402 }
403 }
404 } else {
405 if reservoir.capacity() > 3 * reservoir.len() {
409 reservoir.shrink_to_fit();
410 }
411 }
412 reservoir
413 }
414
415 rng_integer!(
416 i8,
417 u8,
418 gen_u32,
419 gen_mod_u32,
420 "Generates a random `i8` in the given range."
421 );
422
423 rng_integer!(
424 i16,
425 u16,
426 gen_u32,
427 gen_mod_u32,
428 "Generates a random `i16` in the given range."
429 );
430
431 rng_integer!(
432 i32,
433 u32,
434 gen_u32,
435 gen_mod_u32,
436 "Generates a random `i32` in the given range."
437 );
438
439 rng_integer!(
440 i64,
441 u64,
442 gen_u64,
443 gen_mod_u64,
444 "Generates a random `i64` in the given range."
445 );
446
447 rng_integer!(
448 i128,
449 u128,
450 gen_u128,
451 gen_mod_u128,
452 "Generates a random `i128` in the given range."
453 );
454
455 #[cfg(target_pointer_width = "16")]
456 rng_integer!(
457 isize,
458 usize,
459 gen_u32,
460 gen_mod_u32,
461 "Generates a random `isize` in the given range."
462 );
463 #[cfg(target_pointer_width = "32")]
464 rng_integer!(
465 isize,
466 usize,
467 gen_u32,
468 gen_mod_u32,
469 "Generates a random `isize` in the given range."
470 );
471 #[cfg(target_pointer_width = "64")]
472 rng_integer!(
473 isize,
474 usize,
475 gen_u64,
476 gen_mod_u64,
477 "Generates a random `isize` in the given range."
478 );
479
480 #[inline]
482 pub fn lowercase(&mut self) -> char {
483 const CHARS: &[u8] = b"abcdefghijklmnopqrstuvwxyz";
484 *self.choice(CHARS).unwrap() as char
485 }
486
487 #[inline]
489 pub fn seed(&mut self, seed: u64) {
490 self.0 = seed;
491 }
492
493 #[inline]
495 pub fn get_seed(&self) -> u64 {
496 self.0
497 }
498
499 #[inline]
505 pub fn choice<I>(&mut self, iter: I) -> Option<I::Item>
506 where
507 I: IntoIterator,
508 I::IntoIter: ExactSizeIterator,
509 {
510 let mut iter = iter.into_iter();
511
512 let len = iter.len();
514 if len == 0 {
515 return None;
516 }
517 let index = self.usize(0..len);
518
519 iter.nth(index)
520 }
521
522 #[inline]
524 pub fn shuffle<T>(&mut self, slice: &mut [T]) {
525 for i in 1..slice.len() {
526 slice.swap(i, self.usize(..=i));
527 }
528 }
529
530 #[inline]
532 pub fn fill(&mut self, slice: &mut [u8]) {
533 let mut chunks = slice.chunks_exact_mut(core::mem::size_of::<u64>());
536 for chunk in chunks.by_ref() {
537 let n = self.gen_u64().to_ne_bytes();
538 chunk.copy_from_slice(&n);
540 }
541
542 let remainder = chunks.into_remainder();
543
544 if !remainder.is_empty() {
546 let n = self.gen_u64().to_ne_bytes();
548
549 remainder.copy_from_slice(&n[..remainder.len()]);
551 }
552 }
553
554 rng_integer!(
555 u8,
556 u8,
557 gen_u32,
558 gen_mod_u32,
559 "Generates a random `u8` in the given range."
560 );
561
562 rng_integer!(
563 u16,
564 u16,
565 gen_u32,
566 gen_mod_u32,
567 "Generates a random `u16` in the given range."
568 );
569
570 rng_integer!(
571 u32,
572 u32,
573 gen_u32,
574 gen_mod_u32,
575 "Generates a random `u32` in the given range."
576 );
577
578 rng_integer!(
579 u64,
580 u64,
581 gen_u64,
582 gen_mod_u64,
583 "Generates a random `u64` in the given range."
584 );
585
586 rng_integer!(
587 u128,
588 u128,
589 gen_u128,
590 gen_mod_u128,
591 "Generates a random `u128` in the given range."
592 );
593
594 #[cfg(target_pointer_width = "16")]
595 rng_integer!(
596 usize,
597 usize,
598 gen_u32,
599 gen_mod_u32,
600 "Generates a random `usize` in the given range."
601 );
602 #[cfg(target_pointer_width = "32")]
603 rng_integer!(
604 usize,
605 usize,
606 gen_u32,
607 gen_mod_u32,
608 "Generates a random `usize` in the given range."
609 );
610 #[cfg(target_pointer_width = "64")]
611 rng_integer!(
612 usize,
613 usize,
614 gen_u64,
615 gen_mod_u64,
616 "Generates a random `usize` in the given range."
617 );
618 #[cfg(target_pointer_width = "128")]
619 rng_integer!(
620 usize,
621 usize,
622 gen_u128,
623 gen_mod_u128,
624 "Generates a random `usize` in the given range."
625 );
626
627 #[inline]
629 pub fn uppercase(&mut self) -> char {
630 const CHARS: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
631 *self.choice(CHARS).unwrap() as char
632 }
633
634 #[inline]
638 pub fn char(&mut self, range: impl RangeBounds<char>) -> char {
639 let panic_empty_range = || {
640 panic!(
641 "empty range: {:?}..{:?}",
642 range.start_bound(),
643 range.end_bound()
644 )
645 };
646
647 let surrogate_start = 0xd800u32;
648 let surrogate_len = 0x800u32;
649
650 let low = match range.start_bound() {
651 Bound::Unbounded => 0u8 as char,
652 Bound::Included(&x) => x,
653 Bound::Excluded(&x) => {
654 let scalar = if x as u32 == surrogate_start - 1 {
655 surrogate_start + surrogate_len
656 } else {
657 x as u32 + 1
658 };
659 char::try_from(scalar).unwrap_or_else(|_| panic_empty_range())
660 }
661 };
662
663 let high = match range.end_bound() {
664 Bound::Unbounded => core::char::MAX,
665 Bound::Included(&x) => x,
666 Bound::Excluded(&x) => {
667 let scalar = if x as u32 == surrogate_start + surrogate_len {
668 surrogate_start - 1
669 } else {
670 (x as u32).wrapping_sub(1)
671 };
672 char::try_from(scalar).unwrap_or_else(|_| panic_empty_range())
673 }
674 };
675
676 if low > high {
677 panic_empty_range();
678 }
679
680 let gap = if (low as u32) < surrogate_start && (high as u32) >= surrogate_start {
681 surrogate_len
682 } else {
683 0
684 };
685 let range = high as u32 - low as u32 - gap;
686 let mut val = self.u32(0..=range) + low as u32;
687 if val >= surrogate_start {
688 val += gap;
689 }
690 val.try_into().unwrap()
691 }
692}