1use std::convert::TryFrom;
2
3#[derive(Clone, Eq, PartialEq, Hash, Copy, Debug)]
5#[repr(transparent)]
6pub struct Clock(pub(crate) usize);
7
8impl Clock {
9 pub const ZERO: Clock = Clock(0);
11
12 pub fn variable(number: usize) -> Variable {
14 Variable(number + 1)
15 }
16
17 #[inline(always)]
19 pub(crate) fn from_index(index: usize) -> Self {
20 Clock(index)
21 }
22}
23
24#[derive(Clone, Eq, PartialEq, Hash, Copy, Debug)]
26#[repr(transparent)]
27pub struct Variable(pub(crate) usize);
28
29impl Variable {
30 pub fn number(self) -> usize {
32 self.0 - 1
33 }
34}
35
36impl From<Variable> for Clock {
37 fn from(variable: Variable) -> Self {
38 Clock(variable.0)
39 }
40}
41
42impl TryFrom<Clock> for Variable {
43 type Error = ();
44
45 fn try_from(value: Clock) -> Result<Self, Self::Error> {
46 if value.0 != 0 {
47 Ok(Variable(value.0))
48 } else {
49 Err(())
50 }
51 }
52}
53
54pub trait ClockToIndex {
55 fn into_index(self) -> usize;
57}
58
59impl ClockToIndex for Clock {
60 #[inline(always)]
61 fn into_index(self) -> usize {
62 self.0
63 }
64}
65
66impl ClockToIndex for Variable {
67 #[inline(always)]
68 fn into_index(self) -> usize {
69 self.0
70 }
71}
72
73pub trait AnyClock: Copy + ClockToIndex {
75 #[inline(always)]
77 fn as_clock(&self) -> Clock {
78 Clock(self.into_index())
79 }
80
81 fn is_zero(&self) -> bool {
83 self.into_index() == 0
84 }
85
86 fn is_variable(&self) -> bool {
88 self.into_index() != 0
89 }
90}
91
92impl AnyClock for Clock {}
93
94impl AnyClock for Variable {}