rmath 0.1.5

A rust math library
Documentation
use crate::rand::{Source, Seed, RandError, RandErrKind, Result, PrimitiveType};

#[cfg(target_arch = "x86_64")]
use std::arch::x86_64 as march;

#[cfg(target_arch = "x86")]
use std::arch::x86 as march;
use std::marker::PhantomData;

#[derive(Clone)]
pub struct DefaultRand<T> {
    ph: PhantomData<T>
}

impl<T: PrimitiveType> DefaultRand<T> {
    pub fn new<Sd: Seed<T>>(_sd: &Sd) -> Result<Self> {
        Ok(DefaultRand {ph: PhantomData})
    }
    
    #[target_feature(enable = "rdrand")]
    unsafe fn gen_u32(&mut self) -> Result<u32> {
        let mut out = 0;
        if march::_rdrand32_step(&mut out) > 0 {
            Ok(out)
        } else {
            Err(RandError::new(RandErrKind::NoNewRandNumberGen, ""))
        }
    }

    #[cfg(target_arch = "x86")]
    #[target_feature(enable = "rdrand")]
    unsafe fn gen_u64(&mut self) -> Result<u64> {
        match self.gen_u32() {
            Ok(low) => self.gen_u32().map(|high| {
                Ok((low as u64) | ((high as u64) << 32))
            }),
            Err(e) => Err(e),
        }
    }

    #[cfg(target_arch = "x86_64")]
    #[target_feature(enable = "rdrand")]
    unsafe fn gen_u64(&mut self) -> Result<u64> {
        let mut out = 0;
        if march::_rdrand64_step(&mut out) > 0 {
            Ok(out)
        } else {
            Err(RandError::new(RandErrKind::NoNewRandNumberGen, ""))
        }
    }
    
    fn gen_usize(&mut self) -> Result<usize> {
        #[cfg(target_pointer_width = "32")]
            unsafe {self.gen_u32().map(|x| {x as usize}) }

        #[cfg(target_pointer_width = "64")]
            unsafe {self.gen_u64().map(|x| {x as usize})}
    }
}

impl Source<u32> for DefaultRand<u32> {
    fn gen(&mut self) -> Result<u32> {
        unsafe {
            self.gen_u32()
        }
    }

    fn reset<Sd: Seed<u32>>(&mut self, _sd: &Sd) -> Result<()> {
        Ok(())
    }
}

impl Source<u64> for DefaultRand<u64> {
    fn gen(&mut self) -> Result<u64> {
        unsafe {
            self.gen_u64()
        }
    }

    fn reset<Sd: Seed<u64>>(&mut self, _sd: &Sd) -> Result<()> {
        Ok(())
    }
}

impl Source<usize> for DefaultRand<usize> {
    fn gen(&mut self) -> Result<usize> {
        self.gen_usize()
    }

    fn reset<Sd: Seed<usize>>(&mut self, _sd: &Sd) -> Result<()> {
        Ok(())
    }
}