use crate::locks::LockTrait;
use crate::mem_lay::get_layout;
use crate::slab::Slab;
use crate::utils::NonNullEx;
use core::alloc::Layout;
use core::marker::PhantomData;
use core::ops::{Deref, DerefMut};
use core::ptr::{NonNull, drop_in_place};
pub struct SlabBox<T, LOCK, const SLAB_SIZE: usize>
where
LOCK: LockTrait,
{
ptr: NonNull<T>,
_marker: PhantomData<LOCK>,
}
unsafe impl<T, LOCK, const SLAB_SIZE: usize> Send for SlabBox<T, LOCK, SLAB_SIZE>
where
T: Send,
LOCK: LockTrait + Sync,
{
}
unsafe impl<T, LOCK, const SLAB_SIZE: usize> Sync for SlabBox<T, LOCK, SLAB_SIZE>
where
T: Sync,
LOCK: LockTrait + Sync,
{
}
impl<T, LOCK, const SLAB_SIZE: usize> SlabBox<T, LOCK, SLAB_SIZE>
where
LOCK: LockTrait,
{
const SLAB_LAYOUT: Layout = get_layout(SLAB_SIZE);
pub fn new(ptr: NonNull<T>) -> Self {
Self {
ptr,
_marker: PhantomData,
}
}
fn free_ptr(&mut self) {
unsafe {
drop_in_place(self.ptr.as_ptr());
Slab::<T, LOCK>::free_slot(self.ptr, Self::SLAB_LAYOUT).expect("internal error");
}
}
pub fn as_ptr(&self) -> *mut T {
self.ptr.as_ptr()
}
}
impl<T, LOCK, const SLAB_SIZE: usize> Drop for SlabBox<T, LOCK, SLAB_SIZE>
where
LOCK: LockTrait,
{
fn drop(&mut self) {
self.free_ptr();
}
}
impl<T, LOCK, const SLAB_SIZE: usize> Deref for SlabBox<T, LOCK, SLAB_SIZE>
where
LOCK: LockTrait,
{
type Target = T;
fn deref(&self) -> &Self::Target {
self.ptr.unsafe_ref()
}
}
impl<T, LOCK, const SLAB_SIZE: usize> DerefMut for SlabBox<T, LOCK, SLAB_SIZE>
where
LOCK: LockTrait,
{
fn deref_mut(&mut self) -> &mut Self::Target {
self.ptr.unsafe_mut_ref()
}
}