use std::{alloc::{alloc_zeroed, dealloc, Layout}, slice::{from_raw_parts, from_raw_parts_mut}, ops::{Index, IndexMut}, mem::size_of}; const ALIGN_SIMD: usize = 64; // enough to support AVX-512 pub type AlignedMemory64 = AlignedMemory; pub struct AlignedMemory { p: *mut u64, sz_u64: usize, layout: Layout } impl AlignedMemory<{ALIGN}> { pub fn new(sz_u64: usize) -> Self { let sz_bytes = sz_u64 * size_of::(); let layout = Layout::from_size_align(sz_bytes, ALIGN).unwrap(); let ptr; unsafe { ptr = alloc_zeroed(layout); } Self { p: ptr as *mut u64, sz_u64, layout } } pub fn as_slice(&self) -> &[u64] { unsafe { from_raw_parts(self.p, self.sz_u64) } } pub fn as_mut_slice(&mut self) -> &mut [u64] { unsafe { from_raw_parts_mut(self.p, self.sz_u64) } } pub fn len(&self) -> usize { self.sz_u64 } } impl Drop for AlignedMemory<{ALIGN}> { fn drop(&mut self) { unsafe { dealloc(self.p as *mut u8, self.layout); } } } impl Index for AlignedMemory<{ALIGN}> { type Output = u64; fn index(&self, index: usize) -> &Self::Output { &self.as_slice()[index] } } impl IndexMut for AlignedMemory<{ALIGN}> { fn index_mut(&mut self, index: usize) -> &mut Self::Output { &mut self.as_mut_slice()[index] } } impl Clone for AlignedMemory<{ALIGN}> { fn clone(&self) -> Self { let mut out = Self::new(self.sz_u64); out.as_mut_slice().copy_from_slice(self.as_slice()); out } }