commonlibsse_ng\re\g/
GPtr.rs1pub trait RefCounted {
3 fn add_ref(&mut self);
4 fn release(&mut self);
5}
6
7#[repr(transparent)]
12pub struct GPtr<T: RefCounted> {
13 ptr: *mut T,
14}
15
16impl<T: RefCounted> GPtr<T> {
17 #[inline]
18 pub const fn new(ptr: *mut T) -> Self {
19 Self { ptr }
20 }
21
22 #[inline]
23 pub const fn null() -> Self {
24 Self { ptr: core::ptr::null_mut() }
25 }
26
27 #[inline]
28 pub fn from_raw(ptr: *mut T) -> Self {
29 let mut g_ptr = Self { ptr };
30 g_ptr.try_attach();
31 g_ptr
32 }
33
34 #[inline]
35 pub fn reset(&mut self) {
36 self.try_detach();
37 }
38
39 #[inline]
40 pub fn reset_with(&mut self, ptr: *mut T) {
41 if self.ptr != ptr {
42 self.try_detach();
43 self.ptr = ptr;
44 self.try_attach();
45 }
46 }
47
48 #[inline]
49 pub const fn get(&self) -> *mut T {
50 self.ptr
51 }
52
53 #[inline]
54 pub const fn as_ref(&self) -> Option<&T> {
55 unsafe { self.ptr.as_ref() }
56 }
57
58 #[inline]
59 pub const fn as_mut(&mut self) -> Option<&mut T> {
60 unsafe { self.ptr.as_mut() }
61 }
62
63 #[inline]
64 pub fn cast<U>(self) -> GPtr<U>
65 where
66 U: RefCounted,
67 {
68 GPtr::<U>::new(self.ptr.cast())
69 }
70
71 fn try_attach(&mut self) {
72 if let Some(ptr) = self.as_mut() {
73 ptr.add_ref();
74 }
75 }
76
77 fn try_detach(&mut self) {
78 if let Some(ptr) = self.as_mut() {
79 ptr.release();
80 }
81 self.ptr = core::ptr::null_mut();
82 }
83}
84
85impl<T: RefCounted> Clone for GPtr<T> {
86 #[inline]
87 fn clone(&self) -> Self {
88 let mut cloned = Self { ptr: self.ptr };
89 cloned.try_attach();
90 cloned
91 }
92}
93
94impl<T: RefCounted> Drop for GPtr<T> {
95 #[inline]
96 fn drop(&mut self) {
97 self.try_detach();
98 }
99}
100
101impl<T: RefCounted> core::ops::Deref for GPtr<T> {
102 type Target = T;
103
104 #[inline]
105 fn deref(&self) -> &Self::Target {
106 self.as_ref().expect("GPtr is null")
107 }
108}
109
110impl<T: RefCounted> core::ops::DerefMut for GPtr<T> {
111 #[inline]
112 fn deref_mut(&mut self) -> &mut Self::Target {
113 self.as_mut().expect("GPtr is null")
114 }
115}
116
117impl<T: RefCounted> From<*mut T> for GPtr<T> {
118 #[inline]
119 fn from(ptr: *mut T) -> Self {
120 Self::from_raw(ptr)
121 }
122}
123
124impl<T: RefCounted> PartialEq for GPtr<T> {
125 #[inline]
126 fn eq(&self, other: &Self) -> bool {
127 self.ptr == other.ptr
128 }
129}
130
131impl<T: RefCounted> Eq for GPtr<T> {}
132
133impl<T: RefCounted> Default for GPtr<T> {
134 #[inline]
135 fn default() -> Self {
136 Self::null()
137 }
138}
139
140impl<T: RefCounted + core::fmt::Debug> core::fmt::Debug for GPtr<T> {
147 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
148 match self.as_ref() {
149 Some(value) => {
150 f.debug_struct("GPtr").field("ptr", &self.ptr).field("value", value).finish()
151 }
152 None => f.debug_struct("GPtr").field("ptr", &self.ptr).finish(),
153 }
154 }
155}
156
157#[inline]
159pub fn make_g_ptr<T: RefCounted>(value: T) -> GPtr<T> {
160 let boxed = Box::new(value);
162 let raw = Box::into_raw(boxed);
163 let ptr = GPtr::from_raw(raw);
164 unsafe {
166 (*raw).release();
167 }
168 ptr
169}