Skip to main content

common_traits/
same_as.rs

1use core::sync::atomic::{
2    AtomicBool, AtomicI8, AtomicI16, AtomicI32, AtomicI64, AtomicIsize, AtomicU8, AtomicU16,
3    AtomicU32, AtomicU64, AtomicUsize,
4};
5
6use crate::{AtomicF32, AtomicF64, IntoAtomic};
7
8/// Unsafe marker trait for types whose atomic version has the same size and bit
9/// representation.
10///
11/// This marker guarantees that a value can be reinterpreted between the
12/// non-atomic type and its associated atomic type
13/// [`IntoAtomic::AtomicType`] by copying the bytes. Note that it does **not**
14/// guarantee equal *alignment*: on some targets an atomic type has a stricter
15/// alignment than its non-atomic counterpart (for example, on 32-bit x86
16/// `align_of::<u64>() == 4` but `align_of::<AtomicU64>() == 8`), which is why the
17/// by-reference conversions in [`IntoAtomic`]/[`Atomic`](crate::Atomic) check
18/// alignment at run time.
19///
20/// It is implemented for all primitive types and for the types of the
21/// [`half`] crate if the corresponding gate feature is enabled.
22///
23/// [`half`]: https://crates.io/crates/half
24///
25/// # Safety
26///
27/// The implementor must ensure that `T` has the same size and bit representation
28/// as the associated atomic type [`IntoAtomic::AtomicType`].
29pub unsafe trait SameAs<T>: IntoAtomic<AtomicType = T> {}
30
31unsafe impl SameAs<AtomicU8> for u8 {}
32unsafe impl SameAs<AtomicU16> for u16 {}
33unsafe impl SameAs<AtomicU32> for u32 {}
34unsafe impl SameAs<AtomicU64> for u64 {}
35unsafe impl SameAs<AtomicUsize> for usize {}
36
37unsafe impl SameAs<AtomicI8> for i8 {}
38unsafe impl SameAs<AtomicI16> for i16 {}
39unsafe impl SameAs<AtomicI32> for i32 {}
40unsafe impl SameAs<AtomicI64> for i64 {}
41unsafe impl SameAs<AtomicIsize> for isize {}
42
43unsafe impl SameAs<AtomicBool> for bool {}
44
45unsafe impl SameAs<AtomicF32> for f32 {}
46unsafe impl SameAs<AtomicF64> for f64 {}
47
48#[cfg(feature = "half")]
49mod half_same_as {
50    use crate::{AtomicBF16, AtomicF16};
51
52    use super::*;
53    use half::{bf16, f16};
54
55    unsafe impl SameAs<AtomicF16> for f16 {}
56    unsafe impl SameAs<AtomicBF16> for bf16 {}
57}
58
59#[cfg(all(feature = "nightly_f16", not(feature = "half")))]
60mod nightly_f16_same_as {
61    use super::*;
62    use crate::AtomicF16;
63
64    unsafe impl SameAs<AtomicF16> for f16 {}
65}