1 use super::{Pointer, Tag}
;
2 use crate::stable_hasher
::{HashStable, StableHasher}
;
5 use super::CopyTaggedPtr
;
7 /// A TaggedPtr implementing `Drop`.
9 /// If `COMPARE_PACKED` is true, then the pointers will be compared and hashed without
10 /// unpacking. Otherwise we don't implement PartialEq/Eq/Hash; if you want that,
11 /// wrap the TaggedPtr.
12 pub struct TaggedPtr
<P
, T
, const COMPARE_PACKED
: bool
>
17 raw
: CopyTaggedPtr
<P
, T
, COMPARE_PACKED
>,
20 impl<P
, T
, const COMPARE_PACKED
: bool
> Clone
for TaggedPtr
<P
, T
, COMPARE_PACKED
>
25 fn clone(&self) -> Self {
26 unsafe { Self::new(P::with_ref(self.raw.pointer_raw(), |p| p.clone()), self.raw.tag()) }
30 // We pack the tag into the *upper* bits of the pointer to ease retrieval of the
31 // value; a right shift is a multiplication and those are embeddable in
32 // instruction encoding.
33 impl<P
, T
, const COMPARE_PACKED
: bool
> TaggedPtr
<P
, T
, COMPARE_PACKED
>
38 pub fn new(pointer
: P
, tag
: T
) -> Self {
39 TaggedPtr { raw: CopyTaggedPtr::new(pointer, tag) }
42 pub fn pointer_ref(&self) -> &P
::Target
{
43 self.raw
.pointer_ref()
45 pub fn pointer_mut(&mut self) -> &mut P
::Target
47 P
: std
::ops
::DerefMut
,
49 self.raw
.pointer_mut()
51 pub fn tag(&self) -> T
{
54 pub fn set_tag(&mut self, tag
: T
) {
55 self.raw
.set_tag(tag
);
59 impl<P
, T
, const COMPARE_PACKED
: bool
> std
::ops
::Deref
for TaggedPtr
<P
, T
, COMPARE_PACKED
>
64 type Target
= P
::Target
;
65 fn deref(&self) -> &Self::Target
{
66 self.raw
.pointer_ref()
70 impl<P
, T
, const COMPARE_PACKED
: bool
> std
::ops
::DerefMut
for TaggedPtr
<P
, T
, COMPARE_PACKED
>
72 P
: Pointer
+ std
::ops
::DerefMut
,
75 fn deref_mut(&mut self) -> &mut Self::Target
{
76 self.raw
.pointer_mut()
80 impl<P
, T
, const COMPARE_PACKED
: bool
> Drop
for TaggedPtr
<P
, T
, COMPARE_PACKED
>
86 // No need to drop the tag, as it's Copy
88 std
::mem
::drop(P
::from_usize(self.raw
.pointer_raw()));
93 impl<P
, T
, const COMPARE_PACKED
: bool
> fmt
::Debug
for TaggedPtr
<P
, T
, COMPARE_PACKED
>
96 P
::Target
: fmt
::Debug
,
99 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
100 f
.debug_struct("TaggedPtr")
101 .field("pointer", &self.pointer_ref())
102 .field("tag", &self.tag())
107 impl<P
, T
> PartialEq
for TaggedPtr
<P
, T
, true>
112 fn eq(&self, other
: &Self) -> bool
{
113 self.raw
.eq(&other
.raw
)
117 impl<P
, T
> Eq
for TaggedPtr
<P
, T
, true>
124 impl<P
, T
> std
::hash
::Hash
for TaggedPtr
<P
, T
, true>
129 fn hash
<H
: std
::hash
::Hasher
>(&self, state
: &mut H
) {
130 self.raw
.hash(state
);
134 impl<P
, T
, HCX
, const COMPARE_PACKED
: bool
> HashStable
<HCX
> for TaggedPtr
<P
, T
, COMPARE_PACKED
>
136 P
: Pointer
+ HashStable
<HCX
>,
137 T
: Tag
+ HashStable
<HCX
>,
139 fn hash_stable(&self, hcx
: &mut HCX
, hasher
: &mut StableHasher
) {
140 self.raw
.hash_stable(hcx
, hasher
);