pub(crate) mod private {
pub(crate) trait Value: std::fmt::Debug + Default + Copy {
fn since(self, last: Self) -> crate::Delta;
fn since_and_update(&mut self, now: Self) -> crate::Delta;
}
impl Value for u64 {
fn since(self, last: Self) -> crate::Delta {
self.wrapping_sub(last).into()
}
fn since_and_update(&mut self, now: Self) -> crate::Delta {
let delta = now.wrapping_sub(*self);
*self = now;
delta.into()
}
}
pub(crate) trait ArchDesc: Default {
type Value: Value;
fn get_timer() -> Self::Value;
}
pub(crate) trait TraceValue:
Default + Copy + From<crate::Delta> + Into<crate::Delta>
{
fn sat_add(self, other: u64) -> Self;
}
}
pub trait TraceCount: Default + Copy {
fn sat_inc(&mut self);
fn as_usize(self) -> usize;
}
impl TraceCount for () {
fn sat_inc(&mut self) {}
fn as_usize(self) -> usize {
0
}
}
macro_rules! trace_count {
{$t:ty} => {
impl TraceCount for $t {
#[inline(always)]
fn sat_inc(&mut self) {
if *self != Self::MAX {*self = self.wrapping_add(1);}
}
#[inline(always)]
fn as_usize(self) -> usize {
self as usize
}
}
}
}
trace_count!(u8);
trace_count!(u16);
trace_count!(u32);
trace_count!(u64);
trace_count!(u128);
trace_count!(usize);
macro_rules! trace_float_count {
{$t:ty} => {
impl TraceCount for $t {
#[inline(always)]
fn sat_inc(&mut self) {
*self += 1.0;
}
#[inline(always)]
fn as_usize(self) -> usize {
self as usize
}
}
}
}
trace_float_count!(f32);
trace_float_count!(f64);
#[allow(private_bounds)]
pub trait TraceValue: private::TraceValue {}
impl<T> TraceValue for T where T: private::TraceValue {}
impl private::TraceValue for () {
fn sat_add(self, _other: u64) -> Self {}
}
macro_rules! trace_value {
{$t:ty} => {
impl private::TraceValue for $t {
fn sat_add(self, other:u64) -> Self {
self.saturating_add(other as $t)
}
}
}
}
trace_value!(u8);
trace_value!(u16);
trace_value!(u32);
trace_value!(u64);
trace_value!(u128);
trace_value!(usize);
macro_rules! trace_float_value {
{$t:ty} => {
impl private::TraceValue for $t {
fn sat_add(self, other:u64) -> Self {
self + (other as $t)
}
}
}
}
trace_float_value!(f32);
trace_float_value!(f64);
#[allow(private_bounds)]
pub trait TArch: private::ArchDesc {}
impl<T> TArch for T where T: private::ArchDesc {}