use std::sync::Arc;
use once_cell::sync::OnceCell;
pub struct Deferred<T>(Arc<OnceCell<T>>);
impl<T: Send + Sync + 'static> Deferred<T> {
pub fn new<F>(f: F) -> Self
where
F: FnOnce() -> T + Send + Sync + 'static,
{
let inner = Arc::new(OnceCell::new());
let cloned = Arc::clone(&inner);
rayon::spawn(move || {
cloned.get_or_init(f);
});
Self(inner)
}
pub fn wait(&self) -> &T {
if let Some(value) = self.0.get() {
return value;
}
while let Some(rayon::Yield::Executed) = rayon::yield_now() {}
self.0.wait()
}
}
impl<T> Clone for Deferred<T> {
fn clone(&self) -> Self {
Self(Arc::clone(&self.0))
}
}