use core::marker::PhantomData;
use crate::{Nat, array::*, const_fmt};
#[track_caller]
pub(crate) const fn arr_len<A: Array>() -> usize {
const fn doit<N: Nat>() -> usize {
let precalc = const {
match crate::to_usize::<N>() {
Some(n) => Ok(n),
None => Err(const_fmt::fmt![
"Array length ",
PhantomData::<N>,
" exceeds the maximum value for a usize",
]),
}
};
match precalc {
Ok(n) => n,
Err(err) => err.panic(),
}
}
doit::<A::Length>()
}
pub(crate) const fn arr_impl_ubcheck<A: Array>() {
#[cfg(debug_assertions)]
const {
assert!(
align_of::<A>() == align_of::<A::Item>(),
"UB: Array alignment must be the same as that of item"
);
let item_size = size_of::<A::Item>();
let arr_size = size_of::<A>();
if let Some(arr_len) = crate::to_usize::<A::Length>() {
let calc_size = arr_len.checked_mul(item_size);
assert!(
calc_size.is_some() && arr_size == calc_size.unwrap(),
"UB: Array size must be equal to item size multiplied by length"
)
} else {
assert!(
item_size == 0 && arr_size == 0,
"UB: Array with length exceeding usize::MAX must be ZST"
)
}
}
}
#[track_caller]
pub(crate) const fn unsize_raw_mut<A: Array>(ptr: *mut A) -> *mut [A::Item] {
core::ptr::slice_from_raw_parts_mut(ptr.cast(), arr_len::<A>())
}