use std::cell::Cell; use std::ptr; /// Scoped thread-local storage pub(super) struct Scoped { pub(super) inner: Cell<*const T>, } impl Scoped { pub(super) const fn new() -> Scoped { Scoped { inner: Cell::new(ptr::null()), } } /// Inserts a value into the scoped cell for the duration of the closure pub(super) fn set(&self, t: &T, f: F) -> R where F: FnOnce() -> R, { struct Reset<'a, T> { cell: &'a Cell<*const T>, prev: *const T, } impl Drop for Reset<'_, T> { fn drop(&mut self) { self.cell.set(self.prev); } } let prev = self.inner.get(); self.inner.set(t as *const _); let _reset = Reset { cell: &self.inner, prev, }; f() } /// Gets the value out of the scoped cell; pub(super) fn with(&self, f: F) -> R where F: FnOnce(Option<&T>) -> R, { let val = self.inner.get(); if val.is_null() { f(None) } else { unsafe { f(Some(&*val)) } } } }