clock_zones/
clocks.rs

1use std::convert::TryFrom;
2
3/// Represents either the constant *zero clock* or a *clock variable*.
4#[derive(Clone, Eq, PartialEq, Hash, Copy, Debug)]
5#[repr(transparent)]
6pub struct Clock(pub(crate) usize);
7
8impl Clock {
9    /// The constant zero clock.
10    pub const ZERO: Clock = Clock(0);
11
12    /// Constructs a [Variable] with the given number.
13    pub fn variable(number: usize) -> Variable {
14        Variable(number + 1)
15    }
16
17    /// Creates a clock from the given index.
18    #[inline(always)]
19    pub(crate) fn from_index(index: usize) -> Self {
20        Clock(index)
21    }
22}
23
24/// Represents a *clock variable*.
25#[derive(Clone, Eq, PartialEq, Hash, Copy, Debug)]
26#[repr(transparent)]
27pub struct Variable(pub(crate) usize);
28
29impl Variable {
30    /// Retrieves the number of the variable.
31    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    /// Converts the clock into an index.
56    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
73/// Either a [Clock] or a [Variable].
74pub trait AnyClock: Copy + ClockToIndex {
75    /// Converts the [AnyClock] into a [Clock].
76    #[inline(always)]
77    fn as_clock(&self) -> Clock {
78        Clock(self.into_index())
79    }
80
81    /// Checks whether the clock is the constant zero clock.
82    fn is_zero(&self) -> bool {
83        self.into_index() == 0
84    }
85
86    /// Checks whether the clock is a clock variable.
87    fn is_variable(&self) -> bool {
88        self.into_index() != 0
89    }
90}
91
92impl AnyClock for Clock {}
93
94impl AnyClock for Variable {}