1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//! A dead simple to use randomization library for rust.
//!
//! Compiles and works on the GBA.
//!
//! # Basic Usage
//!
//! ```rust
//! use randomize::pcg::{PCGPickU64, PCGMemU64, PCGPhantomU64};
//! use typenum::consts::U5;
//!
//! // On `x86` family CPUs we can seed from the CPU counter.
//! #[cfg(any(target_arch = "x86",target_arch = "x86_64"))]
//! let u: u64 = randomize::u64_from_rdtsc();
//!
//! // On other CPUs you'll need to get a seed from somewhere.
//! #[cfg(not(any(target_arch = "x86",target_arch = "x86_64")))]
//! let u: u64 = 1776;
//!
//! let pick_gen = &mut PCGPickU64::seed(u, u);
//! let mem_gen = &mut PCGMemU64::seed(u);
//! let phantom_gen: &mut PCGPhantomU64<U5> = &mut PCGPhantomU64::seed(u);
//!
//! println!("{}", pick_gen.next_u32());
//! ```
//!
//! # NOT FOR CRYPTOGRAPHIC PURPOSES.
//!
//! The crate is specific to my personal needs for building games and such. I
//! don't want to, or try to, cover all use cases. If you need a highly general
//! crate for randomization you should use the
//! [rand](https://crates.io/crates/rand) crate, which is the "official" way to
//! do randomization in rust.

#![no_std]
#![feature(const_int_wrapping)]
#![feature(const_int_rotate)]
#![feature(const_int_ops)]
#![feature(const_fn)]
#![feature(const_let)]
#![allow(clippy::cast_lossless)]
#![allow(clippy::unreadable_literal)]
#![deny(clippy::float_arithmetic)]
#![forbid(missing_debug_implementations)]
#![warn(missing_docs)]

#[cfg(feature = "serde_support")]
extern crate serde;
#[cfg(feature = "serde_support")]
#[macro_use]
extern crate serde_derive;

pub(crate) use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8};

pub mod lcg;
pub(crate) use self::lcg::*;

pub mod mcg;
pub use self::mcg::*; // TODO(Lokathor): Remove this in 3.0

pub mod pcg;
pub use self::pcg::*;

pub mod noncg;

pub mod bounded;
pub use self::bounded::*;

/// Calls `rdtsc` to get a semi-arbitrary `u64` value.
#[cfg(target_arch = "x86")]
pub fn u64_from_rdtsc() -> u64 {
  unsafe { core::arch::x86::_rdtsc() as u64 }
}
/// Calls `rdtsc` to get a semi-arbitrary `u64` value.
#[cfg(target_arch = "x86_64")]
pub fn u64_from_rdtsc() -> u64 {
  unsafe { core::arch::x86_64::_rdtsc() as u64 }
}
// TODO(Lokathor): In 3.0 we might want to move this to a "get me an arbitrary
// `u64` if you can" type operation. On ARM this might be the `__current_pc`
// intrinsic for example, which is possibly arbitrary enough.

// TODO: bounded results, we must also allow pre-computed bounds to be cached

// TODO: extension arrays for longer periods

// jsf32?