use crate::*;
use crate::meta::*;
use super::Error;
use winapi::um::winbase::{LocalAlloc, LocalReAlloc, LocalFree, LocalSize};
use winapi::um::minwinbase::LMEM_ZEROINIT;
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 Local;
impl Meta for Local {
type Error = Error;
const MIN_ALIGN : Alignment = super::MEMORY_ALLOCATION_ALIGNMENT; const MAX_ALIGN : Alignment = super::MEMORY_ALLOCATION_ALIGNMENT; const MAX_SIZE : usize = usize::MAX;
const ZST_SUPPORTED : bool = false;
}
impl ZstSupported for Local {}
unsafe impl Stateless for Local {}
#[doc = include_str!("_refs.md")]
unsafe impl thin::Alloc for Local {
fn alloc_uninit(&self, size: usize) -> Result<AllocNN, Self::Error> {
if size == 0 { Err(error::BannedZeroSizedAllocationsError)? } let alloc = unsafe { LocalAlloc(0, size) };
NonNull::new(alloc.cast()).ok_or_else(Error::get_last)
}
fn alloc_zeroed(&self, size: usize) -> Result<AllocNN0, Self::Error> {
if size == 0 { Err(error::BannedZeroSizedAllocationsError)? } let alloc = unsafe { LocalAlloc(LMEM_ZEROINIT, size) };
NonNull::new(alloc.cast()).ok_or_else(Error::get_last)
}
}
#[doc = include_str!("_refs.md")]
#[allow(clippy::missing_safety_doc)]
unsafe impl thin::Realloc for Local {
const CAN_REALLOC_ZEROED : bool = true;
unsafe fn realloc_uninit(&self, ptr: AllocNN, new_size: usize) -> Result<AllocNN, Self::Error> {
if new_size == 0 { Err(error::BannedZeroSizedAllocationsError)? } let alloc = unsafe { LocalReAlloc(ptr.as_ptr().cast(), new_size, 0) };
NonNull::new(alloc.cast()).ok_or_else(Error::get_last)
}
unsafe fn realloc_zeroed(&self, ptr: AllocNN, new_size: usize) -> Result<AllocNN, Self::Error> {
if new_size == 0 { Err(error::BannedZeroSizedAllocationsError)? } let alloc = unsafe { LocalReAlloc(ptr.as_ptr().cast(), new_size, LMEM_ZEROINIT) };
NonNull::new(alloc.cast()).ok_or_else(Error::get_last)
}
}
#[doc = include_str!("_refs.md")]
#[allow(clippy::missing_safety_doc)]
unsafe impl thin::Free for Local {
unsafe fn free_nullable(&self, ptr: *mut MaybeUninit<u8>) {
if unsafe { LocalFree(ptr.cast()) }.is_null() { return }
if cfg!(debug_assertions) { bug::ub::free_failed(ptr) }
}
}
unsafe impl thin::SizeOf for Local {}
#[doc = include_str!("_refs.md")]
#[allow(clippy::missing_safety_doc)]
unsafe impl thin::SizeOfDebug for Local {
unsafe fn size_of_debug(&self, ptr: AllocNN) -> Option<usize> {
super::clear_last_error();
let size = unsafe { LocalSize(ptr.as_ptr().cast()) };
if size == 0 {
let err = super::get_last_error();
if err != 0 { return None }
}
Some(size)
}
}
#[no_implicit_prelude] mod cleanroom {
use super::{impls, Local};
impls! {
unsafe impl ialloc::fat::Alloc for Local => ialloc::thin::Alloc;
unsafe impl ialloc::fat::Realloc for Local => ialloc::thin::Realloc;
unsafe impl ialloc::fat::Free for Local => ialloc::thin::Free;
}
}
#[test] fn thin_alignment() { thin::test::alignment(Local) }
#[test] fn thin_edge_case_sizes() { thin::test::edge_case_sizes(Local) }
#[test] fn thin_nullable() { thin::test::nullable(Local) }
#[test] fn thin_size() { thin::test::size_exact_alloc(Local) }
#[test] fn thin_uninit() { unsafe { thin::test::uninit_alloc_unsound(Local) } }
#[test] fn thin_uninit_realloc() { thin::test::uninit_realloc(Local) }
#[test] fn thin_zeroed() { thin::test::zeroed_alloc(Local) }
#[test] fn thin_zeroed_realloc() { thin::test::zeroed_realloc(Local) }
#[test] fn thin_zst_support() { thin::test::zst_supported_accurate(Local) }
#[test] fn fat_alignment() { fat::test::alignment(Local) }
#[test] fn fat_edge_case_sizes() { fat::test::edge_case_sizes(Local) }
#[test] fn fat_uninit() { unsafe { fat::test::uninit_alloc_unsound(Local) } }
#[test] fn fat_uninit_realloc() { fat::test::uninit_realloc(Local) }
#[test] fn fat_zeroed() { fat::test::zeroed_alloc(Local) }
#[test] fn fat_zeroed_realloc() { fat::test::zeroed_realloc(Local) }
#[test] fn fat_zst_support() { fat::test::zst_supported_accurate(Local) }