1use crate::traits::IntoOptionNonNull;
2use core::fmt;
3use core::ptr::NonNull;
4
5#[repr(transparent)]
10pub struct Ptr<T> {
11 inner: Option<NonNull<T>>,
12}
13
14impl<T> Default for Ptr<T> {
15 #[inline]
16 fn default() -> Self {
17 Self { inner: None }
18 }
19}
20
21impl<T> Copy for Ptr<T> {}
22
23impl<T> Clone for Ptr<T> {
24 #[inline]
25 fn clone(&self) -> Self {
26 *self
27 }
28}
29
30impl<T> fmt::Debug for Ptr<T> {
31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 fmt::Debug::fmt(&self.inner, f)
33 }
34}
35
36impl<T> Ptr<T> {
37 #[inline]
39 pub const fn new(ptr: Option<NonNull<T>>) -> Self {
40 Self { inner: ptr }
41 }
42
43 #[inline]
46 pub fn as_mut_ptr(self) -> *mut T {
47 self.inner
48 .map(|p| p.as_ptr())
49 .unwrap_or(core::ptr::null_mut())
50 }
51
52 #[inline]
55 pub fn as_ptr(self) -> *const T {
56 self.inner
57 .map(|p| p.as_ptr() as *const T)
58 .unwrap_or(core::ptr::null())
59 }
60
61 #[inline]
63 pub const fn option(self) -> Option<NonNull<T>> {
64 self.inner
65 }
66
67 #[inline]
69 pub const fn as_option(self) -> Option<NonNull<T>> {
70 self.inner
71 }
72
73 #[inline]
75 pub fn is_null(self) -> bool {
76 self.inner.is_none()
77 }
78
79 #[inline]
81 pub fn is_some(self) -> bool {
82 self.inner.is_some()
83 }
84
85 #[inline]
87 pub fn is_none(self) -> bool {
88 self.inner.is_none()
89 }
90}
91
92impl<T> PartialEq for Ptr<T> {
95 #[inline]
96 fn eq(&self, other: &Self) -> bool {
97 self.inner == other.inner
98 }
99}
100
101impl<T> Eq for Ptr<T> {}
102
103impl<T> core::hash::Hash for Ptr<T> {
104 #[inline]
105 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
106 self.inner.hash(state);
107 }
108}
109
110impl<T> PartialEq<Option<NonNull<T>>> for Ptr<T> {
111 #[inline]
112 fn eq(&self, other: &Option<NonNull<T>>) -> bool {
113 self.inner == *other
114 }
115}
116
117impl<T> PartialEq<NonNull<T>> for Ptr<T> {
118 #[inline]
119 fn eq(&self, other: &NonNull<T>) -> bool {
120 self.inner == Some(*other)
121 }
122}
123
124impl<T> PartialEq<*const T> for Ptr<T> {
125 #[inline]
126 fn eq(&self, other: &*const T) -> bool {
127 self.as_ptr() == *other
128 }
129}
130
131impl<T> PartialEq<*mut T> for Ptr<T> {
132 #[inline]
133 fn eq(&self, other: &*mut T) -> bool {
134 self.as_mut_ptr() == *other
135 }
136}
137
138impl<T> IntoOptionNonNull<T> for Ptr<T> {
140 #[inline]
141 fn into_option_non_null(self) -> Option<NonNull<T>> {
142 self.inner
143 }
144}
145
146#[derive(PartialEq, Eq, Hash)]
149pub struct TaggedPtr<T> {
150 pub ptr: Ptr<T>,
152 pub tag: crate::Tag,
154}
155
156impl<T> Copy for TaggedPtr<T> {}
157
158impl<T> Clone for TaggedPtr<T> {
159 #[inline]
160 fn clone(&self) -> Self {
161 *self
162 }
163}
164
165impl<T> Default for TaggedPtr<T> {
166 #[inline]
167 fn default() -> Self {
168 Self {
169 ptr: Ptr::default(),
170 tag: crate::Tag::default(),
171 }
172 }
173}
174
175impl<T> TaggedPtr<T> {
176 #[inline]
178 pub fn new<P>(ptr: P, tag: crate::Tag) -> Self
179 where
180 P: IntoOptionNonNull<T>,
181 {
182 Self {
183 ptr: Ptr::new(ptr.into_option_non_null()),
184 tag,
185 }
186 }
187
188 #[inline]
190 pub fn decompose(self) -> (Ptr<T>, crate::Tag) {
191 (self.ptr, self.tag)
192 }
193}
194
195impl<T> fmt::Debug for TaggedPtr<T> {
196 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197 f.debug_struct("TaggedPtr")
198 .field("ptr", &self.ptr)
199 .field("tag", &self.tag)
200 .finish()
201 }
202}
203
204impl<T> From<(Ptr<T>, crate::Tag)> for TaggedPtr<T> {
205 #[inline]
206 fn from(tuple: (Ptr<T>, crate::Tag)) -> Self {
207 Self {
208 ptr: tuple.0,
209 tag: tuple.1,
210 }
211 }
212}
213
214impl<T> From<(Option<NonNull<T>>, crate::Tag)> for TaggedPtr<T> {
215 #[inline]
216 fn from(tuple: (Option<NonNull<T>>, crate::Tag)) -> Self {
217 Self {
218 ptr: Ptr::new(tuple.0),
219 tag: tuple.1,
220 }
221 }
222}
223
224impl<T> From<TaggedPtr<T>> for (Ptr<T>, crate::Tag) {
225 #[inline]
226 fn from(tagged: TaggedPtr<T>) -> Self {
227 (tagged.ptr, tagged.tag)
228 }
229}
230
231impl<T> IntoOptionNonNull<T> for TaggedPtr<T> {
232 #[inline]
233 fn into_option_non_null(self) -> Option<NonNull<T>> {
234 self.ptr.into_option_non_null()
235 }
236}