#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Cost {
Exact(u64),
Dynamic(u64),
}
impl Cost {
#[inline]
pub fn value(self) -> u64 {
match self { Cost::Exact(n) | Cost::Dynamic(n) => n }
}
#[inline]
pub fn is_dynamic(self) -> bool {
matches!(self, Cost::Dynamic(_))
}
#[inline]
pub fn sum(parent: u64, a: Cost, b: Cost) -> Cost {
let total = parent.saturating_add(a.value()).saturating_add(b.value());
if a.is_dynamic() || b.is_dynamic() {
Cost::Dynamic(total)
} else {
Cost::Exact(total)
}
}
#[inline]
pub fn sum1(parent: u64, a: Cost) -> Cost {
let total = parent.saturating_add(a.value());
if a.is_dynamic() { Cost::Dynamic(total) } else { Cost::Exact(total) }
}
#[inline]
pub fn branch(parent: u64, test: Cost, yes: Cost, no: Cost) -> Cost {
let arm = yes.value().max(no.value());
let total = parent.saturating_add(test.value()).saturating_add(arm);
let dyn_any = test.is_dynamic() || yes.is_dynamic() || no.is_dynamic();
if dyn_any { Cost::Dynamic(total) } else { Cost::Exact(total) }
}
}
pub(crate) const PATTERN_COSTS: [u64; 18] = [
1, 1, 1, 1, 1, 1, 1, 1, 64, 1, 64, 32, 32, 32, 32, 25, 1, 1, ];