use super::NumBits;
use core::cmp::Ordering;
use core::hash::{Hash, Hasher};
use core::marker::PhantomData;
use core::ptr::NonNull;
pub(super) struct PtrImpl<T, B = PhantomData<T>> {
ptr: NonNull<T>,
tag: usize,
phantom: PhantomData<fn() -> B>,
}
impl<T, B: NumBits> PtrImpl<T, B> {
pub fn new(ptr: NonNull<T>, tag: usize) -> Self {
Self::assert();
Self {
ptr,
tag: tag & Self::MASK,
phantom: PhantomData,
}
}
fn new_unchecked_impl(ptr: NonNull<T>, tag: usize) -> Self {
Self::assert();
debug_assert!(tag < Self::ALIGNMENT);
Self::new(ptr, tag)
}
pub unsafe fn new_unchecked(ptr: NonNull<T>, tag: usize) -> Self {
Self::new_unchecked_impl(ptr, tag)
}
pub unsafe fn new_unchecked_dereferenceable(
ptr: NonNull<T>,
tag: usize,
) -> Self {
Self::new_unchecked_impl(ptr, tag)
}
pub fn get(self) -> (NonNull<T>, usize) {
self.get_priv()
}
}
impl<T, B> PtrImpl<T, B> {
fn get_priv(self) -> (NonNull<T>, usize) {
(self.ptr, self.tag)
}
}
impl<T, B> PartialEq for PtrImpl<T, B> {
fn eq(&self, other: &Self) -> bool {
self.get_priv() == other.get_priv()
}
}
impl<T, B> Ord for PtrImpl<T, B> {
fn cmp(&self, other: &Self) -> Ordering {
self.get_priv().cmp(&other.get_priv())
}
}
impl<T, B> Hash for PtrImpl<T, B> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.get_priv().hash(state);
}
}