atomic_prim_traits 0.2.0

Traits over primitive atomic types.
Documentation
#![cfg_attr(feature = "nightly", feature(atomic_min_max, atomic_mut_ptr, no_more_cas))]
use std::sync::atomic::{self, Ordering};
use std::hash::Hash;
use std::fmt::{Debug, Display};
use std::panic::{RefUnwindSafe, UnwindSafe};

use std::ops::{
    Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign, Rem, RemAssign,
    BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign,
    Shl, ShlAssign, Shr, ShrAssign,
    Not,
};

pub trait AtomicInt : Default + Send + Sync + RefUnwindSafe + UnwindSafe {
    type Prim
        : Copy + Debug + Display + Eq + Hash + Ord + Sized
        + Add + AddAssign
        + BitAnd + BitAndAssign
        + BitOr + BitOrAssign
        + BitXor + BitXorAssign
        + Div + DivAssign
        + Mul + MulAssign
        + Not
        + Rem + RemAssign
        + Shl + ShlAssign
        + Shr + ShrAssign
        + Sub + SubAssign;

    fn new(val: <Self as AtomicInt>::Prim) -> Self;

    fn fetch_add(
        &self,
        new: <Self as AtomicInt>::Prim,
        ordering: Ordering
    ) -> <Self as AtomicInt>::Prim;

    fn fetch_sub(
        &self,
        new: <Self as AtomicInt>::Prim,
        ordering: Ordering
    ) -> <Self as AtomicInt>::Prim;

    fn fetch_and(
        &self,
        new: <Self as AtomicInt>::Prim,
        ordering: Ordering
    ) -> <Self as AtomicInt>::Prim;

    fn fetch_nand(
        &self,
        new: <Self as AtomicInt>::Prim,
        ordering: Ordering
    ) -> <Self as AtomicInt>::Prim;

    fn fetch_or(
        &self,
        new: <Self as AtomicInt>::Prim,
        ordering: Ordering
    ) -> <Self as AtomicInt>::Prim;

    fn fetch_xor(
        &self,
        new: <Self as AtomicInt>::Prim,
        ordering: Ordering
    ) -> <Self as AtomicInt>::Prim;

    #[cfg(feature="nightly")]
    fn fetch_min(&self, val: <Self as AtomicInt>::Prim, order: Ordering) -> <Self as AtomicInt>::Prim;

    #[cfg(feature="nightly")]
    fn fetch_max(&self, val: <Self as AtomicInt>::Prim, order: Ordering) -> <Self as AtomicInt>::Prim;

    #[cfg(feature="nightly")]
    fn fetch_update<F>(
        &self,
        f: F,
        fetch_order: Ordering,
        set_order: Ordering
    ) -> Result<<Self as AtomicInt>::Prim, <Self as AtomicInt>::Prim>
    where F: FnMut(<Self as AtomicInt>::Prim) -> Option<<Self as AtomicInt>::Prim>;

    fn get_mut(&mut self) -> &mut <Self as AtomicInt>::Prim;

    fn into_inner(self) -> <Self as AtomicInt>::Prim;

    fn load(&self, order: Ordering) -> <Self as AtomicInt>::Prim;

    fn store(&self, val: <Self as AtomicInt>::Prim, order: Ordering);

    fn swap(&self, val: <Self as AtomicInt>::Prim, order: Ordering) -> <Self as AtomicInt>::Prim;

    fn compare_and_swap(
        &self,
        current: <Self as AtomicInt>::Prim,
        new: <Self as AtomicInt>::Prim,
        ordering: Ordering
    ) -> <Self as AtomicInt>::Prim;

    fn compare_exchange(
        &self,
        current: <Self as AtomicInt>::Prim,
        new: <Self as AtomicInt>::Prim,
        success: Ordering,
        failure: Ordering
    ) -> Result<<Self as AtomicInt>::Prim, <Self as AtomicInt>::Prim>;

    fn compare_exchange_weak(
        &self,
        current: <Self as AtomicInt>::Prim,
        new: <Self as AtomicInt>::Prim,
        success: Ordering,
        failure: Ordering
    ) -> Result<<Self as AtomicInt>::Prim, <Self as AtomicInt>::Prim>;

    #[cfg(feature="nightly")]
    fn as_mut_ptr(&self) -> *mut <Self as AtomicInt>::Prim;
}

macro_rules! impl_atomic_int {
    ($atomic:ty = $prim:ty) => {
        impl AtomicInt for $atomic {
            type Prim = $prim;

            fn new(val: $prim) -> Self {
                <$atomic>::new(val)
            }

            fn fetch_add(
                &self,
                new: $prim,
                ordering: Ordering,
            ) -> $prim {
                self.fetch_add(new, ordering)
            }

            fn fetch_sub(
                &self,
                new: $prim,
                ordering: Ordering,
            ) -> $prim {
                self.fetch_sub(new, ordering)
            }

            fn fetch_and(
                &self,
                new: $prim,
                ordering: Ordering,
            ) -> $prim {
                self.fetch_and(new, ordering)
            }

            fn fetch_nand(
                &self,
                new: $prim,
                ordering: Ordering,
            ) -> $prim {
                self.fetch_nand(new, ordering)
            }

            fn fetch_or(
                &self,
                new: $prim,
                ordering: Ordering,
            ) -> $prim {
                self.fetch_or(new, ordering)
            }

            fn fetch_xor(
                &self,
                new: $prim,
                ordering: Ordering,
            ) -> $prim {
                self.fetch_xor(new, ordering)
            }

            #[cfg(feature = "nightly")]
            fn fetch_min(
                &self,
                val: $prim,
                ordering: Ordering,
            ) -> $prim {
                self.fetch_min(val, ordering)
            }

            #[cfg(feature = "nightly")]
            fn fetch_max(
                &self,
                val: $prim,
                ordering: Ordering,
            ) -> $prim {
                self.fetch_max(val, ordering)
            }

            #[cfg(feature = "nightly")]
            fn fetch_update<F>(
                &self,
                f: F,
                fetch_order: Ordering,
                set_order: Ordering,
            ) -> Result<$prim, $prim>
            where
                F: FnMut($prim) -> Option<$prim>,
            {
                self.fetch_update(f, fetch_order, set_order)
            }

            fn get_mut(&mut self) -> &mut $prim {
                self.get_mut()
            }

            fn into_inner(self) -> $prim {
                self.into_inner()
            }

            fn load(&self, order: Ordering) -> $prim {
                self.load(order)
            }

            fn store(&self, val: $prim, order: Ordering) {
                self.store(val, order)
            }

            fn swap(&self, val: $prim, order: Ordering) -> $prim {
                self.swap(val, order)
            }

            fn compare_and_swap(
                &self,
                current: $prim,
                new: $prim,
                ordering: Ordering
            ) -> $prim {
                self.compare_and_swap(current, new, ordering)
            }

            fn compare_exchange(
                &self,
                current: $prim,
                new: $prim,
                success: Ordering,
                failure: Ordering
            ) -> Result<$prim, $prim> {
                self.compare_exchange(current, new, success, failure)
            }

            fn compare_exchange_weak(
                &self,
                current: $prim,
                new: $prim,
                success: Ordering,
                failure: Ordering
            ) -> Result<$prim, $prim> {
                self.compare_exchange_weak(current, new, success, failure)
            }

            #[cfg(feature="nightly")]
            fn as_mut_ptr(&self) -> *mut $prim {
                self.as_mut_ptr()
            }
        }
    };
}

impl_atomic_int!(atomic::AtomicU8 = u8);
impl_atomic_int!(atomic::AtomicU16 = u16);
impl_atomic_int!(atomic::AtomicU32 = u32);
impl_atomic_int!(atomic::AtomicU64 = u64);
impl_atomic_int!(atomic::AtomicUsize = usize);

impl_atomic_int!(atomic::AtomicI8 = i8);
impl_atomic_int!(atomic::AtomicI16 = i16);
impl_atomic_int!(atomic::AtomicI32 = i32);
impl_atomic_int!(atomic::AtomicI64 = i64);
impl_atomic_int!(atomic::AtomicIsize = isize);