use std::mem::MaybeUninit;
pub unsafe fn assume_all_init<T>(ts: Box<[MaybeUninit<T>]>) -> Box<[T]> {
std::mem::transmute(ts)
}
pub fn new_uninit<T>(len: usize) -> Box<[MaybeUninit<T>]> {
unsafe {
let slice_ref_mut = if std::mem::size_of::<T>() == 0 {
std::slice::from_raw_parts_mut(std::ptr::NonNull::dangling().as_ptr(), len)
} else {
let layout = std::alloc::Layout::array::<MaybeUninit<T>>(len).unwrap();
let mem = std::alloc::alloc(layout) as *mut MaybeUninit<T>;
std::slice::from_raw_parts_mut(mem, len)
};
Box::from_raw(slice_ref_mut)
}
}
pub fn new_zeroed<T>(len: usize) -> Box<[MaybeUninit<T>]> {
unsafe {
let slice_ref_mut = if std::mem::size_of::<T>() == 0 {
std::slice::from_raw_parts_mut(std::ptr::NonNull::dangling().as_ptr(), len)
} else {
let layout = std::alloc::Layout::array::<MaybeUninit<T>>(len).unwrap();
let mem = std::alloc::alloc_zeroed(layout) as *mut MaybeUninit<T>;
std::slice::from_raw_parts_mut(mem, len)
};
Box::from_raw(slice_ref_mut)
}
}
pub fn new_copies<T>(len: usize, val: T) -> Box<[T]>
where
T: Copy,
{
let mut ts = new_uninit(len);
if std::mem::size_of::<T>() != 0 {
for t in ts.iter_mut() {
let ptr: *mut T = t.as_mut_ptr();
unsafe { ptr.write(val) }
}
}
unsafe { assume_all_init(ts) }
}
pub fn new_clones<T>(len: usize, val: T) -> Box<[T]>
where
T: Clone,
{
let mut ts = new_uninit(len);
if std::mem::size_of::<T>() != 0 {
for t in ts.iter_mut() {
let ptr: *mut T = t.as_mut_ptr();
unsafe { ptr.write(val.clone()) }
}
}
unsafe { assume_all_init(ts) }
}
pub fn new_defaults<T>(len: usize) -> Box<[T]>
where
T: Default,
{
let mut ts = new_uninit(len);
if std::mem::size_of::<T>() != 0 {
for t in ts.iter_mut() {
let ptr: *mut T = t.as_mut_ptr();
unsafe { ptr.write(T::default()) }
}
}
unsafe { assume_all_init(ts) }
}
pub fn new_with<T>(len: usize, mut gen: impl FnMut(usize) -> T) -> Box<[T]> {
let mut ts = new_uninit(len);
if std::mem::size_of::<T>() != 0 {
for (idx, t) in ts.iter_mut().enumerate() {
let ptr: *mut T = t.as_mut_ptr();
unsafe { ptr.write(gen(idx)) }
}
}
unsafe { assume_all_init(ts) }
}