refs/
own.rs

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}