1#![forbid(unsafe_op_in_unsafe_fn)]
2
3use std::fmt;
4use std::hash::{Hash, Hasher};
5use std::marker::PhantomData;
6use std::ops::{Deref, DerefMut};
7
8#[derive(Copy, Clone)]
9pub struct GcPtr<T> {
10 ptr: *const T,
11 _phantom: PhantomData<T>,
12}
13
14impl<T> GcPtr<T> {
15 pub unsafe fn from_raw(ptr: *const T) -> Self {
23 Self {
24 ptr,
25 _phantom: PhantomData,
26 }
27 }
28 pub fn null() -> Self {
29 Self {
30 ptr: std::ptr::null(),
31 _phantom: PhantomData,
32 }
33 }
34 pub fn is_null(&self) -> bool {
35 self.ptr.is_null()
36 }
37 pub unsafe fn as_raw(&self) -> *const T {
44 self.ptr
45 }
46 pub unsafe fn as_raw_mut(&self) -> *mut T {
53 self.ptr as *mut T
54 }
55}
56
57impl<T> Deref for GcPtr<T> {
58 type Target = T;
59 fn deref(&self) -> &Self::Target {
60 unsafe { &*self.ptr }
61 }
62}
63impl<T> DerefMut for GcPtr<T> {
64 fn deref_mut(&mut self) -> &mut Self::Target {
65 unsafe { &mut *(self.ptr as *mut T) }
66 }
67}
68
69impl<T: PartialEq> PartialEq for GcPtr<T> {
70 fn eq(&self, other: &Self) -> bool {
71 if self.is_null() && other.is_null() {
72 true
73 } else if self.is_null() || other.is_null() {
74 false
75 } else {
76 **self == **other
77 }
78 }
79}
80impl<T: Eq> Eq for GcPtr<T> {}
81impl<T: Hash> Hash for GcPtr<T> {
82 fn hash<H: Hasher>(&self, state: &mut H) {
83 if !self.is_null() {
84 (**self).hash(state)
85 }
86 }
87}
88impl<T: fmt::Debug> fmt::Debug for GcPtr<T> {
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 if self.is_null() {
91 write!(f, "GcPtr(null)")
92 } else {
93 write!(f, "GcPtr({:?})", **self)
94 }
95 }
96}
97impl<T: fmt::Display> fmt::Display for GcPtr<T> {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 if self.is_null() {
100 write!(f, "null")
101 } else {
102 write!(f, "{}", **self)
103 }
104 }
105}
106
107unsafe impl<T: Send> Send for GcPtr<T> {}
108unsafe impl<T: Sync> Sync for GcPtr<T> {}