use std::cmp::{Ordering};
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u8)]
pub enum Value {
Unused = 0,
Normal = 2,
Address = 3,
}
impl Value {
pub fn is_value(self) -> bool {
matches!(self, Value::Normal | Value::Address)
}
pub fn is_address(self) -> bool {
matches!(self, Value::Address)
}
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u8)]
pub enum Effect {
Cold = 0,
Hot = 1,
Send = 2,
}
impl Effect {
pub fn is_cold(self) -> bool {
matches!(self, Effect::Cold)
}
pub fn is_send(self) -> bool {
matches!(self, Effect::Send)
}
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Dep(pub Value, pub Effect);
impl Dep {
pub const NONE: Dep = Dep(Value::Unused, Effect::Cold);
pub const COLD_VALUE: Dep = Dep(Value::Normal, Effect::Cold);
pub const COLD_LOAD: Dep = Dep(Value::Address, Effect::Cold);
pub const GUARD: Dep = Dep(Value::Unused, Effect::Hot);
pub const VALUE: Dep = Dep(Value::Normal, Effect::Hot);
pub const LOAD: Dep = Dep(Value::Address, Effect::Hot);
pub const SEND: Dep = Dep(Value::Normal, Effect::Send);
pub const STORE: Dep = Dep(Value::Address, Effect::Send);
pub fn is_value(self) -> bool { self.0.is_value() }
pub fn is_address(self) -> bool { self.0.is_address() }
pub fn is_cold(self) -> bool { self.1.is_cold() }
pub fn is_send(self) -> bool { self.1.is_send() }
}
impl PartialOrd for Dep {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
use Ordering::*;
match (self.0.cmp(&other.0), self.1.cmp(&other.1)) {
(Less, Greater) | (Greater, Less) => None,
(Equal, ordering) => Some(ordering),
(ordering, _) => Some(ordering),
}
}
}
impl std::ops::BitOr for Dep {
type Output = Self;
fn bitor(self, other: Self) -> Self {
Self(self.0.max(other.0), self.1.max(other.1))
}
}