use crate::nillable::{AllNil, FirstIsNil};
pub struct Flip(bool);
impl Default for Flip {
#[inline]
fn default() -> Self {
Self(true)
}
}
impl Flip {
#[inline]
pub fn tas(&mut self) -> bool {
let res = self.0;
self.0 = false;
res
}
}
pub struct Register<T> {
inner: T,
next: T,
on_clock: bool,
}
impl<T> Default for Register<T>
where
T: AllNil,
{
#[inline]
fn default() -> Self {
Self {
inner: T::auto_size(),
next: T::auto_size(),
on_clock: false,
}
}
}
impl<T> Register<T> {
#[inline]
pub fn schedule(&mut self, t: T)
where
T: FirstIsNil,
{
if !t.first_is_nil() {
self.next = t;
}
}
#[inline]
pub fn with_clock(&mut self, clk: crate::nillable::Nillable<bool>) {
self.on_clock = clk.is(crate::nillable::Nillable::Defined(true));
}
#[inline]
pub fn try_initialize(&mut self, t: T)
where
T: FirstIsNil,
{
if self.inner.first_is_nil() {
self.inner = t;
}
}
#[inline]
pub fn commit(&mut self)
where
T: Clone,
{
self.inner = self.next.clone();
}
#[inline]
pub fn get(&mut self) -> T
where
T: Clone + AllNil,
{
if self.on_clock {
self.inner.clone()
} else {
T::auto_size()
}
}
}