use crate::{
core::optional::{gen_optional, NSTDOptional},
NSTDAny, NSTDAnyMut, NSTDUInt, NSTD_INT_MAX,
};
use nstdapi::nstdapi;
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct NSTDAllocLayout {
size: NSTDUInt,
align: NSTDUInt,
}
gen_optional!(NSTDOptionalAllocLayout, NSTDAllocLayout);
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub enum NSTDAllocError {
NSTD_ALLOC_ERROR_NONE,
NSTD_ALLOC_ERROR_OUT_OF_MEMORY,
NSTD_ALLOC_ERROR_MEMORY_NOT_FOUND,
NSTD_ALLOC_ERROR_HEAP_NOT_FOUND,
NSTD_ALLOC_ERROR_INVALID_HEAP,
NSTD_ALLOC_ERROR_INVALID_LAYOUT,
}
#[nstdapi]
#[derive(Clone, Copy)]
pub struct NSTDAllocator {
pub state: NSTDAny,
pub allocate: unsafe extern "C" fn(NSTDAny, NSTDAllocLayout) -> NSTDAnyMut,
pub allocate_zeroed: unsafe extern "C" fn(NSTDAny, NSTDAllocLayout) -> NSTDAnyMut,
pub reallocate: unsafe extern "C" fn(
NSTDAny,
&mut NSTDAnyMut,
NSTDAllocLayout,
NSTDAllocLayout,
) -> NSTDAllocError,
pub deallocate: unsafe extern "C" fn(NSTDAny, NSTDAnyMut, NSTDAllocLayout) -> NSTDAllocError,
}
unsafe impl Send for NSTDAllocator {}
unsafe impl Sync for NSTDAllocator {}
#[inline]
#[nstdapi]
pub const fn nstd_core_alloc_layout_new(
size: NSTDUInt,
align: NSTDUInt,
) -> NSTDOptionalAllocLayout {
match size <= NSTD_INT_MAX && crate::core::mem::is_power_of_two(align) {
true => NSTDOptional::Some(NSTDAllocLayout { size, align }),
false => NSTDOptional::None,
}
}
#[inline]
#[nstdapi]
pub const unsafe fn nstd_core_alloc_layout_new_unchecked(
size: NSTDUInt,
align: NSTDUInt,
) -> NSTDAllocLayout {
NSTDAllocLayout { size, align }
}
#[inline]
#[nstdapi]
pub const fn nstd_core_alloc_layout_array(
size: NSTDUInt,
align: NSTDUInt,
len: NSTDUInt,
) -> NSTDOptionalAllocLayout {
#[allow(clippy::arithmetic_side_effects)]
if crate::core::mem::is_power_of_two(align) && size % align == 0 {
if let Some(size) = size.checked_mul(len) {
if size <= NSTD_INT_MAX {
return NSTDOptional::Some(NSTDAllocLayout { size, align });
}
}
}
NSTDOptional::None
}
#[inline]
#[nstdapi]
#[allow(clippy::arithmetic_side_effects)]
pub const unsafe fn nstd_core_alloc_layout_array_unchecked(
size: NSTDUInt,
align: NSTDUInt,
len: NSTDUInt,
) -> NSTDAllocLayout {
NSTDAllocLayout {
size: size.wrapping_mul(len),
align,
}
}
#[inline]
#[nstdapi]
pub const fn nstd_core_alloc_layout_size(layout: NSTDAllocLayout) -> NSTDUInt {
layout.size
}
#[inline]
#[nstdapi]
pub const fn nstd_core_alloc_layout_align(layout: NSTDAllocLayout) -> NSTDUInt {
layout.align
}