1use std::{
2 fmt::{Debug, Formatter},
3 marker::Unsize,
4 ops::{CoerceUnsized, Deref, DerefMut},
5 ptr,
6 ptr::from_ref,
7};
8
9use crate::{AsAny, RawPointer, Weak, ref_counter::RefCounter};
10
11pub(crate) type Stamp = u64;
12pub(crate) type Addr = usize;
13
14pub struct Own<T: ?Sized> {
15 bx: Box<T>,
16 stamp: Stamp,
17 type_name: &'static str,
18}
19
20unsafe impl<T: ?Sized> Send for Own<T> {}
21unsafe impl<T: ?Sized> Sync for Own<T> {}
22
23pub(crate) fn stamp() -> Stamp {
24 use instant::SystemTime;
25
26 SystemTime::now()
27 .duration_since(SystemTime::UNIX_EPOCH)
28 .expect("Time went backwards")
29 .as_millis()
30 .try_into()
31 .unwrap()
32}
33
34impl<T: Sized + 'static> Own<T> {
35 pub fn new(val: T) -> Self {
36 let stamp = stamp();
37
38 let type_name = std::any::type_name::<T>();
39
40 #[cfg(feature = "stats")]
41 crate::stats::adjust_stat(type_name, 1);
42
43 let val = Box::new(val);
44 let address = from_ref::<T>(&val).cast::<u8>() as usize;
45
46 assert_ne!(address, 1, "Invalid address. In cou be a closure or empty type.");
47
48 RefCounter::add(address, stamp);
49
50 Self {
51 bx: val,
52 stamp,
53 type_name,
54 }
55 }
56}
57
58impl<T: ?Sized + AsAny> Own<T> {
59 pub fn downcast<U: 'static>(&self) -> Option<Weak<U>> {
60 self.weak().downcast()
61 }
62}
63
64impl<T: ?Sized> Own<T> {
65 #[cfg(feature = "checks")]
66 fn check() {
67 assert!(
68 hreads::is_main_thread(),
69 "Unsafe Own pointer deref: {}. Thread is not Main. Thread id: {}",
70 std::any::type_name::<T>(),
71 hreads::current_thread_id()
72 );
73 }
74}
75
76impl<T: ?Sized> Own<T> {
77 pub(crate) fn addr(&self) -> usize {
78 from_ref::<T>(self.bx.as_ref()).cast::<u8>() as usize
79 }
80}
81
82impl<T: ?Sized> Drop for Own<T> {
83 fn drop(&mut self) {
84 #[cfg(feature = "stats")]
85 crate::stats::adjust_stat(self.type_name, -1);
86 RefCounter::remove(self.addr());
87 }
88}
89
90impl<T: ?Sized> Deref for Own<T> {
91 type Target = T;
92 fn deref(&self) -> &T {
93 self.bx.deref()
94 }
95}
96
97impl<T: ?Sized> DerefMut for Own<T> {
98 fn deref_mut(&mut self) -> &mut Self::Target {
99 #[cfg(feature = "checks")]
100 Self::check();
101 self.bx.deref_mut()
102 }
103}
104
105impl<T: ?Sized> Own<T> {
106 pub fn weak(&self) -> Weak<T> {
107 Weak {
108 ptr: ptr::from_ref(self.bx.deref()).cast_mut(),
109 stamp: self.stamp,
110 type_name: self.type_name,
111 }
112 }
113
114 pub fn raw(&self) -> RawPointer {
115 RawPointer::new(self.addr(), self.stamp, self.type_name)
116 }
117}
118
119impl<T: Default + Sized + 'static> Default for Own<T> {
120 fn default() -> Self {
121 Self::new(T::default())
122 }
123}
124
125impl<T: ?Sized + Debug> Debug for Own<T> {
126 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
127 self.deref().fmt(f)
128 }
129}
130
131impl<T: ?Sized + PartialEq> PartialEq for Own<T> {
132 fn eq(&self, other: &Self) -> bool {
133 self.deref().eq(other.deref())
134 }
135}
136
137impl<T: ?Sized + PartialEq> PartialEq<T> for Own<T> {
138 fn eq(&self, other: &T) -> bool {
139 self.deref().eq(other)
140 }
141}
142
143impl<T, U> CoerceUnsized<Own<U>> for Own<T>
144where
145 T: Unsize<U> + ?Sized,
146 U: ?Sized,
147{
148}
149
150#[cfg(test)]
151mod tests {
152 use std::{
153 ops::{Deref, DerefMut},
154 sync::atomic::{AtomicU64, Ordering},
155 thread::spawn,
156 };
157
158 use hreads::set_current_thread_as_main;
159 use serial_test::serial;
160
161 use crate::Own;
162
163 #[test]
164 fn deref() {
165 let num = Own::new(5);
166 assert_eq!(num.deref(), &5);
167 assert_eq!(num.weak().deref(), &5);
168 }
169
170 #[test]
171 #[should_panic(expected = "Invalid address. In cou be a closure or empty type.")]
172 fn own_from_closure() {
173 let _ = Own::new(|| {});
174 }
175
176 #[test]
177 #[serial]
178 fn deref_mut() {
179 set_current_thread_as_main();
180 let mut num = Own::new(5);
181 *num = 10;
182 assert_eq!(num.deref(), &10);
183 assert_eq!(num.weak().deref_mut(), &10);
184 }
185
186 #[test]
187 #[serial]
188 #[should_panic]
189 fn deref_async() {
190 set_current_thread_as_main();
191 let mut num = Own::new(5);
192 spawn(move || {
193 assert_eq!(num.deref_mut(), &5);
194 })
195 .join()
196 .unwrap();
197 }
198
199 #[test]
200 #[should_panic(expected = "Defererencing already freed weak pointer: i32")]
201 fn deref_freed() {
202 let num = Own::new(5);
203 let weak = num.weak();
204 drop(num);
205 dbg!(weak);
206 }
207
208 static VAL: AtomicU64 = AtomicU64::new(0);
209
210 #[test]
211 fn check_drop() {
212 struct ToDrop {
213 _a: bool,
214 }
215
216 impl Drop for ToDrop {
217 fn drop(&mut self) {
218 VAL.store(20, Ordering::Relaxed);
219 }
220 }
221
222 assert_eq!(VAL.load(Ordering::Relaxed), 0);
223
224 let num = Own::new(ToDrop { _a: false });
225 let weak = num.weak();
226 assert!(!weak.is_null());
227 drop(num);
228 assert!(weak.is_null());
229
230 assert_eq!(VAL.load(Ordering::Relaxed), 20);
231 }
232
233 #[test]
234 fn misc() {
235 let five = Own::new(5);
236 let ten = Own::new(10);
237 let another_five = Own::new(5);
238 let five_int = 5;
239
240 assert_eq!(five, another_five);
241 assert_ne!(five, ten);
242 assert_eq!(five, 5);
243 assert_ne!(five, 10);
244 assert_eq!("5", &format!("{five:?}"));
245 assert_eq!(five, five_int);
246 }
247}