#[cfg(not(has_once_is_completed))]
use core::sync::atomic::{AtomicBool, Ordering};
use std::sync::Once as RawOnce;
#[rustversion::before(1.51)]
pub const LEGACY_POISON_BEHAVIOR: bool = true;
#[rustversion::since(1.51)]
pub const LEGACY_POISON_BEHAVIOR: bool = false;
pub struct Once {
raw: RawOnce,
#[cfg(not(has_once_is_completed))]
completed: AtomicBool,
}
impl Once {
#[inline]
pub const fn new() -> Once {
#[allow(deprecated)] Once {
raw: std::sync::ONCE_INIT,
#[cfg(not(has_once_is_completed))]
completed: AtomicBool::new(false),
}
}
#[inline]
#[cfg_attr(has_once_is_completed, clippy::msrv = "1.43")]
pub fn is_completed(&self) -> bool {
#[cfg(has_once_is_completed)]
{
self.raw.is_completed()
}
#[cfg(not(has_once_is_completed))]
{
self.completed.load(Ordering::Acquire)
}
}
#[inline]
pub fn call_once(&self, func: impl FnOnce()) {
self.raw.call_once(func);
}
#[inline]
pub fn call_once_force(&self, func: impl FnOnce()) {
raw_call_once_force(&self.raw, || {
func();
#[cfg(not(has_once_is_completed))]
{
self.completed.store(true, Ordering::Release);
}
});
}
}
#[inline]
#[rustversion::before(1.51)]
pub fn raw_call_once_force(once: &RawOnce, inner: impl FnOnce()) {
assert!(LEGACY_POISON_BEHAVIOR);
once.call_once(inner)
}
#[inline]
#[rustversion::since(1.51)]
pub fn raw_call_once_force(once: &RawOnce, inner: impl FnOnce()) {
assert!(!LEGACY_POISON_BEHAVIOR);
once.call_once_force(|_| inner());
}