butils 0.1.1

Utilities shared by software included in BSuccinct.
Documentation
#![doc = include_str!("../README.md")]

/// Infinitive iterator over random `u64` values generated by XorShift64 algorithm.
///
/// It must be initialized with non-zero seed, never generates zero, and its period is 2^64-1.
///
/// The algorithm is described in:
/// - George Marsaglia, "Xorshift RNGs", Journal of Statistical Software, 2003, 8(14), 1–6,
///   <https://doi.org/10.18637/jss.v008.i14>
#[derive(Clone, Copy)]
pub struct XorShift64(pub u64);

impl XorShift64 {
    /// Generates and returns next `u64` value.
    pub fn get(&mut self) -> u64 {
        self.0 ^= self.0 << 13;
        self.0 ^= self.0 >> 7;
        self.0 ^= self.0 << 17;
        self.0
    }
}

impl Iterator for XorShift64 {
    type Item = u64;

    #[inline] fn next(&mut self) -> Option<Self::Item> {
        Some(self.get())
    }

    #[inline] fn size_hint(&self) -> (usize, Option<usize>) {
        (usize::MAX, None)
    }
}

//impl ExactSizeIterator for XorShift64 {}

/// Infinitive iterator over random `u32` values generated by XorShift32 algorithm.
///
/// It must be initialized with non-zero seed, never generates zero, and its period is 2^32-1.
///
/// The algorithm is described in:
/// - George Marsaglia, "Xorshift RNGs", Journal of Statistical Software, 2003, 8(14), 1–6,
///   <https://doi.org/10.18637/jss.v008.i14>
#[derive(Clone, Copy)]
pub struct XorShift32(pub u32);

impl XorShift32 {
    /// Generates and returns next `u32` value.
    pub fn get(&mut self) -> u32 {
        self.0 ^= self.0 << 13;
        self.0 ^= self.0 >> 17;
        self.0 ^= self.0 << 5;
        self.0
    }
}

impl Iterator for XorShift32 {
    type Item = u32;

    #[inline] fn next(&mut self) -> Option<Self::Item> { Some(self.get()) }

    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { (usize::MAX, None) }
}

//impl ExactSizeIterator for XorShift32 {}

/// Trait defined to extend the `f64` type with unit conversion methods.
pub trait UnitPrefix {
    /// Returns `self * 1_000`.
    fn as_milis(self) -> Self;
    /// Returns `self * 1_000_000`.
    fn as_micros(self) -> Self;
    /// Returns `self * 1_000_000_000`.
    fn as_nanos(self) -> Self;
    /// Returns `self * 1_000_000_000_000`.
    fn as_picos(self) -> Self;
}

impl UnitPrefix for f64 {
    #[inline(always)] fn as_milis(self) -> f64 { self * 1_000.0 }
    #[inline(always)] fn as_micros(self) -> f64 { self * 1_000_000.0 }
    #[inline(always)] fn as_nanos(self) -> f64 { self * 1_000_000_000.0 }
    #[inline(always)] fn as_picos(self) -> f64 { self * 1_000_000_000_000.0 }
}