use crate::*;
use core::alloc::Layout;
use core::mem::MaybeUninit;
use core::ptr::NonNull;
const _HEAP_MAXREQ : usize = usize::MAX & !0x1F;
#[doc = include_str!("_refs.md")]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pub struct AlignedMalloc;
impl meta::Meta for AlignedMalloc {
type Error = ();
const MAX_ALIGN : Alignment = Alignment::MAX;
const MAX_SIZE : usize = usize::MAX;
const ZST_SUPPORTED : bool = false;
}
unsafe impl fat::Alloc for AlignedMalloc {
#[track_caller] fn alloc_uninit(&self, layout: Layout) -> Result<NonNull<MaybeUninit<u8>>, Self::Error> {
#[cfg( target_env = "msvc") ] let alloc = unsafe { ffi::_aligned_malloc(layout.size(), layout.align()) };
#[cfg(not(target_env = "msvc"))] let alloc = unsafe { ffi::aligned_alloc(layout.align(), layout.size()) };
NonNull::new(alloc.cast()).ok_or(())
}
#[cfg(target_env = "msvc")]
#[track_caller] fn alloc_zeroed(&self, layout: Layout) -> Result<NonNull<u8>, Self::Error> {
let alloc = unsafe { ffi::_aligned_recalloc(core::ptr::null_mut(), 1, layout.size(), layout.align()) };
NonNull::new(alloc.cast()).ok_or(())
}
}
unsafe impl fat::Free for AlignedMalloc {
#[track_caller] unsafe fn free(&self, ptr: NonNull<MaybeUninit<u8>>, _layout: Layout) {
#[cfg(target_env = "msvc")] unsafe { ffi::_aligned_free(ptr.as_ptr().cast()) }
#[cfg(not(target_env = "msvc"))] unsafe {
#[cfg(c23)] ffi::free_aligned_sized(ptr.as_ptr().cast(), _layout.align(), _layout.size());
#[allow(dead_code)] ffi::free(ptr.as_ptr().cast());
}
}
}
unsafe impl fat::Realloc for AlignedMalloc {
#[cfg(target_env = "msvc")]
#[track_caller] unsafe fn realloc_uninit(&self, ptr: AllocNN, _old_layout: Layout, new_layout: Layout) -> Result<AllocNN, Self::Error> {
let alloc = unsafe { ffi::_aligned_realloc(ptr.as_ptr().cast(), new_layout.size(), new_layout.align()) };
NonNull::new(alloc.cast()).ok_or(())
}
#[cfg(target_env = "msvc")]
unsafe fn realloc_zeroed(&self, ptr: AllocNN, _old_layout: Layout, new_layout: Layout) -> Result<AllocNN, Self::Error> {
let alloc = unsafe { ffi::_aligned_recalloc(ptr.as_ptr().cast(), 1, new_layout.size(), new_layout.align()) };
NonNull::new(alloc.cast()).ok_or(())
}
}
unsafe impl thin::Free for AlignedMalloc {
#[track_caller] unsafe fn free_nullable(&self, ptr: *mut MaybeUninit<u8>) {
#[cfg( target_env = "msvc") ] unsafe { ffi::_aligned_free(ptr.cast()) }
#[cfg(not(target_env = "msvc"))] unsafe { ffi::free(ptr.cast()) }
}
}
mod ffi {
pub use libc::*;
#[allow(unused_imports)] use core::ptr::NonNull;
#[cfg(not(target_env = "msvc"))] extern "C" {
#[cfg(any(c11, cpp17))] pub fn aligned_alloc(alignment: size_t, size: size_t) -> *mut c_void;
#[cfg(any(c23 ))] pub fn free_sized(ptr: *mut c_void, size: size_t) -> *mut c_void;
#[cfg(any(c23 ))] pub fn free_aligned_sized(ptr: *mut c_void, alignment: size_t, size: size_t) -> *mut c_void;
}
#[cfg(target_env = "msvc")] extern "cdecl" {
pub fn _aligned_free(block: *mut c_void);
pub fn _aligned_malloc(size: size_t, alignment: size_t) -> *mut c_void;
pub fn _aligned_offset_malloc(size: size_t, alignment: size_t, offset: size_t) -> *mut c_void;
pub fn _aligned_msize(block: NonNull<c_void>, alignment: size_t, offset: size_t) -> size_t;
pub fn _aligned_offset_realloc(block: *mut c_void, size: size_t, alignment: size_t, offset: size_t) -> *mut c_void;
pub fn _aligned_offset_recalloc(block: *mut c_void, count: size_t, size: size_t, alignment: size_t, offset: size_t) -> *mut c_void;
pub fn _aligned_realloc(block: *mut c_void, size: size_t, alignment: size_t) -> *mut c_void;
pub fn _aligned_recalloc(block: *mut c_void, count: size_t, size: size_t, alignment: size_t) -> *mut c_void;
}
#[cfg(never)] #[cfg(target_env = "msvc")] extern "cdecl" {
pub fn _aligned_free_dbg(block: *mut c_void);
pub fn _aligned_malloc_dbg(size: size_t, alignment: size_t, file_name: abistr::CStrPtr<u8>, line_number: c_int) -> *mut c_void;
pub fn _aligned_msize_dbg(block: NonNull<c_void>, alignment: size_t, offset: size_t) -> size_t;
pub fn _aligned_offset_malloc_dbg(size: size_t, alignment: size_t, offset: size_t, file_name: abistr::CStrPtr<u8>, line_number: c_int) -> *mut c_void;
pub fn _aligned_offset_realloc_dbg(block: *mut c_void, size: size_t, alignment: size_t, offset: size_t, file_name: abistr::CStrPtr<u8>, line_number: c_int) -> *mut c_void;
pub fn _aligned_offset_recalloc_dbg(block: *mut c_void, count: size_t, size: size_t, alignment: size_t, offset: size_t, file_name: abistr::CStrPtr<u8>, line_number: c_int) -> *mut c_void;
pub fn _aligned_realloc_dbg(block: *mut c_void, size: size_t, alignment: size_t, file_name: abistr::CStrPtr<u8>, line_number: c_int) -> *mut c_void;
pub fn _aligned_recalloc_dbg(block: *mut c_void, count: size_t, size: size_t, alignment: size_t, file_name: abistr::CStrPtr<u8>, line_number: c_int) -> *mut c_void;
}
}