1use core::fmt;
2use core::ptr::NonNull;
3
4#[repr(transparent)]
9pub struct Ptr<T> {
10 inner: Option<NonNull<T>>,
11}
12
13impl<T> Default for Ptr<T> {
14 #[inline]
15 fn default() -> Self {
16 Self { inner: None }
17 }
18}
19
20impl<T> Copy for Ptr<T> {}
21
22impl<T> Clone for Ptr<T> {
23 #[inline]
24 fn clone(&self) -> Self {
25 *self
26 }
27}
28
29impl<T> fmt::Debug for Ptr<T> {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 fmt::Debug::fmt(&self.inner, f)
32 }
33}
34
35impl<T> Ptr<T> {
36 #[inline]
38 pub const fn new(ptr: Option<NonNull<T>>) -> Self {
39 Self { inner: ptr }
40 }
41 #[inline]
44 pub fn as_mut_ptr(self) -> *mut T {
45 self.inner
46 .map(|p| p.as_ptr())
47 .unwrap_or(core::ptr::null_mut())
48 }
49
50 #[inline]
53 pub fn as_ptr(self) -> *const T {
54 self.inner
55 .map(|p| p.as_ptr() as *const T)
56 .unwrap_or(core::ptr::null())
57 }
58
59 #[inline]
61 pub const fn option(self) -> Option<NonNull<T>> {
62 self.inner
63 }
64
65 #[inline]
67 pub const fn as_option(self) -> Option<NonNull<T>> {
68 self.inner
69 }
70
71 #[inline]
73 pub fn is_null(self) -> bool {
74 self.inner.is_none()
75 }
76
77 #[inline]
79 pub fn is_some(self) -> bool {
80 self.inner.is_some()
81 }
82
83 #[inline]
85 pub fn is_none(self) -> bool {
86 self.inner.is_none()
87 }
88
89 #[inline]
96 pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
97 self.inner.map(|p| unsafe { p.as_ref() })
98 }
99
100 #[inline]
107 pub unsafe fn as_mut<'a>(mut self) -> Option<&'a mut T> {
108 self.inner.as_mut().map(|p| unsafe { p.as_mut() })
109 }
110
111 #[inline]
113 pub fn expect(self, msg: &str) -> NonNull<T> {
114 self.inner.expect(msg)
115 }
116
117 #[inline]
119 pub fn unwrap(self) -> NonNull<T> {
120 self.inner
121 .expect("called `Ptr::unwrap()` on a null pointer")
122 }
123
124 #[inline]
126 pub fn unwrap_or(self, default: NonNull<T>) -> NonNull<T> {
127 self.inner.unwrap_or(default)
128 }
129
130 #[inline]
132 pub fn map<U, F>(self, f: F) -> Ptr<U>
133 where
134 F: FnOnce(NonNull<T>) -> NonNull<U>,
135 {
136 Ptr::new(self.inner.map(f))
137 }
138
139 #[inline]
141 pub fn map_or<U, F>(self, default: U, f: F) -> U
142 where
143 F: FnOnce(NonNull<T>) -> U,
144 {
145 self.inner.map_or(default, f)
146 }
147
148 #[inline]
150 pub fn map_or_else<U, D, F>(self, default: D, f: F) -> U
151 where
152 D: FnOnce() -> U,
153 F: FnOnce(NonNull<T>) -> U,
154 {
155 self.inner.map_or_else(default, f)
156 }
157}
158
159impl<T> fmt::Pointer for Ptr<T> {
160 #[inline]
161 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
162 fmt::Pointer::fmt(&self.as_ptr(), f)
163 }
164}
165
166impl<T> PartialOrd for Ptr<T> {
167 #[inline]
168 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
169 Some(self.cmp(other))
170 }
171}
172
173impl<T> Ord for Ptr<T> {
174 #[inline]
175 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
176 self.as_ptr().cmp(&other.as_ptr())
177 }
178}
179
180impl<T> From<Ptr<T>> for *const T {
181 #[inline]
182 fn from(ptr: Ptr<T>) -> Self {
183 ptr.as_ptr()
184 }
185}
186
187impl<T> From<Ptr<T>> for *mut T {
188 #[inline]
189 fn from(ptr: Ptr<T>) -> Self {
190 ptr.as_mut_ptr()
191 }
192}
193
194impl<T> From<Ptr<T>> for Option<*const T> {
195 #[inline]
196 fn from(ptr: Ptr<T>) -> Self {
197 ptr.inner.map(|p| p.as_ptr() as *const T)
198 }
199}
200
201impl<T> From<Ptr<T>> for Option<*mut T> {
202 #[inline]
203 fn from(ptr: Ptr<T>) -> Self {
204 ptr.inner.map(|p| p.as_ptr())
205 }
206}
207
208impl<T> PartialEq for Ptr<T> {
211 #[inline]
212 fn eq(&self, other: &Self) -> bool {
213 self.inner == other.inner
214 }
215}
216
217impl<T> Eq for Ptr<T> {}
218
219impl<T> core::hash::Hash for Ptr<T> {
220 #[inline]
221 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
222 self.inner.hash(state);
223 }
224}
225
226impl<T> PartialEq<Option<NonNull<T>>> for Ptr<T> {
227 #[inline]
228 fn eq(&self, other: &Option<NonNull<T>>) -> bool {
229 self.inner == *other
230 }
231}
232
233impl<T> PartialEq<NonNull<T>> for Ptr<T> {
234 #[inline]
235 fn eq(&self, other: &NonNull<T>) -> bool {
236 self.inner == Some(*other)
237 }
238}
239
240impl<T> PartialEq<*const T> for Ptr<T> {
241 #[inline]
242 fn eq(&self, other: &*const T) -> bool {
243 self.as_ptr() == *other
244 }
245}
246
247impl<T> PartialEq<*mut T> for Ptr<T> {
248 #[inline]
249 fn eq(&self, other: &*mut T) -> bool {
250 self.as_mut_ptr() == *other
251 }
252}
253
254impl<T> From<Option<NonNull<T>>> for Ptr<T> {
257 #[inline]
258 fn from(ptr: Option<NonNull<T>>) -> Self {
259 Self { inner: ptr }
260 }
261}
262
263impl<T> From<NonNull<T>> for Ptr<T> {
264 #[inline]
265 fn from(ptr: NonNull<T>) -> Self {
266 Self { inner: Some(ptr) }
267 }
268}
269
270impl<T> From<*const T> for Ptr<T> {
271 #[inline]
272 fn from(ptr: *const T) -> Self {
273 Self {
274 inner: NonNull::new(ptr as *mut T),
275 }
276 }
277}
278
279impl<T> From<*mut T> for Ptr<T> {
280 #[inline]
281 fn from(ptr: *mut T) -> Self {
282 Self {
283 inner: NonNull::new(ptr),
284 }
285 }
286}
287
288impl<T> From<TaggedPtr<T>> for Ptr<T> {
289 #[inline]
290 fn from(tagged: TaggedPtr<T>) -> Self {
291 tagged.ptr
292 }
293}
294
295impl<T> From<Ptr<T>> for Option<NonNull<T>> {
296 #[inline]
297 fn from(ptr: Ptr<T>) -> Self {
298 ptr.inner
299 }
300}
301
302impl<T> From<TaggedPtr<T>> for Option<NonNull<T>> {
303 #[inline]
304 fn from(tagged: TaggedPtr<T>) -> Self {
305 tagged.ptr.inner
306 }
307}
308
309pub struct TaggedPtr<T> {
312 pub ptr: Ptr<T>,
314 pub tag: crate::Tag,
316}
317
318impl<T> Copy for TaggedPtr<T> {}
319
320impl<T> Clone for TaggedPtr<T> {
321 #[inline]
322 fn clone(&self) -> Self {
323 *self
324 }
325}
326
327impl<T> PartialEq for TaggedPtr<T> {
328 #[inline]
329 fn eq(&self, other: &Self) -> bool {
330 self.ptr == other.ptr && self.tag == other.tag
331 }
332}
333
334impl<T> Eq for TaggedPtr<T> {}
335
336impl<T> core::hash::Hash for TaggedPtr<T> {
337 #[inline]
338 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
339 self.ptr.hash(state);
340 self.tag.hash(state);
341 }
342}
343
344impl<T> Default for TaggedPtr<T> {
345 #[inline]
346 fn default() -> Self {
347 Self {
348 ptr: Ptr::default(),
349 tag: crate::Tag::default(),
350 }
351 }
352}
353
354impl<T> TaggedPtr<T> {
355 #[inline]
357 pub fn new<P>(ptr: P, tag: crate::Tag) -> Self
358 where
359 P: Into<Ptr<T>>,
360 {
361 Self {
362 ptr: ptr.into(),
363 tag,
364 }
365 }
366
367 #[inline]
369 pub fn decompose(self) -> (Ptr<T>, crate::Tag) {
370 (self.ptr, self.tag)
371 }
372
373 #[inline]
376 pub fn as_ptr(self) -> *const T {
377 self.ptr.as_ptr()
378 }
379
380 #[inline]
383 pub fn as_mut_ptr(self) -> *mut T {
384 self.ptr.as_mut_ptr()
385 }
386
387 #[inline]
389 pub fn is_null(self) -> bool {
390 self.ptr.is_null()
391 }
392
393 #[inline]
395 pub fn is_some(self) -> bool {
396 self.ptr.is_some()
397 }
398
399 #[inline]
401 pub fn is_none(self) -> bool {
402 self.ptr.is_none()
403 }
404
405 #[inline]
412 pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
413 unsafe { self.ptr.as_ref() }
414 }
415
416 #[inline]
423 pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> {
424 unsafe { self.ptr.as_mut() }
425 }
426
427 #[inline]
429 pub fn with_ptr<U>(self, ptr: impl Into<Ptr<U>>) -> TaggedPtr<U> {
430 TaggedPtr {
431 ptr: ptr.into(),
432 tag: self.tag,
433 }
434 }
435
436 #[inline]
438 pub fn with_tag(self, tag: crate::Tag) -> Self {
439 Self { ptr: self.ptr, tag }
440 }
441
442 #[inline]
444 pub fn map_ptr<U, F>(self, f: F) -> TaggedPtr<U>
445 where
446 F: FnOnce(Ptr<T>) -> Ptr<U>,
447 {
448 TaggedPtr {
449 ptr: f(self.ptr),
450 tag: self.tag,
451 }
452 }
453}
454
455impl<T> fmt::Pointer for TaggedPtr<T> {
456 #[inline]
457 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
458 fmt::Pointer::fmt(&self.ptr, f)
459 }
460}
461
462impl<T> PartialOrd for TaggedPtr<T> {
463 #[inline]
464 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
465 Some(self.cmp(other))
466 }
467}
468
469impl<T> Ord for TaggedPtr<T> {
470 #[inline]
471 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
472 match self.ptr.cmp(&other.ptr) {
473 core::cmp::Ordering::Equal => self.tag.cmp(&other.tag),
474 ord => ord,
475 }
476 }
477}
478
479impl<T> From<TaggedPtr<T>> for *const T {
480 #[inline]
481 fn from(tagged: TaggedPtr<T>) -> Self {
482 tagged.as_ptr()
483 }
484}
485
486impl<T> From<TaggedPtr<T>> for *mut T {
487 #[inline]
488 fn from(tagged: TaggedPtr<T>) -> Self {
489 tagged.as_mut_ptr()
490 }
491}
492
493impl<T> fmt::Debug for TaggedPtr<T> {
494 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
495 f.debug_struct("TaggedPtr")
496 .field("ptr", &self.ptr)
497 .field("tag", &self.tag)
498 .finish()
499 }
500}
501
502impl<T> From<(Ptr<T>, crate::Tag)> for TaggedPtr<T> {
503 #[inline]
504 fn from(tuple: (Ptr<T>, crate::Tag)) -> Self {
505 Self {
506 ptr: tuple.0,
507 tag: tuple.1,
508 }
509 }
510}
511
512impl<T> From<(Option<NonNull<T>>, crate::Tag)> for TaggedPtr<T> {
513 #[inline]
514 fn from(tuple: (Option<NonNull<T>>, crate::Tag)) -> Self {
515 Self {
516 ptr: Ptr::new(tuple.0),
517 tag: tuple.1,
518 }
519 }
520}
521
522impl<T> From<(NonNull<T>, crate::Tag)> for TaggedPtr<T> {
523 #[inline]
524 fn from(tuple: (NonNull<T>, crate::Tag)) -> Self {
525 Self {
526 ptr: Ptr::from(tuple.0),
527 tag: tuple.1,
528 }
529 }
530}
531
532impl<T> From<(*const T, crate::Tag)> for TaggedPtr<T> {
533 #[inline]
534 fn from(tuple: (*const T, crate::Tag)) -> Self {
535 Self {
536 ptr: Ptr::from(tuple.0),
537 tag: tuple.1,
538 }
539 }
540}
541
542impl<T> From<(*mut T, crate::Tag)> for TaggedPtr<T> {
543 #[inline]
544 fn from(tuple: (*mut T, crate::Tag)) -> Self {
545 Self {
546 ptr: Ptr::from(tuple.0),
547 tag: tuple.1,
548 }
549 }
550}
551
552impl<T> From<TaggedPtr<T>> for (Ptr<T>, crate::Tag) {
553 #[inline]
554 fn from(tagged: TaggedPtr<T>) -> Self {
555 (tagged.ptr, tagged.tag)
556 }
557}