1#[macro_export]
6macro_rules! define_atomic_id {
7 ($atomic_id_type:ident) => {
8 #[derive(::core::marker::Copy, ::core::clone::Clone, ::core::hash::Hash, ::core::cmp::Eq, ::core::cmp::PartialEq, ::core::cmp::PartialOrd, ::core::cmp::Ord, ::core::fmt::Debug)]
13 pub struct $atomic_id_type(::core::num::NonZero<u32>);
14
15 impl $atomic_id_type {
16 #[expect(
18 clippy::new_without_default,
19 reason = "Implementing the `Default` trait on atomic IDs would imply that two `<AtomicIdType>::default()` equal each other. By only implementing `new()`, we indicate that each atomic ID created will be unique."
20 )]
21 pub fn new() -> Self {
22 use ::core::sync::atomic::{AtomicU32, Ordering};
23
24 static COUNTER: AtomicU32 = AtomicU32::new(1);
25
26 let counter = COUNTER.fetch_add(1, Ordering::Relaxed);
27 Self(::core::num::NonZero::<u32>::new(counter).unwrap_or_else(|| {
28 ::core::panic!(
29 "The system ran out of unique `{}`s.",
30 ::core::stringify!($atomic_id_type)
31 );
32 }))
33 }
34 }
35
36 impl ::core::convert::From<$atomic_id_type> for ::core::num::NonZero<u32> {
37 fn from(value: $atomic_id_type) -> Self {
38 value.0
39 }
40 }
41
42 impl ::core::convert::From<::core::num::NonZero<u32>> for $atomic_id_type {
43 fn from(value: ::core::num::NonZero<u32>) -> Self {
44 Self(value)
45 }
46 }
47 };
48}