use crate::*;
use crate::meta::*;
use libc::*;
use core::mem::MaybeUninit;
use core::ptr::NonNull;
#[doc = include_str!("_refs.md")]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pub struct Malloc;
impl Meta for Malloc {
type Error = ();
const MAX_ALIGN : Alignment = if cfg!(target_env = "msvc") {
if core::mem::size_of::<usize>() >= 8 { ALIGN_16 } else { ALIGN_8 }
} else {
#[cfg(any(target_env = "msvc", not(c11), not(feature = "libc")))] #[allow(non_camel_case_types)] type max_align_t = f64;
Alignment::of::<max_align_t>()
};
const MAX_SIZE : usize = usize::MAX;
const ZST_SUPPORTED : bool = false;
}
unsafe impl Stateless for Malloc {}
#[doc = include_str!("_refs.md")]
unsafe impl thin::Alloc for Malloc {
#[track_caller] fn alloc_uninit(&self, size: usize) -> Result<NonNull<MaybeUninit<u8>>, Self::Error> {
let alloc = unsafe { malloc(size) };
NonNull::new(alloc.cast()).ok_or(())
}
#[track_caller] fn alloc_zeroed(&self, size: usize) -> Result<NonNull<u8>, Self::Error> {
let alloc = unsafe { calloc(1, size) };
NonNull::new(alloc.cast()).ok_or(())
}
}
#[doc = include_str!("_refs.md")]
#[allow(clippy::missing_safety_doc)]
unsafe impl thin::Free for Malloc {
#[track_caller] unsafe fn free_nullable(&self, ptr: *mut MaybeUninit<u8>) {
unsafe { free(ptr.cast()) }
}
}
#[doc = include_str!("_refs.md")]
#[allow(clippy::missing_safety_doc)]
unsafe impl thin::Realloc for Malloc {
const CAN_REALLOC_ZEROED : bool = cfg!(target_env = "msvc");
#[track_caller] unsafe fn realloc_uninit(&self, ptr: AllocNN, new_size: usize) -> Result<AllocNN, Self::Error> {
if new_size == 0 { let alloc = thin::Alloc::alloc_uninit(self, new_size)?;
unsafe { thin::Free::free(self, ptr) };
Ok(alloc)
} else {
let alloc = unsafe { realloc(ptr.as_ptr().cast(), new_size) };
NonNull::new(alloc.cast()).ok_or(())
}
}
#[track_caller] unsafe fn realloc_zeroed(&self, ptr: AllocNN, new_size: usize) -> Result<AllocNN, Self::Error> {
if Self::CAN_REALLOC_ZEROED && new_size == 0 { let alloc = thin::Alloc::alloc_zeroed(self, new_size)?;
unsafe { thin::Free::free(self, ptr) };
return Ok(alloc.cast());
}
#[cfg(target_env = "msvc")] {
extern "C" { fn _recalloc(memblock: *mut c_void, num: size_t, size: size_t) -> *mut c_void; }
let alloc = unsafe { _recalloc(ptr.as_ptr().cast(), 1, new_size) };
NonNull::new(alloc.cast()).ok_or(())
}
#[cfg(not(target_env = "msvc"))] {
let _ = (ptr, new_size);
Err(())
}
}
}
#[doc = include_str!("_refs.md")]
#[allow(clippy::missing_safety_doc)]
unsafe impl thin::SizeOfDebug for Malloc {
unsafe fn size_of_debug(&self, _ptr: NonNull<MaybeUninit<u8>>) -> Option<usize> {
#[cfg(not(target_env = "msvc"))] { None }
#[cfg( target_env = "msvc" )] {
extern "C" { fn _msize(memblock: *mut c_void) -> size_t; }
let size = unsafe { _msize(_ptr.as_ptr().cast()) };
if size == !0 { return None } Some(size)
}
}
}
#[no_implicit_prelude] mod cleanroom {
use super::{impls, Malloc};
impls! {
unsafe impl ialloc::fat::Alloc for Malloc => ialloc::thin::Alloc;
unsafe impl ialloc::fat::Realloc for Malloc => ialloc::thin::Realloc;
unsafe impl ialloc::fat::Free for Malloc => ialloc::thin::Free;
}
}
#[cfg(test)] const MALLOC_ZERO_INITS : bool = cfg!(any(
target_os = "linux", target_os = "macos", ));
#[test] fn thin_alignment() { thin::test::alignment(Malloc) }
#[test] fn thin_edge_case_sizes() { thin::test::edge_case_sizes(Malloc) }
#[test] fn thin_nullable() { thin::test::nullable(Malloc) }
#[cfg( target_env = "msvc" )] #[test] fn thin_size_msvc() { thin::test::size_exact_alloc_except_zsts(Malloc) }
#[cfg(not(target_env = "msvc"))] #[test] fn thin_size() { thin::test::size_exact_alloc(Malloc) }
#[test] fn thin_uninit() { if !MALLOC_ZERO_INITS { unsafe { thin::test::uninit_alloc_unsound(Malloc) } } }
#[test] fn thin_uninit_realloc() { thin::test::uninit_realloc(Malloc) }
#[test] fn thin_zeroed() { thin::test::zeroed_alloc(Malloc) }
#[test] fn thin_zeroed_realloc() { thin::test::zeroed_realloc(Malloc) }
#[test] fn thin_zst_support() { thin::test::zst_supported_conservative(Malloc) }
#[test] fn fat_alignment() { fat::test::alignment(Malloc) }
#[test] fn fat_edge_case_sizes() { fat::test::edge_case_sizes(Malloc) }
#[test] fn fat_uninit() { if !MALLOC_ZERO_INITS { unsafe { fat::test::uninit_alloc_unsound(Malloc) } } }
#[test] fn fat_uninit_realloc() { fat::test::uninit_realloc(Malloc) }
#[test] fn fat_zeroed() { fat::test::zeroed_alloc(Malloc) }
#[test] fn fat_zeroed_realloc() { fat::test::zeroed_realloc(Malloc) }
#[test] fn fat_zst_support() { fat::test::zst_supported_conservative(Malloc) }
#[cfg(test)] mod adapt_alloc_zst {
use crate::allocator::adapt::AllocZst;
use super::{thin, fat, Malloc, MALLOC_ZERO_INITS};
#[test] fn thin_alignment() { thin::test::alignment(AllocZst(Malloc)) }
#[test] fn thin_edge_case_sizes() { thin::test::edge_case_sizes(AllocZst(Malloc)) }
#[test] fn thin_nullable() { thin::test::nullable(AllocZst(Malloc)) }
#[cfg( target_env = "msvc" )] #[test] fn thin_size_msvc() { thin::test::size_exact_alloc_except_zsts(Malloc) }
#[cfg(not(target_env = "msvc"))] #[test] fn thin_size() { thin::test::size_exact_alloc(Malloc) }
#[test] fn thin_uninit() { if !MALLOC_ZERO_INITS { unsafe { thin::test::uninit_alloc_unsound(AllocZst(Malloc)) } } }
#[test] fn thin_uninit_realloc() { thin::test::uninit_realloc(AllocZst(Malloc)) }
#[test] fn thin_zeroed() { thin::test::zeroed_alloc(AllocZst(Malloc)) }
#[test] fn thin_zeroed_realloc() { thin::test::zeroed_realloc(AllocZst(Malloc)) }
#[test] fn thin_zst_support() { thin::test::zst_supported_conservative(AllocZst(Malloc)) }
#[test] fn fat_alignment() { fat::test::alignment(AllocZst(Malloc)) }
#[test] fn fat_edge_case_sizes() { fat::test::edge_case_sizes(AllocZst(Malloc)) }
#[test] fn fat_uninit() { if !MALLOC_ZERO_INITS { unsafe { fat::test::uninit_alloc_unsound(AllocZst(Malloc)) } } }
#[test] fn fat_uninit_realloc() { fat::test::uninit_realloc(AllocZst(Malloc)) }
#[test] fn fat_zeroed() { fat::test::zeroed_alloc(AllocZst(Malloc)) }
#[test] fn fat_zeroed_realloc() { fat::test::zeroed_realloc(AllocZst(Malloc)) }
#[test] fn fat_zst_support() { fat::test::zst_supported_conservative(AllocZst(Malloc)) }
}
#[cfg(test)] mod adapt_dangle_zst {
use crate::allocator::adapt::DangleZst;
use super::{thin, fat, Malloc, MALLOC_ZERO_INITS};
#[test] fn thin_alignment() { thin::test::alignment(DangleZst(Malloc)) }
#[test] fn thin_edge_case_sizes() { thin::test::edge_case_sizes(DangleZst(Malloc)) }
#[test] fn thin_nullable() { thin::test::nullable(DangleZst(Malloc)) }
#[test] fn thin_size() { thin::test::size_exact_alloc(DangleZst(Malloc)) }
#[test] fn thin_uninit() { if !MALLOC_ZERO_INITS { unsafe { thin::test::uninit_alloc_unsound(DangleZst(Malloc)) } } }
#[test] fn thin_uninit_realloc() { thin::test::uninit_realloc(DangleZst(Malloc)) }
#[test] fn thin_zeroed() { thin::test::zeroed_alloc(DangleZst(Malloc)) }
#[test] fn thin_zeroed_realloc() { thin::test::zeroed_realloc(DangleZst(Malloc)) }
#[test] fn thin_zst_support() { thin::test::zst_supported_conservative(DangleZst(Malloc)) }
#[test] fn fat_alignment() { fat::test::alignment(DangleZst(Malloc)) }
#[test] fn fat_edge_case_sizes() { fat::test::edge_case_sizes(DangleZst(Malloc)) }
#[test] fn fat_uninit() { if !MALLOC_ZERO_INITS { unsafe { fat::test::uninit_alloc_unsound(DangleZst(Malloc)) } } }
#[test] fn fat_uninit_realloc() { fat::test::uninit_realloc(DangleZst(Malloc)) }
#[test] fn fat_zeroed() { fat::test::zeroed_alloc(DangleZst(Malloc)) }
#[test] fn fat_zeroed_realloc() { fat::test::zeroed_realloc(DangleZst(Malloc)) }
#[test] fn fat_zst_support() { fat::test::zst_supported_conservative(DangleZst(Malloc)) }
}