ya-rand 2.0.2

A crate for simple and fast random number generation
Documentation
use crate::rng::{Generator, SeedableGenerator};
use crate::util;

/// Rust implementation of the xoshiro512++ PRNG.
///
/// This generator is very fast, high-quality, and small,
/// but not cryptographically secure.
///
/// More information can be found at: <https://prng.di.unimi.it/>.
#[derive(Debug, PartialEq, Eq)]
pub struct Xoshiro512pp {
    state: [u64; 8],
}

impl Default for Xoshiro512pp {
    fn default() -> Self {
        Self::new_with_seed(0)
    }
}

impl SeedableGenerator for Xoshiro512pp {
    fn new_with_seed(seed: u64) -> Self {
        let state = util::state_from_seed(seed);
        let mut ret = Self { state };
        let _discard_first = ret.u64();
        ret
    }
}

impl Generator for Xoshiro512pp {
    #[inline]
    fn try_new() -> Result<Self, getrandom::Error> {
        let state = util::state_from_entropy()?;
        Ok(Self { state })
    }

    #[cfg_attr(feature = "inline", inline)]
    fn u64(&mut self) -> u64 {
        let result = self.state[0]
            .wrapping_add(self.state[2])
            .rotate_left(17)
            .wrapping_add(self.state[2]);
        let tmp = self.state[1] << 11;

        self.state[2] ^= self.state[0];
        self.state[5] ^= self.state[1];
        self.state[1] ^= self.state[2];
        self.state[7] ^= self.state[3];
        self.state[3] ^= self.state[4];
        self.state[4] ^= self.state[5];
        self.state[0] ^= self.state[6];
        self.state[6] ^= self.state[7];

        self.state[6] ^= tmp;
        self.state[7] = self.state[7].rotate_left(21);

        result
    }
}