use crate::Digestible;
use core::sync::atomic::Ordering;
#[doc(hidden)]
pub trait AtomicType {
type TargetType: Digestible;
fn load(&self, order: Ordering) -> Self::TargetType;
}
impl<'a, T: AtomicType> AtomicType for &'a T {
type TargetType = T::TargetType;
fn load(&self, order: Ordering) -> Self::TargetType {
(**self).load(order)
}
}
#[cfg(feature = "alloc")]
mod has_alloc {
use crate::digest_with::atomics::AtomicType;
use alloc::boxed::Box;
use alloc::rc::Rc;
use alloc::sync::Arc;
use core::sync::atomic::Ordering;
impl<T: AtomicType> AtomicType for Arc<T> {
type TargetType = T::TargetType;
fn load(&self, order: Ordering) -> Self::TargetType {
self.as_ref().load(order)
}
}
impl<T: AtomicType> AtomicType for Rc<T> {
type TargetType = T::TargetType;
fn load(&self, order: Ordering) -> Self::TargetType {
self.as_ref().load(order)
}
}
impl<T: AtomicType> AtomicType for Box<T> {
type TargetType = T::TargetType;
fn load(&self, order: Ordering) -> Self::TargetType {
self.as_ref().load(order)
}
}
}
macro_rules! digestible_atomic {
($(($atomic:ty, $target:ty)),*) =>{
$(
impl AtomicType for $atomic{
type TargetType = $target;
fn load(&self, ordering: Ordering) -> Self::TargetType {
self.load(ordering)
}
}
)*
};
}
digestible_atomic!(
(core::sync::atomic::AtomicBool, bool),
(core::sync::atomic::AtomicU8, u8),
(core::sync::atomic::AtomicU16, u16),
(core::sync::atomic::AtomicU32, u32),
(core::sync::atomic::AtomicU64, u64),
(core::sync::atomic::AtomicI8, i8),
(core::sync::atomic::AtomicI16, i16),
(core::sync::atomic::AtomicI32, i32),
(core::sync::atomic::AtomicI64, i64),
(core::sync::atomic::AtomicUsize, usize),
(core::sync::atomic::AtomicIsize, isize)
);
macro_rules! digest_with {
(
$ordering:path,
$name:ident
) => {
#[doc = concat!("Loads the Digestible Data from the Atomic. Using Ordering [", stringify!($ordering), "](core::sync::atomic::",stringify!($ordering),")")]
#[doc = "\n\n AtomicType is implemented for all Atomic Types except AtomicPtr"]
#[inline(always)]
pub fn $name<B: byteorder::ByteOrder, W: crate::DigestWriter>(atomic: &impl AtomicType, writer: &mut W) {
atomic.load($ordering).digest::<B, W>(writer);
}
};
($(($ordering:path, $name:ident)),*) => {
$(
digest_with!($ordering, $name);
)*
};
}
digest_with!(
(Ordering::Relaxed, digest_relaxed),
(Ordering::Acquire, digest_acquire),
(Ordering::SeqCst, digest_seq_cst)
);