I have the problem that Atomic seems not to provide a trait interface for its methods.
I don't know hot to specify the type that matches all Atomic types.
for example here T should be Atomic:
thank you for the answer. atomic-traits looks good. but it doesn't implement the trait for AtomicF32 of the AtomicFloat crate. Is it possible to extend atomic-traits?
It looks like you can implement atomic_traits::Atomic for the AtomicF32 and AtomicF64, but I haven't tried it.
Oh, wait, that would violate the orphan rules. So the best thing would be to convince the owner of one of those crates to implement the trait, under a feature flag. Or you could try to contribute that change to one of the crates.
One workaround for the orphan rules is to create newtypes (wrapper structs) for AtomicF32 and AtomicF64 that implement the Atomic trait. The wrappers can also implement Deref to make them easier to use. Here's a quick partial example.
use std::sync::atomic::Ordering;
use atomic_traits::Atomic;
struct AtomicF32(atomic_float::AtomicF32);
impl Deref for AtomicF32 {
type Target = atomic_float::AtomicF32;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Atomic for AtomicF32 {
type Type = f32;
fn new(v: Self::Type) -> Self {
AtomicF32(atomic_float::AtomicF32::new(v))
}
fn swap(
&self,
val: Self::Type,
order: std::sync::atomic::Ordering,
) -> Self::Type {
self.0.swap(val, order)
}
// TODO: implement the rest of the interface methods...
}
// Now you can use AtomicF32 as a generic
fn f<T, A: Atomic<Type = T>>(a: &A, v: T) -> T {
a.swap(v, Ordering::Relaxed)
}
let a = AtomicF32::new(1.23);
let v = f(&a, 2.34);
assert_eq!(v, 1.23);
The rational of the orphan rules in particular is to balance what both upstream and downstream can implement, to minimize the cases of new implementations being a major breaking change (by causing multiple implementations of the same trait for the same type).
For example, if you could write the suggested implementation, then I could write the implementation. If both of our crates ended up as dependencies in some third project, there were be overlapping implementations. One of the goals is to make this "incompatible crates due to coherence" situation impossible.