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