use core::marker::PhantomData;
use core::mem::ManuallyDrop;
use core::ptr::NonNull;
use allocator_api2::alloc::Allocator;
use super::in_chunk::{InLocalChunk, InSharedChunk};
use super::local_chunk::LocalChunk;
use super::shared_chunk::SharedChunk;
pub(crate) struct OwnedInLocalChunk<T: ?Sized, A: Allocator + Clone> {
ptr: ManuallyDrop<InLocalChunk<T, A>>,
_marker: PhantomData<A>,
}
impl<T: ?Sized, A: Allocator + Clone> OwnedInLocalChunk<T, A> {
#[inline]
pub(crate) unsafe fn from_raw_alloc(ptr: NonNull<T>) -> Self {
let in_chunk = unsafe { InLocalChunk::new(ptr) };
Self {
ptr: ManuallyDrop::new(in_chunk),
_marker: PhantomData,
}
}
#[inline]
#[must_use]
pub(crate) fn into_in_chunk(self) -> InLocalChunk<T, A> {
let mut me = ManuallyDrop::new(self);
unsafe { ManuallyDrop::take(&mut me.ptr) }
}
}
impl<T: ?Sized, A: Allocator + Clone> Drop for OwnedInLocalChunk<T, A> {
fn drop(&mut self) {
let chunk = self.ptr.chunk_ptr();
unsafe { LocalChunk::dec_ref(chunk) };
}
}
pub(crate) struct OwnedInSharedChunk<T: ?Sized, A: Allocator + Clone> {
ptr: ManuallyDrop<InSharedChunk<T, A>>,
_marker: PhantomData<A>,
}
impl<T: ?Sized, A: Allocator + Clone> OwnedInSharedChunk<T, A> {
#[inline]
pub(crate) unsafe fn from_raw_alloc(ptr: NonNull<T>) -> Self {
let in_chunk = unsafe { InSharedChunk::new(ptr) };
Self {
ptr: ManuallyDrop::new(in_chunk),
_marker: PhantomData,
}
}
#[inline]
#[must_use]
pub(crate) fn into_in_chunk(self) -> InSharedChunk<T, A> {
let mut me = ManuallyDrop::new(self);
unsafe { ManuallyDrop::take(&mut me.ptr) }
}
}
impl<T: ?Sized, A: Allocator + Clone> Drop for OwnedInSharedChunk<T, A> {
fn drop(&mut self) {
let chunk = self.ptr.chunk_ptr();
unsafe { SharedChunk::dec_ref(chunk) };
}
}