From c054ac0174353b9f49588d415859891003696b97 Mon Sep 17 00:00:00 2001 From: Avril Date: Fri, 26 Mar 2021 03:24:13 +0000 Subject: [PATCH] begin adding rng --- shuffle3rs/src/main.rs | 1 + shuffle3rs/src/rng/mod.rs | 142 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 shuffle3rs/src/rng/mod.rs diff --git a/shuffle3rs/src/main.rs b/shuffle3rs/src/main.rs index 3be70e8..13a220e 100644 --- a/shuffle3rs/src/main.rs +++ b/shuffle3rs/src/main.rs @@ -10,6 +10,7 @@ mod shuffle; mod arg; mod proc; +mod rng; use arg::Mode; diff --git a/shuffle3rs/src/rng/mod.rs b/shuffle3rs/src/rng/mod.rs new file mode 100644 index 0000000..0cd8075 --- /dev/null +++ b/shuffle3rs/src/rng/mod.rs @@ -0,0 +1,142 @@ +//! Contains the RNGs used +use super::*; +use std::{ptr, slice, mem::{self, MaybeUninit}}; +use std::ops::Drop; + +/// A tuple packed into a type that can be used for SeedableRng::SEED. +#[derive(Debug)] +pub struct PackedTupleSeed([MaybeUninit; 2]); + +impl Eq for PackedTupleSeed{} +impl PartialEq for PackedTupleSeed +{ + fn eq(&self, other: &Self) -> bool + { + self.first() == other.first() && + self.second() == other.second() + } +} + +impl PackedTupleSeed +{ + pub const SIZE_BYTES: usize = mem::size_of::() * 2; + pub fn as_mut_array(&mut self) -> &mut [T; 2] + { + unsafe {&mut *(&mut self.0 as *mut [_; 2] as *mut [T; 2])} + } + pub fn as_array(&self) -> &[T; 2] + { + unsafe {& *(&self.0 as *const [_; 2] as *const [T; 2])} + } + pub fn second_mut(&mut self) -> &mut T + { + unsafe {&mut *self.0[1].as_mut_ptr()} + } + pub fn first_mut(&mut self) -> &mut T + { + unsafe {&mut *self.0[0].as_mut_ptr()} + } + pub fn second(&self) -> &T + { + unsafe {& *self.0[1].as_ptr()} + } + pub fn first(&self) -> &T + { + unsafe {& *self.0[0].as_ptr()} + } + + #[inline] pub fn new(a: T, b: T) -> Self { + Self ([ + MaybeUninit::new(a), + MaybeUninit::new(b), + ]) + } + + #[inline] pub fn into_tuple(self) -> (T, T) + { + let ab = unsafe { + (self.0[0].as_ptr().read(), + self.0[1].as_ptr().read()) + }; + mem::forget(self); + ab + } + + #[inline] pub fn into_second(self) -> T + { + self.into_tuple().1 + } + #[inline] pub fn into_first(self) -> T + { + self.into_tuple().0 + } +} + +impl From<(T, T)> for PackedTupleSeed +{ + fn from((a,b): (T, T)) -> Self + { + Self::new(a, b) + } +} + +impl From> for (T, T) +{ + fn from(from: PackedTupleSeed) -> Self + { + from.into_tuple() + } +} + +impl Clone for PackedTupleSeed +{ + fn clone(&self) -> Self { + Self([ + MaybeUninit::new(self.first().clone()), + MaybeUninit::new(self.second().clone()), + ]) + } +} + +impl Default for PackedTupleSeed +{ + #[inline] + fn default() -> Self + { + Self([ + MaybeUninit::new(Default::default()), + MaybeUninit::new(Default::default()), + ]) + } +} + +impl AsMut<[u8]> for PackedTupleSeed +{ + fn as_mut(&mut self) -> &mut [u8] + { + unsafe { + slice::from_raw_parts_mut(self as *mut Self as *mut u8, mem::size_of::()) + } + } +} +impl AsRef<[u8]> for PackedTupleSeed +{ + fn as_ref(&self) -> &[u8] + { + unsafe { + slice::from_raw_parts(self as *const Self as *const u8, mem::size_of::()) + } + } +} + +impl Drop for PackedTupleSeed +{ + fn drop(&mut self) { + if mem::needs_drop::() { + unsafe { + ptr::drop_in_place(self.0[0].as_mut_ptr()); + ptr::drop_in_place(self.0[1].as_mut_ptr()); + } + } + } +}