use core::ops::{Deref, DerefMut};
use core::ptr::NonNull;
use core::slice;

/// Wrapper 包装内部节点的使用，这些节点都是从内部POOL分配的，释放时缓存起来
/// 提供和slice之间的相互转换，节点内部无需保存slice，消除宽指针节省内存空间

#[repr(transparent)]
pub(crate) struct Wrapper<T: ?Sized>(NonNull<T>);

impl<T: ?Sized> Clone for Wrapper<T> {
    #[inline]
    fn clone(&self) -> Self {
        *self
    }
}
impl<T: ?Sized> Copy for Wrapper<T> {}

impl<T: ?Sized> Wrapper<T> {
    #[inline]
    pub(crate) const fn new(ptr: NonNull<T>) -> Self {
        Self(ptr)
    }
    #[inline]
    pub(crate) const fn as_ptr(&self) -> *mut T {
        self.0.as_ptr()
    }
    #[inline]
    pub(crate) unsafe fn assume_other<'a, U>(&self) -> &'a U {
        unsafe { self.0.cast().as_ref() }
    }
    #[inline]
    pub(crate) unsafe fn assume_slice<'a, U>(&self, len: usize) -> &'a [U] {
        unsafe { slice::from_raw_parts(self.0.cast().as_ptr(), len) }
    }
    #[inline]
    pub(crate) fn cast<U>(self) -> Wrapper<U> {
        Wrapper(self.0.cast::<U>())
    }
}

impl<T> Wrapper<T> {
    #[inline]
    pub(crate) unsafe fn as_slice_mut<'a>(&self, len: usize) -> &'a mut [T] {
        unsafe { slice::from_raw_parts_mut(self.0.as_ptr(), len) }
    }
}

impl<T: ?Sized> Deref for Wrapper<T> {
    type Target = T;
    #[inline]
    fn deref(&self) -> &Self::Target {
        unsafe { self.0.as_ref() }
    }
}

impl<T: ?Sized> DerefMut for Wrapper<T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { self.0.as_mut() }
    }
}
