#![no_std]
#![warn(missing_docs)]
use core::fmt::{Debug, Formatter, Display};
use core::sync::atomic::{
AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicU16, AtomicU32, AtomicU8, Ordering,
};
use atomic_float::AtomicF32;
macro_rules! impls {
($name:ident: $atomic:ident, $inner:ty) => {
#[derive(Default)]
#[repr(transparent)]
pub struct $name($atomic);
impl $name {
#[inline(always)]
pub const fn new(val: $inner) -> Self {
$name($atomic::new(val))
}
#[inline(always)]
pub fn get(&self) -> $inner {
self.0.load(Ordering::Relaxed)
}
#[inline(always)]
pub fn set(&self, val: $inner) {
self.0.store(val, Ordering::Relaxed)
}
#[inline(always)]
pub fn update(&self, f: impl FnOnce($inner) -> $inner) {
self.set(f(self.get()))
}
}
impl Debug for $name {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
self.0.fmt(f)
}
}
impl Display for $name {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
self.0.fmt(f)
}
}
impl From<$inner> for $name {
fn from(val: $inner) -> Self {
$name::new(val)
}
}
#[cfg(feature="serde")]
impl serde::Serialize for $name {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.0.load(Ordering::Relaxed).serialize(serializer)
}
}
#[cfg(feature="serde")]
impl<'de> serde::Deserialize<'de> for $name {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
serde::Deserialize::deserialize(deserializer).map(Self::new)
}
}
};
}
impls!(RelaxedBool: AtomicBool, bool);
impls!(RelaxedU8: AtomicU8, u8);
impls!(RelaxedU16: AtomicU16, u16);
impls!(RelaxedU32: AtomicU32, u32);
impls!(RelaxedI8: AtomicI8, i8);
impls!(RelaxedI16: AtomicI16, i16);
impls!(RelaxedI32: AtomicI32, i32);
impls!(RelaxedF32: AtomicF32, f32);
impl RelaxedBool {
#[cfg(target_has_atomic = "8")]
pub fn fetch_not(&self) -> bool {
self.0.fetch_not(Ordering::Relaxed)
}
}