use std::convert::TryFrom;
#[derive(Clone, Eq, PartialEq, Hash, Copy, Debug)]
#[repr(transparent)]
pub struct Clock(pub(crate) usize);
impl Clock {
pub const ZERO: Clock = Clock(0);
pub fn variable(number: usize) -> Variable {
Variable(number + 1)
}
#[inline(always)]
pub(crate) fn from_index(index: usize) -> Self {
Clock(index)
}
}
#[derive(Clone, Eq, PartialEq, Hash, Copy, Debug)]
#[repr(transparent)]
pub struct Variable(pub(crate) usize);
impl Variable {
pub fn number(self) -> usize {
self.0 - 1
}
}
impl From<Variable> for Clock {
fn from(variable: Variable) -> Self {
Clock(variable.0)
}
}
impl TryFrom<Clock> for Variable {
type Error = ();
fn try_from(value: Clock) -> Result<Self, Self::Error> {
if value.0 != 0 {
Ok(Variable(value.0))
} else {
Err(())
}
}
}
pub trait ClockToIndex {
fn into_index(self) -> usize;
}
impl ClockToIndex for Clock {
#[inline(always)]
fn into_index(self) -> usize {
self.0
}
}
impl ClockToIndex for Variable {
#[inline(always)]
fn into_index(self) -> usize {
self.0
}
}
pub trait AnyClock: Copy + ClockToIndex {
#[inline(always)]
fn as_clock(&self) -> Clock {
Clock(self.into_index())
}
fn is_zero(&self) -> bool {
self.into_index() == 0
}
fn is_variable(&self) -> bool {
self.into_index() != 0
}
}
impl AnyClock for Clock {}
impl AnyClock for Variable {}