use std::ops::{Deref, DerefMut};
use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Debug, Default)]
pub struct Tracked<T> {
value: T,
generation: AtomicU64,
}
impl<T> Tracked<T> {
pub fn new(value: T) -> Self {
Tracked {
value,
generation: AtomicU64::new(0),
}
}
pub(crate) fn generation(&self) -> u64 {
self.generation.load(Ordering::Relaxed)
}
pub(crate) fn peek(&self) -> &T {
&self.value
}
}
impl<T> Deref for Tracked<T> {
type Target = T;
fn deref(&self) -> &T {
&self.value
}
}
impl<T> DerefMut for Tracked<T> {
fn deref_mut(&mut self) -> &mut T {
self.generation.fetch_add(1, Ordering::Relaxed);
&mut self.value
}
}
impl<T> From<T> for Tracked<T> {
fn from(value: T) -> Self {
Tracked::new(value)
}
}
impl<T: Clone> Clone for Tracked<T> {
fn clone(&self) -> Self {
Tracked::new(self.value.clone())
}
}