#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(u8)]
pub enum Signal {
UndefinedOperation = 1 << 0,
PossiblyUndefinedOperation = 1 << 1,
IntvlPartOfNaI = 1 << 2,
InvalidOperand = 1 << 3,
}
const fn signal_bit(signal: Signal) -> u8 {
match signal {
Signal::UndefinedOperation => 1,
Signal::PossiblyUndefinedOperation => 2,
Signal::IntvlPartOfNaI => 4,
Signal::InvalidOperand => 8,
}
}
impl From<Signal> for u8 {
fn from(value: Signal) -> Self {
signal_bit(value)
}
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
#[repr(transparent)]
pub struct SignalFlags(u8);
impl SignalFlags {
pub const NONE: Self = Self(0);
#[must_use]
pub const fn bits(self) -> u8 {
self.0
}
#[must_use]
pub const fn is_empty(self) -> bool {
self.0 == 0
}
#[must_use]
pub const fn contains(self, signal: Signal) -> bool {
self.0 & signal_bit(signal) != 0
}
pub const fn insert(&mut self, signal: Signal) {
self.0 |= signal_bit(signal);
}
pub const fn clear(&mut self) {
self.0 = 0;
}
#[must_use]
pub const fn take(&mut self) -> Self {
let previous = *self;
self.clear();
previous
}
}
pub trait SignalSink {
fn raise(&mut self, signal: Signal);
}
impl SignalSink for SignalFlags {
fn raise(&mut self, signal: Signal) {
self.insert(signal);
}
}
impl SignalSink for () {
fn raise(&mut self, _: Signal) {}
}