use std::sync::atomic::{AtomicUsize, Ordering};
#[derive(Debug)]
pub(crate) struct Counter(AtomicUsize);
impl Counter {
pub(crate) const fn new() -> Self {
Self(AtomicUsize::new(0))
}
pub(crate) fn value(&self) -> usize {
self.0.load(Ordering::Relaxed)
}
pub(crate) fn increment(&self) {
self.increment_by(1)
}
pub(crate) fn increment_by(&self, value: usize) {
self.0.fetch_add(value, Ordering::Relaxed);
}
pub(crate) fn local(&self) -> LocalCounter<'_> {
LocalCounter::new(self)
}
}
#[derive(Debug)]
pub(crate) struct LocalCounter<'a> {
parent: &'a Counter,
value: usize,
}
impl<'a> LocalCounter<'a> {
fn new(parent: &'a Counter) -> Self {
Self { parent, value: 0 }
}
pub(crate) fn increment(&mut self) {
self.increment_by(1)
}
pub(crate) fn increment_by(&mut self, value: usize) {
self.value += value
}
}
impl Drop for LocalCounter<'_> {
fn drop(&mut self) {
self.parent.increment_by(self.value)
}
}