1use crate::tag::{read_tag, set_tag, strip, NullTag, Tag, TagPosition};
2use core::fmt::{self, Debug};
3use core::marker::PhantomData;
4use core::ptr;
5
6#[repr(transparent)]
12pub struct Shared<'shield, V, T1 = NullTag, T2 = NullTag>
13where
14 V: 'shield,
15 T1: Tag,
16 T2: Tag,
17{
18 pub(crate) data: usize,
19 _m0: PhantomData<&'shield ()>,
20 _m1: PhantomData<V>,
21 _m2: PhantomData<T1>,
22 _m3: PhantomData<T2>,
23}
24
25impl<'shield, V, T1, T2> Shared<'shield, V, T1, T2>
26where
27 V: 'shield,
28 T1: Tag,
29 T2: Tag,
30{
31 pub fn null() -> Self {
32 unsafe { Self::from_raw(ptr::null::<()>() as usize) }
33 }
34
35 pub unsafe fn from_ptr(ptr: *mut V) -> Self {
40 Self::from_raw(ptr as usize)
41 }
42
43 pub unsafe fn from_raw(data: usize) -> Self {
51 Self {
52 data,
53 _m0: PhantomData,
54 _m1: PhantomData,
55 _m2: PhantomData,
56 _m3: PhantomData,
57 }
58 }
59
60 pub fn into_raw(self) -> usize {
62 self.data
63 }
64
65 pub fn as_ptr(self) -> *mut V {
67 self.data as *mut V
68 }
69
70 pub fn strip(self) -> Self {
72 let data = strip::<T1, T2>(self.data);
73 unsafe { Self::from_raw(data) }
74 }
75
76 pub unsafe fn as_ref(self) -> Option<&'shield V> {
83 self.as_ptr().as_ref()
84 }
85
86 pub unsafe fn as_mut_ref(self) -> Option<&'shield mut V> {
93 let ptr = self.as_ptr();
94
95 if !ptr.is_null() {
96 Some(&mut *ptr)
97 } else {
98 None
99 }
100 }
101
102 pub unsafe fn as_ref_unchecked(self) -> &'shield V {
108 &*self.as_ptr()
109 }
110
111 pub unsafe fn as_mut_ref_unchecked(self) -> &'shield mut V {
117 &mut *self.as_ptr()
118 }
119
120 pub fn is_null(self) -> bool {
122 self.as_ptr().is_null()
123 }
124
125 pub fn tag_lo(self) -> T1 {
127 let bits = read_tag::<T1>(self.data, TagPosition::Lo);
128 Tag::deserialize(bits)
129 }
130
131 pub fn tag_hi(self) -> T2 {
133 let bits = read_tag::<T2>(self.data, TagPosition::Hi);
134 Tag::deserialize(bits)
135 }
136
137 pub fn with_tag_lo(self, tag: T1) -> Self {
139 let bits = tag.serialize();
140 let data = set_tag::<T1>(self.data, bits, TagPosition::Lo);
141 unsafe { Self::from_raw(data) }
142 }
143
144 pub fn with_tag_hi(self, tag: T2) -> Self {
146 let bits = tag.serialize();
147 let data = set_tag::<T2>(self.data, bits, TagPosition::Hi);
148 unsafe { Self::from_raw(data) }
149 }
150}
151
152impl<'shield, V, T1, T2> Clone for Shared<'shield, V, T1, T2>
153where
154 V: 'shield,
155 T1: Tag,
156 T2: Tag,
157{
158 fn clone(&self) -> Self {
159 unsafe { Self::from_raw(self.data) }
160 }
161}
162
163impl<'shield, V, T1, T2> Copy for Shared<'shield, V, T1, T2>
164where
165 V: 'shield,
166 T1: Tag,
167 T2: Tag,
168{
169}
170
171impl<'shield, V, T1, T2> PartialEq for Shared<'shield, V, T1, T2>
172where
173 V: 'shield,
174 T1: Tag,
175 T2: Tag,
176{
177 fn eq(&self, other: &Self) -> bool {
178 self.into_raw() == other.into_raw()
179 }
180}
181
182impl<'shield, V, T1, T2> Eq for Shared<'shield, V, T1, T2>
183where
184 V: 'shield,
185 T1: Tag,
186 T2: Tag,
187{
188}
189
190impl<'shield, V, T1, T2> Debug for Shared<'shield, V, T1, T2>
191where
192 V: 'shield,
193 T1: Tag,
194 T2: Tag,
195{
196 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
197 write!(formatter, "{:?}", self.data)
198 }
199}
200
201unsafe impl<'shield, V, T1, T2> Send for Shared<'shield, V, T1, T2>
202where
203 V: 'shield,
204 T1: Tag,
205 T2: Tag,
206{
207}
208
209unsafe impl<'shield, V, T1, T2> Sync for Shared<'shield, V, T1, T2>
210where
211 V: 'shield,
212 T1: Tag,
213 T2: Tag,
214{
215}
216
217impl<'shield, V, T1, T2> Unpin for Shared<'shield, V, T1, T2>
218where
219 V: 'shield,
220 T1: Tag,
221 T2: Tag,
222{
223}