use std::fmt;
use super::atomic_integer_value::AtomicIntegerValue;
use super::atomic_number_ops::AtomicNumberOps;
use super::atomic_ops::AtomicOps;
use super::atomic_value::AtomicValue;
#[doc(alias = "AtomicBool")]
#[doc(alias = "AtomicI8")]
#[doc(alias = "AtomicU8")]
#[doc(alias = "AtomicI16")]
#[doc(alias = "AtomicU16")]
#[doc(alias = "AtomicI32")]
#[doc(alias = "AtomicU32")]
#[doc(alias = "AtomicI64")]
#[doc(alias = "AtomicU64")]
#[doc(alias = "AtomicI128")]
#[doc(alias = "AtomicU128")]
#[doc(alias = "AtomicIsize")]
#[doc(alias = "AtomicUsize")]
#[doc(alias = "AtomicF32")]
#[doc(alias = "AtomicF64")]
#[repr(transparent)]
pub struct Atomic<T>
where
T: AtomicValue,
{
primitive: T::Primitive,
}
impl<T> Atomic<T>
where
T: AtomicValue,
{
#[inline]
pub fn new(value: T) -> Self {
Self {
primitive: T::new_primitive(value),
}
}
#[inline]
pub fn load(&self) -> T {
AtomicOps::load(&self.primitive)
}
#[inline]
pub fn store(&self, value: T) {
AtomicOps::store(&self.primitive, value);
}
#[inline]
pub fn swap(&self, value: T) -> T {
AtomicOps::swap(&self.primitive, value)
}
#[inline]
pub fn compare_set(&self, current: T, new: T) -> Result<(), T> {
AtomicOps::compare_set(&self.primitive, current, new)
}
#[inline]
pub fn compare_set_weak(&self, current: T, new: T) -> Result<(), T> {
AtomicOps::compare_set_weak(&self.primitive, current, new)
}
#[inline]
pub fn compare_and_exchange(&self, current: T, new: T) -> T {
AtomicOps::compare_exchange(&self.primitive, current, new)
}
#[inline]
pub fn compare_and_exchange_weak(&self, current: T, new: T) -> T {
AtomicOps::compare_exchange_weak(&self.primitive, current, new)
}
#[inline]
pub fn fetch_update<F>(&self, f: F) -> T
where
F: Fn(T) -> T,
{
AtomicOps::fetch_update(&self.primitive, f)
}
#[inline]
pub fn inner(&self) -> &T::Inner {
T::inner(&self.primitive)
}
}
impl<T> Atomic<T>
where
T: AtomicValue,
T::Primitive: AtomicNumberOps<Value = T>,
{
#[inline]
pub fn fetch_add(&self, delta: T) -> T {
AtomicNumberOps::fetch_add(&self.primitive, delta)
}
#[inline]
pub fn fetch_sub(&self, delta: T) -> T {
AtomicNumberOps::fetch_sub(&self.primitive, delta)
}
#[inline]
pub fn fetch_mul(&self, factor: T) -> T {
AtomicNumberOps::fetch_mul(&self.primitive, factor)
}
#[inline]
pub fn fetch_div(&self, divisor: T) -> T {
AtomicNumberOps::fetch_div(&self.primitive, divisor)
}
}
impl<T> Atomic<T>
where
T: AtomicIntegerValue,
{
#[inline]
pub fn fetch_inc(&self) -> T {
T::fetch_inc(&self.primitive)
}
#[inline]
pub fn fetch_dec(&self) -> T {
T::fetch_dec(&self.primitive)
}
#[inline]
pub fn fetch_and(&self, value: T) -> T {
T::fetch_and(&self.primitive, value)
}
#[inline]
pub fn fetch_or(&self, value: T) -> T {
T::fetch_or(&self.primitive, value)
}
#[inline]
pub fn fetch_xor(&self, value: T) -> T {
T::fetch_xor(&self.primitive, value)
}
#[inline]
pub fn fetch_not(&self) -> T {
T::fetch_not(&self.primitive)
}
#[inline]
pub fn fetch_accumulate<F>(&self, value: T, f: F) -> T
where
F: Fn(T, T) -> T,
{
T::fetch_accumulate(&self.primitive, value, f)
}
#[inline]
pub fn fetch_max(&self, value: T) -> T {
T::fetch_max(&self.primitive, value)
}
#[inline]
pub fn fetch_min(&self, value: T) -> T {
T::fetch_min(&self.primitive, value)
}
}
impl Atomic<bool> {
#[inline]
pub fn fetch_set(&self) -> bool {
self.primitive.fetch_set()
}
#[inline]
pub fn fetch_clear(&self) -> bool {
self.primitive.fetch_clear()
}
#[inline]
pub fn fetch_not(&self) -> bool {
self.primitive.fetch_not()
}
#[inline]
pub fn fetch_and(&self, value: bool) -> bool {
self.primitive.fetch_and(value)
}
#[inline]
pub fn fetch_or(&self, value: bool) -> bool {
self.primitive.fetch_or(value)
}
#[inline]
pub fn fetch_xor(&self, value: bool) -> bool {
self.primitive.fetch_xor(value)
}
#[inline]
pub fn set_if_false(&self, new: bool) -> Result<(), bool> {
self.primitive.set_if_false(new)
}
#[inline]
pub fn set_if_true(&self, new: bool) -> Result<(), bool> {
self.primitive.set_if_true(new)
}
}
impl<T> Default for Atomic<T>
where
T: AtomicValue + Default,
{
#[inline]
fn default() -> Self {
Self::new(T::default())
}
}
impl<T> From<T> for Atomic<T>
where
T: AtomicValue,
{
#[inline]
fn from(value: T) -> Self {
Self::new(value)
}
}
impl<T> fmt::Debug for Atomic<T>
where
T: AtomicValue + fmt::Debug,
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Atomic")
.field("value", &self.load())
.finish()
}
}
impl<T> fmt::Display for Atomic<T>
where
T: AtomicValue + fmt::Display,
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.load())
}
}