1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
use crate::uses::*; #[macro_export] macro_rules! UnsafeOnce { ($t: ty, $b: block) => {{ static mut S: Option<$t> = None; unsafe { if S.is_some() { } else { S = Some($b); } S.as_mut() } .unwrap() }}; } #[macro_export] macro_rules! UnsafeLocal { ($t: ty, $b: block) => {{ use std::cell::UnsafeCell; thread_local!(static S: UnsafeCell<Option<$t>> = UnsafeCell::new(None)); let mut r = None; unsafe { S.with(|f| { let f = f.get(); if (*f).is_some() { } else { *f = Some($b); } r = Some(f) }); (*r.unwrap()).as_mut().unwrap() } }}; } #[macro_export] macro_rules! FnStatic { ($n: ident, $t: ty, $b: block) => { fn $n() -> &'static mut $t { UnsafeOnce!($t, { Def() }) } *$n() = $b; }; } #[macro_export] macro_rules! FnLocal { ($n: ident, $t: ty, $b: block) => { fn $n() -> &'static mut $t { UnsafeLocal!($t, { Def() }) } *$n() = $b; }; } #[derive(Debug)] pub struct static_ptr<T: Send + Sync> { t: Dummy<T>, ptr: usize, } impl<T: Send + Sync> static_ptr<T> { pub unsafe fn new(t: &T) -> Self { let ptr = t as *const T as usize; Self { ptr, t: Dummy } } pub fn get(&self) -> &'static T { unsafe { &*(self.ptr as *const T) } } #[allow(unused_mut)] pub fn get_mut(&mut self) -> &'static mut T { unsafe { &mut *(self.ptr as *mut T) } } } impl<T: Send + Sync> Copy for static_ptr<T> {} impl<T: Send + Sync> Clone for static_ptr<T> { fn clone(&self) -> Self { Self { ptr: self.ptr, t: Dummy } } } #[macro_export] macro_rules! StaticPtr { ($n: expr) => { unsafe { static_ptr::new($n) }; }; ($($n: expr),+) => { unsafe { ($(static_ptr::new($n),)+) }; }; }