use std::cell::Cell;
use super::coverage::Fidelity;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum Numerics {
Exact,
#[default]
Fast,
}
impl Numerics {
pub fn fidelity(self) -> Fidelity {
match self {
Numerics::Exact => Fidelity::BitIdentical,
Numerics::Fast => Fidelity::Envelope,
}
}
pub fn exactly<Output>(body: impl FnOnce() -> Output) -> Output {
let _scope = NumericsScope::enter(Numerics::Exact);
body()
}
}
thread_local! {
static CURRENT: Cell<Numerics> = const { Cell::new(Numerics::Fast) };
}
pub(crate) fn current() -> Numerics {
CURRENT.with(Cell::get)
}
pub(crate) struct NumericsScope {
previous: Numerics,
}
impl NumericsScope {
pub(crate) fn enter(numerics: Numerics) -> Self {
let previous = CURRENT.with(|cell| cell.replace(numerics));
Self { previous }
}
}
impl Drop for NumericsScope {
fn drop(&mut self) {
CURRENT.with(|cell| cell.set(self.previous));
}
}