generic-atomics 0.1.0

Generic Atomic types for types that implement num-primitive traits
Documentation
use crate::{
    atomic_float_wrapper::{
        Abs, Neg, UseUpdateToAdd, UseUpdateToMax, UseUpdateToMin, UseUpdateToSub,
    },
    AtomicNumber, IntoAtomicNumber,
};
use atomic_traits::{fetch::Update, AsPtr, Atomic, Bitwise};
use core::sync::atomic::Ordering::{self};
use num_primitive::PrimitiveFloat;
use num_traits::FromPrimitive;

pub trait AtomicFloat<F>:
    Atomic<Type = F>
    + Bitwise
    + AsPtr
    + Update<Type = F>
    + Abs<Type = F>
    + Neg<Type = F>
    + UseUpdateToAdd<Type = F>
    + UseUpdateToSub<Type = F>
    + UseUpdateToMin<Type = F>
    + UseUpdateToMax<Type = F>
    + Send
    + Sync
where
    F: PrimitiveFloat,
{
}

impl<AF, F> AtomicFloat<F> for AF
where
    AF: Atomic<Type = F>
        + Bitwise
        + AsPtr
        + Update<Type = F>
        + Abs<Type = F>
        + Neg<Type = F>
        + UseUpdateToAdd<Type = F>
        + UseUpdateToSub<Type = F>
        + UseUpdateToMin<Type = F>
        + UseUpdateToMax<Type = F>
        + Send
        + Sync,
    F: PrimitiveFloat,
{
}

pub trait IntoAtomicFloat: IntoAtomicNumber<AN = Self::AF> + PrimitiveFloat {
    type AF: AtomicFloat<Self>;
    fn into_atomic_float(self) -> impl AtomicFloat<Self>;
}

impl<T, A> IntoAtomicFloat for T
where
    T: IntoAtomicNumber<AN = A> + PrimitiveFloat + FromPrimitive,
    A: AtomicFloat<Self>,
{
    type AF = T::AN;

    fn into_atomic_float(self) -> impl AtomicFloat<Self> {
        Self::AF::new(self)
    }
}

pub trait PrimitiveAtomicFloat: PrimitiveFloat + IntoAtomicFloat {}
impl<T> PrimitiveAtomicFloat for T where T: PrimitiveFloat + IntoAtomicFloat {}

impl<T> Abs for AtomicNumber<T>
where
    T: PrimitiveAtomicFloat + FromPrimitive,
{
    type Type = T;

    #[inline(always)]
    fn fetch_abs(&self, order: Ordering) -> Self::Type {
        self.atomic.fetch_abs(order)
    }
}

impl<T> Neg for AtomicNumber<T>
where
    T: PrimitiveAtomicFloat + FromPrimitive,
{
    type Type = T;

    #[inline(always)]
    fn fetch_neg(&self, order: Ordering) -> Self::Type {
        self.atomic.fetch_neg(order)
    }
}
impl<T> UseUpdateToAdd for AtomicNumber<T>
where
    T: PrimitiveAtomicFloat + FromPrimitive,
{
    type Type = T;

    #[inline(always)]
    fn fetch_add_via_update(&self, val: Self::Type, order: Ordering) -> Self::Type {
        self.atomic.fetch_add_via_update(val, order)
    }
}

impl<T> UseUpdateToSub for AtomicNumber<T>
where
    T: PrimitiveAtomicFloat + FromPrimitive,
{
    type Type = T;

    #[inline(always)]
    fn fetch_sub_via_update(&self, val: Self::Type, order: Ordering) -> Self::Type {
        self.atomic.fetch_sub_via_update(val, order)
    }
}

impl<T> UseUpdateToMin for AtomicNumber<T>
where
    T: PrimitiveAtomicFloat + FromPrimitive,
{
    type Type = T;

    #[inline(always)]
    fn fetch_min_via_update(&self, val: Self::Type, order: Ordering) -> Self::Type {
        self.atomic.fetch_min_via_update(val, order)
    }
}

impl<T> UseUpdateToMax for AtomicNumber<T>
where
    T: PrimitiveAtomicFloat + FromPrimitive,
{
    type Type = T;

    #[inline]
    fn fetch_max_via_update(&self, val: Self::Type, order: Ordering) -> T {
        self.atomic.fetch_max_via_update(val, order)
    }
}