#![warn(clippy::pedantic)]
#![no_std]
use core::mem::{self, MaybeUninit};
use alloc::{
alloc::{handle_alloc_error, Layout, LayoutError},
boxed::Box,
};
extern crate alloc;
pub unsafe fn new<T, const N: usize>(initial: &T) -> Result<Box<[T; N]>, LayoutError>
where
T: Clone,
{
let mut arr = new_uninit::<T, N>()?;
for v in arr.as_mut() {
v.write(initial.clone());
}
Ok(mem::transmute(arr))
}
pub unsafe fn new_default<T, const N: usize>() -> Result<Box<[T; N]>, LayoutError>
where
T: Default,
{
let mut arr = new_uninit::<T, N>()?;
for v in arr.as_mut() {
v.write(T::default());
}
Ok(mem::transmute(arr))
}
pub unsafe fn new_uninit<T, const N: usize>() -> Result<Box<[MaybeUninit<T>; N]>, LayoutError> {
let layout = Layout::array::<T>(N)?;
let ptr = alloc::alloc::alloc(layout);
if ptr.is_null() {
handle_alloc_error(layout);
}
Ok(Box::from_raw(ptr.cast()))
}
#[cfg(test)]
mod tests {
#[test]
fn test_new() {
let arr = unsafe { super::new::<Option<bool>, 1_000>(&Some(false)).unwrap() };
assert_eq!(arr.len(), 1_000);
assert_eq!(arr[999], Some(false));
}
#[test]
fn test_default() {
let arr = unsafe { super::new_default::<Option<bool>, 1_000>().unwrap() };
assert_eq!(arr.len(), 1_000);
assert_eq!(arr[999], None);
}
#[test]
fn test_uninit() {
let _ = unsafe { super::new_uninit::<u64, 1_000>().unwrap() };
}
}