#![allow(unused)]
use std::slice::from_raw_parts_mut;
use crate::{cbrng::b64::Threefish256, i2f_bits, u2f_01};
#[unsafe(no_mangle)]
pub extern "C" fn threefish256_new(seed: u64) -> *mut Threefish256 {
Box::into_raw(Box::new(Threefish256::new(seed)))
}
#[unsafe(no_mangle)]
pub extern "C" fn threefish256_free(ptr: *mut Threefish256) {
if !ptr.is_null() {
unsafe { drop(Box::from_raw(ptr)) };
}
}
#[inline(always)]
fn threefish256_fill<T, M>(rng: &mut Threefish256, buffer: &mut [T], map: M)
where
M: Fn(u64) -> T,
{
for chunk in buffer.chunks_mut(4) {
let r = rng.next_raw();
for (dst, v) in chunk.iter_mut().zip(r) {
*dst = map(*v);
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn threefish256_next_u64s(ptr: *mut Threefish256, out: *mut u64, count: usize) {
unsafe {
let rng = &mut *ptr;
let buffer = from_raw_parts_mut(out, count);
threefish256_fill(rng, buffer, |x| x);
}
}
#[unsafe(no_mangle)]
pub extern "C" fn threefish256_next_f64s(ptr: *mut Threefish256, out: *mut f64, count: usize) {
unsafe {
let rng = &mut *ptr;
let buffer = from_raw_parts_mut(out, count);
threefish256_fill(rng, buffer, |x| u2f_01!(f64, 64, x));
}
}
#[unsafe(no_mangle)]
pub extern "C" fn threefish256_rand_i64s(
ptr: *mut Threefish256,
out: *mut i64,
count: usize,
min: i64,
max: i64,
) {
unsafe {
let rng = &mut *ptr;
let buffer = from_raw_parts_mut(out, count);
let range = (max as i128 - min as i128 + 1) as u128;
threefish256_fill(rng, buffer, |x| ((x as u128 * range) >> 64) as i64 + min);
}
}
#[unsafe(no_mangle)]
pub extern "C" fn threefish256_rand_f64s(
ptr: *mut Threefish256,
out: *mut f64,
count: usize,
min: f64,
max: f64,
) {
unsafe {
let rng = &mut *ptr;
let buffer = from_raw_parts_mut(out, count);
let mult = max - min;
threefish256_fill(rng, buffer, |x| u2f_01!(f64, 64, x) * mult + min);
}
}