#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MaxPlus(pub u64);
impl MaxPlus {
pub const ZERO: MaxPlus = MaxPlus(0);
pub const ONE: MaxPlus = MaxPlus(1);
pub const NEG_INF: MaxPlus = MaxPlus(0);
#[inline]
pub const fn is_neg_inf(self) -> bool {
self.0 == 0
}
#[inline]
pub const fn is_finite(self) -> bool {
self.0 != 0
}
#[inline]
pub const fn from_val(v: u64) -> Self {
assert!(v < u64::MAX, "MaxPlus: value too large");
MaxPlus(v + 1)
}
#[inline]
pub const fn to_val(self) -> Option<u64> {
if self.0 == 0 { None } else { Some(self.0 - 1) }
}
#[inline]
pub const fn add(self, other: MaxPlus) -> MaxPlus {
if self.0 >= other.0 { self } else { other }
}
#[inline]
pub const fn mul(self, other: MaxPlus) -> MaxPlus {
if self.is_neg_inf() || other.is_neg_inf() {
MaxPlus::ZERO
} else {
let (sum, overflow) = self.0.overflowing_add(other.0);
if overflow {
MaxPlus(u64::MAX)
} else {
MaxPlus(sum - 1)
}
}
}
}
impl core::fmt::Display for MaxPlus {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if self.is_neg_inf() {
write!(f, "-inf")
} else {
write!(f, "{}", self.0 - 1)
}
}
}