use std::ops;
use {hazard, local};
pub struct Guard<T: 'static> {
hazard: Option<hazard::Writer>,
pointer: &'static T,
}
impl<T> Guard<T> {
pub fn new<F>(ptr: F) -> Guard<T>
where F: FnOnce() -> &'static T {
let hazard = local::get_hazard();
let ptr = ptr();
hazard.set(hazard::State::Protect(ptr as *const T as *const u8));
Guard {
hazard: Some(hazard),
pointer: ptr,
}
}
pub fn map<U, F>(mut self, f: F) -> Guard<U>
where F: FnOnce(&T) -> &U {
Guard {
hazard: self.hazard.take(),
pointer: f(self.pointer),
}
}
}
impl<T> Drop for Guard<T> {
fn drop(&mut self) {
local::free_hazard(self.hazard.take().unwrap());
}
}
impl<T> ops::Deref for Guard<T> {
type Target = T;
fn deref(&self) -> &T {
self.pointer
}
}