use core::marker::PhantomData;
use core::mem;
use core::ptr::NonNull;
use allocator_api2::alloc::Allocator;
use super::chunk::Chunk;
pub(crate) struct ChunkRef<A: Allocator + Clone> {
chunk: NonNull<Chunk<A>>,
_phantom: PhantomData<*const Chunk<A>>,
}
impl<A: Allocator + Clone> ChunkRef<A> {
#[inline]
pub(crate) unsafe fn adopt(chunk: NonNull<Chunk<A>>) -> Self {
Self {
chunk,
_phantom: PhantomData,
}
}
#[inline]
pub(crate) unsafe fn from_value_ptr<T: ?Sized>(value: NonNull<T>) -> Self {
unsafe {
let header = Chunk::<A>::header_from_value_ptr(value.cast::<u8>());
let chunk_fat = Chunk::<A>::header_to_fat(header.as_ptr());
Self {
chunk: NonNull::new_unchecked(chunk_fat),
_phantom: PhantomData,
}
}
}
#[inline]
pub(crate) fn forget(self) -> NonNull<Chunk<A>> {
let chunk = self.chunk;
mem::forget(self);
chunk
}
}
impl<A: Allocator + Clone> Drop for ChunkRef<A> {
#[inline]
fn drop(&mut self) {
unsafe {
Chunk::<A>::release_one_ref(self.chunk);
}
}
}