#[allow(unused_imports)]
use core::sync::atomic::Ordering::{self, *};
use docfg::docfg;
#[allow(non_camel_case_types)]
pub type Atomic_c_char = <core::ffi::c_char as HasAtomic>::Atomic;
#[allow(non_camel_case_types)]
pub type Atomic_c_schar = <core::ffi::c_schar as HasAtomic>::Atomic;
#[allow(non_camel_case_types)]
pub type Atomic_c_uchar = <core::ffi::c_uchar as HasAtomic>::Atomic;
#[allow(non_camel_case_types)]
pub type Atomic_c_short = <core::ffi::c_short as HasAtomic>::Atomic;
#[allow(non_camel_case_types)]
pub type Atomic_c_ushort = <core::ffi::c_ushort as HasAtomic>::Atomic;
#[allow(non_camel_case_types)]
pub type Atomic_c_int = <core::ffi::c_int as HasAtomic>::Atomic;
#[allow(non_camel_case_types)]
pub type Atomic_c_uint = <core::ffi::c_uint as HasAtomic>::Atomic;
#[allow(non_camel_case_types)]
pub type Atomic_c_long = <core::ffi::c_long as HasAtomic>::Atomic;
#[allow(non_camel_case_types)]
pub type Atomic_c_ulong = <core::ffi::c_ulong as HasAtomic>::Atomic;
#[allow(non_camel_case_types)]
pub type Atomic_c_longlong = <core::ffi::c_longlong as HasAtomic>::Atomic;
#[allow(non_camel_case_types)]
pub type Atomic_c_ulonglong = <core::ffi::c_ulonglong as HasAtomic>::Atomic;
#[docfg(feature = "nightly")]
#[allow(non_camel_case_types)]
pub type Atomic_c_size_t = <core::ffi::c_size_t as HasAtomic>::Atomic;
#[docfg(feature = "nightly")]
#[allow(non_camel_case_types)]
pub type Atomic_c_ssize_t = <core::ffi::c_ssize_t as HasAtomic>::Atomic;
#[docfg(feature = "nightly")]
#[allow(non_camel_case_types)]
pub type Atomic_c_ptrdiff_t = <core::ffi::c_ptrdiff_t as HasAtomic>::Atomic;
pub trait HasAtomic {
type Atomic: Atomic<Primitive = Self>;
}
#[allow(clippy::missing_errors_doc)]
pub unsafe trait Atomic: Send + Sync {
type Primitive: HasAtomic<Atomic = Self>;
fn new(v: Self::Primitive) -> Self;
fn get_mut(&mut self) -> &mut Self::Primitive;
fn into_inner(self) -> Self::Primitive;
fn load(&self, order: Ordering) -> Self::Primitive;
fn store(&self, val: Self::Primitive, order: Ordering);
fn swap(&self, val: Self::Primitive, order: Ordering) -> Self::Primitive;
fn compare_exchange(
&self,
current: Self::Primitive,
new: Self::Primitive,
success: Ordering,
failure: Ordering,
) -> Result<Self::Primitive, Self::Primitive>;
fn compare_exchange_weak(
&self,
current: Self::Primitive,
new: Self::Primitive,
success: Ordering,
failure: Ordering,
) -> Result<Self::Primitive, Self::Primitive>;
fn fetch_update<F: FnMut(Self::Primitive) -> Option<Self::Primitive>>(
&self,
set_order: Ordering,
fetch_ordering: Ordering,
f: F,
) -> Result<Self::Primitive, Self::Primitive>;
}
#[cfg_attr(docsrs, doc(cfg(feature = "const")))]
#[cfg(feature = "const")]
#[const_trait]
pub trait AtomicConstNew: Atomic {
fn new(v: Self::Primitive) -> Self;
}
pub trait AtomicAdd<T = <Self as Atomic>::Primitive>: Atomic {
fn fetch_add(&self, val: T, order: Ordering) -> Self::Primitive;
}
pub trait AtomicSub<T = <Self as Atomic>::Primitive>: Atomic {
fn fetch_sub(&self, val: T, order: Ordering) -> Self::Primitive;
}
pub trait AtomicBitAnd<T = <Self as Atomic>::Primitive>: Atomic {
fn fetch_and(&self, val: T, order: Ordering) -> Self::Primitive;
fn fetch_nand(&self, val: T, order: Ordering) -> Self::Primitive;
}
pub trait AtomicBitOr<T = <Self as Atomic>::Primitive>: Atomic {
fn fetch_or(&self, val: T, order: Ordering) -> Self::Primitive;
}
pub trait AtomicBitXor<T = <Self as Atomic>::Primitive>: Atomic {
fn fetch_xor(&self, val: T, order: Ordering) -> Self::Primitive;
}
pub trait AtomicMin<T = <Self as Atomic>::Primitive>: Atomic {
fn fetch_min(&self, val: T, order: Ordering) -> Self::Primitive;
}
pub trait AtomicMax<T = <Self as Atomic>::Primitive>: Atomic {
fn fetch_max(&self, val: T, order: Ordering) -> Self::Primitive;
}
pub trait HasAtomicInt: HasAtomic {
type AtomicInt: AtomicInt<Primitive = Self>;
}
pub trait AtomicNumOps<T = <Self as Atomic>::Primitive>:
Atomic + AtomicAdd<T> + AtomicSub<T>
{
}
pub trait AtomicBitOps<T = <Self as Atomic>::Primitive>:
Atomic + AtomicBitAnd<T> + AtomicBitOr<T> + AtomicBitXor<T>
{
}
pub trait AtomicOrd<T = <Self as Atomic>::Primitive>: Atomic + AtomicMin<T> + AtomicMax<T> {}
pub trait AtomicNum: AtomicNumOps + AtomicOrd {}
pub trait AtomicInt: AtomicNum + AtomicBitOps {}
impl<T: HasAtomic> HasAtomicInt for T
where
T::Atomic: AtomicInt<Primitive = T>,
{
type AtomicInt = <T as HasAtomic>::Atomic;
}
impl<T, U> AtomicNumOps<T> for U where U: Atomic + AtomicAdd<T> + AtomicSub<T> {}
impl<T, U> AtomicBitOps<T> for U where U: Atomic + AtomicBitAnd<T> + AtomicBitOr<T> + AtomicBitXor<T>
{}
impl<T, U> AtomicOrd<T> for U where U: Atomic + AtomicMin<T> + AtomicMax<T> {}
impl<T> AtomicNum for T where T: AtomicNumOps + AtomicOrd {}
impl<T> AtomicInt for T where T: AtomicNum + AtomicBitOps {}
macro_rules! impl_atomic {
($($len:literal: $prim:ty => $atomic:ty),+) => {
$(
#[docfg(target_has_atomic = $len)]
impl HasAtomic for $prim {
type Atomic = $atomic;
}
#[docfg(target_has_atomic = $len)]
unsafe impl Atomic for $atomic {
type Primitive = $prim;
#[inline]
fn new (v: Self::Primitive) -> Self {
<$atomic>::new(v)
}
#[inline]
fn get_mut (&mut self) -> &mut Self::Primitive {
<$atomic>::get_mut(self)
}
#[inline]
fn into_inner (self) -> Self::Primitive {
<$atomic>::into_inner(self)
}
#[inline]
fn load (&self, order: Ordering) -> Self::Primitive {
<$atomic>::load(self, order)
}
#[inline]
fn store (&self, val: Self::Primitive, order: Ordering) {
<$atomic>::store(self, val, order)
}
#[inline]
fn swap (&self, val: Self::Primitive, order: Ordering) -> Self::Primitive {
<$atomic>::swap(self, val, order)
}
#[inline]
fn compare_exchange (&self, current: Self::Primitive, new: Self::Primitive, success: Ordering, failure: Ordering) -> Result<Self::Primitive, Self::Primitive> {
<$atomic>::compare_exchange(self, current, new, success, failure)
}
#[inline]
fn compare_exchange_weak (&self, current: Self::Primitive, new: Self::Primitive, success: Ordering, failure: Ordering) -> Result<Self::Primitive, Self::Primitive> {
<$atomic>::compare_exchange_weak(self, current, new, success, failure)
}
#[inline]
fn fetch_update<F: FnMut(Self::Primitive) -> Option<Self::Primitive>> (&self, set_order: Ordering, fetch_ordering: Ordering, f: F) -> Result<Self::Primitive, Self::Primitive> {
<$atomic>::fetch_update(self, set_order, fetch_ordering, f)
}
}
cfg_if::cfg_if! {
if #[cfg(feature = "const")] {
#[cfg_attr(docsrs, doc(cfg(feature = "const")))]
impl const AtomicConstNew for $atomic {
#[inline]
fn new (v: Self::Primitive) -> Self {
<$atomic>::new(v)
}
}
}
}
)+
};
}
macro_rules! impl_int {
($($len:literal: ($int:ty, $uint:ty) => ($iatomic:ty, $uatomic:ty)),+) => {
$(
impl_int!($len: $int => $iatomic);
impl_int!($len: $uint => $uatomic);
)+
};
($($len:literal: $prim:ty => $atomic:ty),+) => {
$(
impl_atomic!($len: $prim => $atomic);
#[docfg(target_has_atomic = $len)]
impl AtomicAdd for $atomic {
#[inline]
fn fetch_add(&self, val: $prim, order: Ordering) -> $prim {
<$atomic>::fetch_add(self, val, order)
}
}
#[docfg(target_has_atomic = $len)]
impl AtomicSub for $atomic {
#[inline]
fn fetch_sub(&self, val: $prim, order: Ordering) -> $prim {
<$atomic>::fetch_sub(self, val, order)
}
}
#[docfg(target_has_atomic = $len)]
impl AtomicBitAnd for $atomic {
#[inline]
fn fetch_and(&self, val: $prim, order: Ordering) -> $prim {
<$atomic>::fetch_and(self, val, order)
}
#[inline]
fn fetch_nand(&self, val: $prim, order: Ordering) -> $prim {
<$atomic>::fetch_nand(self, val, order)
}
}
#[docfg(target_has_atomic = $len)]
impl AtomicBitOr for $atomic {
#[inline]
fn fetch_or(&self, val: $prim, order: Ordering) -> $prim {
<$atomic>::fetch_or(self, val, order)
}
}
#[docfg(target_has_atomic = $len)]
impl AtomicBitXor for $atomic {
#[inline]
fn fetch_xor(&self, val: $prim, order: Ordering) -> $prim {
<$atomic>::fetch_xor(self, val, order)
}
}
#[docfg(target_has_atomic = $len)]
impl AtomicMin for $atomic {
#[inline]
fn fetch_min(&self, val: $prim, order: Ordering) -> $prim {
<$atomic>::fetch_min(self, val, order)
}
}
#[docfg(target_has_atomic = $len)]
impl AtomicMax for $atomic {
#[inline]
fn fetch_max(&self, val: $prim, order: Ordering) -> $prim {
<$atomic>::fetch_max(self, val, order)
}
}
)+
};
}
impl_int! {
"8": (u8, i8) => (core::sync::atomic::AtomicU8, core::sync::atomic::AtomicI8),
"16": (u16, i16) => (core::sync::atomic::AtomicU16, core::sync::atomic::AtomicI16),
"32": (u32, i32) => (core::sync::atomic::AtomicU32, core::sync::atomic::AtomicI32),
"64": (u64, i64) => (core::sync::atomic::AtomicU64, core::sync::atomic::AtomicI64),
"ptr": (usize, isize) => (core::sync::atomic::AtomicUsize, core::sync::atomic::AtomicIsize)
}
impl_atomic! {
"8": bool => core::sync::atomic::AtomicBool
}
#[docfg(target_has_atomic = "ptr")]
impl<T> HasAtomic for *mut T {
type Atomic = core::sync::atomic::AtomicPtr<T>;
}
#[docfg(target_has_atomic = "ptr")]
unsafe impl<T> Atomic for core::sync::atomic::AtomicPtr<T> {
type Primitive = *mut T;
#[inline]
fn new(v: Self::Primitive) -> Self {
core::sync::atomic::AtomicPtr::new(v)
}
#[inline]
fn get_mut(&mut self) -> &mut Self::Primitive {
core::sync::atomic::AtomicPtr::get_mut(self)
}
#[inline]
fn into_inner(self) -> Self::Primitive {
core::sync::atomic::AtomicPtr::into_inner(self)
}
#[inline]
fn load(&self, order: Ordering) -> Self::Primitive {
core::sync::atomic::AtomicPtr::load(self, order)
}
#[inline]
fn store(&self, val: Self::Primitive, order: Ordering) {
core::sync::atomic::AtomicPtr::store(self, val, order)
}
#[inline]
fn swap(&self, val: Self::Primitive, order: Ordering) -> Self::Primitive {
core::sync::atomic::AtomicPtr::swap(self, val, order)
}
#[inline]
fn compare_exchange(
&self,
current: Self::Primitive,
new: Self::Primitive,
success: Ordering,
failure: Ordering,
) -> Result<Self::Primitive, Self::Primitive> {
core::sync::atomic::AtomicPtr::compare_exchange(self, current, new, success, failure)
}
#[inline]
fn compare_exchange_weak(
&self,
current: Self::Primitive,
new: Self::Primitive,
success: Ordering,
failure: Ordering,
) -> Result<Self::Primitive, Self::Primitive> {
core::sync::atomic::AtomicPtr::compare_exchange_weak(self, current, new, success, failure)
}
#[inline]
fn fetch_update<F: FnMut(Self::Primitive) -> Option<Self::Primitive>>(
&self,
set_order: Ordering,
fetch_ordering: Ordering,
f: F,
) -> Result<Self::Primitive, Self::Primitive> {
core::sync::atomic::AtomicPtr::fetch_update(self, set_order, fetch_ordering, f)
}
}