Skip to main content

grafix_toolbox/kit/policies/
memory.rs

1pub struct Ptr<T> {
2	p: *mut T, // TODO Is Box still noalias?
3}
4impl<T> Drop for Ptr<T> {
5	fn drop(&mut self) {
6		let _ = unsafe { Box::from_raw(self.p) };
7	}
8}
9impl<T> Ptr<T> {
10	pub fn weak(&self) -> mem::ManuallyDrop<Self> {
11		mem::ManuallyDrop::new(Ptr { p: self.p })
12	}
13	pub unsafe fn as_ref(&self) -> &'static T {
14		unsafe { &*self.p }
15	}
16	pub fn ptr(&self) -> *mut T {
17		self.p
18	}
19}
20impl<T> From<Box<T>> for Ptr<T> {
21	fn from(b: Box<T>) -> Self {
22		Self { p: Box::into_raw(b) }
23	}
24}
25impl<T: Default> Default for Ptr<T> {
26	fn default() -> Self {
27		Box::<T>::default().into()
28	}
29}
30impl<T: Debug> Debug for Ptr<T> {
31	fn fmt(&self, f: &mut Formatter) -> fmtRes {
32		f.debug_tuple("Ptr").field(unsafe { &*self.p }).finish()
33	}
34}
35unsafe impl<T> Send for Ptr<T> {}
36unsafe impl<T> Sync for Ptr<T> {}
37
38#[macro_export]
39macro_rules! LazyStatic {
40	($t: ty, $b: block) => {{
41		use {std::sync::OnceLock, $crate::lib::Mutex};
42		static S: OnceLock<Mutex<$t>> = OnceLock::new();
43		S.get_or_init(|| Mutex::new($b)).lock()
44	}};
45	($t: ty) => {
46		LazyStatic!($t, { <$t>::default() })
47	};
48}
49
50#[macro_export]
51macro_rules! LocalStatic {
52	($t: ty, $b: block) => {{
53		use std::{cell::OnceCell, cell::Cell};
54		thread_local!(static S: OnceCell<Cell<$t>> = <_>::default());
55		let r = S.with(|f| f.get_or_init(|| $b.into()).as_ptr());
56		unsafe { &mut *r }
57	}};
58	($t: ty) => {
59		LocalStatic!($t, { <$t>::default() })
60	};
61}
62
63#[macro_export]
64macro_rules! LeakyStatic {
65	($t: ty, $b: block) => {{
66		use std::mem::ManuallyDrop;
67		LocalStatic!(ManuallyDrop<$t>, { ManuallyDrop::new($b) }) as &mut $t
68	}};
69	($t: ty) => {
70		LeakyStatic!($t, { <$t>::default() })
71	};
72}
73
74use crate::lib::*;