use core::sync::atomic::{AtomicBool, AtomicU8, AtomicU16, AtomicU32, AtomicU64, AtomicUsize};
use crate::CloseValue;
#[derive(Default, Debug)]
pub struct Counter(pub AtomicU64);
impl Counter {
pub fn new(starting_count: u64) -> Self {
Self(AtomicU64::new(starting_count))
}
pub fn increment(&self) {
self.0.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
}
pub fn add(&self, i: u64) {
self.0.fetch_add(i, std::sync::atomic::Ordering::Relaxed);
}
pub fn set(&self, i: u64) {
self.0.store(i, std::sync::atomic::Ordering::SeqCst);
}
}
impl CloseValue for &'_ Counter {
type Closed = u64;
fn close(self) -> Self::Closed {
<&AtomicU64>::close(&self.0)
}
}
impl CloseValue for Counter {
type Closed = u64;
fn close(self) -> Self::Closed {
self.0.close()
}
}
macro_rules! close_value_atomic {
(atomic: $atomic: ty, inner: $inner: ty) => {
impl $crate::CloseValue for &'_ $atomic {
type Closed = $inner;
fn close(self) -> Self::Closed {
self.load(std::sync::atomic::Ordering::Relaxed)
}
}
impl $crate::CloseValue for $atomic {
type Closed = $inner;
fn close(self) -> Self::Closed {
self.load(std::sync::atomic::Ordering::Relaxed)
}
}
};
}
close_value_atomic!(atomic: AtomicU64, inner: u64);
close_value_atomic!(atomic: AtomicU32, inner: u32);
close_value_atomic!(atomic: AtomicU16, inner: u16);
close_value_atomic!(atomic: AtomicU8, inner: u8);
close_value_atomic!(atomic: AtomicUsize, inner: usize);
close_value_atomic!(atomic: AtomicBool, inner: bool);