use std::fmt; use std::hash::{Hash, Hasher}; use std::ops::{Deref, DerefMut}; use super::CopyTaggedPtr; use super::{Pointer, Tag}; use crate::stable_hasher::{HashStable, StableHasher}; /// A tagged pointer that supports pointers that implement [`Drop`]. /// /// This is essentially `{ pointer: P, tag: T }` packed in a single pointer. /// /// You should use [`CopyTaggedPtr`] instead of the this type in all cases /// where `P` implements [`Copy`]. /// /// If `COMPARE_PACKED` is true, then the pointers will be compared and hashed without /// unpacking. Otherwise we don't implement [`PartialEq`], [`Eq`] and [`Hash`]; /// if you want that, wrap the [`TaggedPtr`]. pub struct TaggedPtr
where P: Pointer, T: Tag, { raw: CopyTaggedPtr
, } impl
TaggedPtr
where P: Pointer, T: Tag, { /// Tags `pointer` with `tag`. #[inline] pub fn new(pointer: P, tag: T) -> Self { TaggedPtr { raw: CopyTaggedPtr::new(pointer, tag) } } /// Retrieves the tag. #[inline] pub fn tag(&self) -> T { self.raw.tag() } /// Sets the tag to a new value. #[inline] pub fn set_tag(&mut self, tag: T) { self.raw.set_tag(tag) } } impl
Clone for TaggedPtr
where P: Pointer + Clone, T: Tag, { fn clone(&self) -> Self { let ptr = self.raw.with_pointer_ref(P::clone); Self::new(ptr, self.tag()) } } impl
Deref for TaggedPtr
where P: Pointer, T: Tag, { type Target = P::Target; #[inline] fn deref(&self) -> &Self::Target { self.raw.deref() } } impl
DerefMut for TaggedPtr
where P: Pointer + DerefMut, T: Tag, { #[inline] fn deref_mut(&mut self) -> &mut Self::Target { self.raw.deref_mut() } } impl
Drop for TaggedPtr
where P: Pointer, T: Tag, { fn drop(&mut self) { // No need to drop the tag, as it's Copy unsafe { drop(P::from_ptr(self.raw.pointer_raw())); } } } impl
fmt::Debug for TaggedPtr
where P: Pointer + fmt::Debug, T: Tag + fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.raw.with_pointer_ref(|ptr| { f.debug_struct("TaggedPtr").field("pointer", ptr).field("tag", &self.tag()).finish() }) } } impl
PartialEq for TaggedPtr
where P: Pointer, T: Tag, { #[inline] fn eq(&self, other: &Self) -> bool { self.raw.eq(&other.raw) } } impl
Eq for TaggedPtr
where P: Pointer, T: Tag, { } impl
Hash for TaggedPtr
where
P: Pointer,
T: Tag,
{
#[inline]
fn hash HashStable
where
P: Pointer + HashStable