1#[cfg(supports_64bit_atomics)]
8pub use core::sync::atomic::AtomicU64;
9#[cfg(not(supports_64bit_atomics))]
10pub use portable_atomic::AtomicU64;
11
12use core::{num::NonZeroU64, sync::atomic::Ordering};
13
14static NEXT_ID: AtomicU64 = AtomicU64::new(1);
15
16#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
17pub struct Identifier {
18 inner: NonZeroU64,
19}
20
21impl Identifier {
22 pub fn create() -> Self {
23 let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
24 let inner = unsafe { NonZeroU64::new_unchecked(id) };
26 Self { inner }
27 }
28}
29
30macro_rules! impl_eq_ord_hash_proxy {
36 ($type:ty => $($access:tt)*) => {
37 impl PartialEq for $type {
38 fn eq(&self, other: &Self) -> bool {
39 self $($access)* == other $($access)*
40 }
41 }
42
43 impl Eq for $type {}
44
45 impl PartialOrd for $type {
46 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
47 Some(self.cmp(other))
48 }
49 }
50
51 impl Ord for $type {
52 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
53 self $($access)*.cmp(&other $($access)*)
54 }
55 }
56
57 impl core::hash::Hash for $type {
58 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
59 self $($access)*.hash(state)
60 }
61 }
62 };
63}
64
65#[cfg_attr(not(any(wgpu_core, custom)), expect(unused_macros))]
71macro_rules! impl_eq_ord_hash_arc_address {
72 ($type:ty => $($access:tt)*) => {
73 impl PartialEq for $type {
74 fn eq(&self, other: &Self) -> bool {
75 let address_left = alloc::sync::Arc::as_ptr(&self $($access)*);
76 let address_right = alloc::sync::Arc::as_ptr(&other $($access)*);
77
78 address_left == address_right
79 }
80 }
81
82 impl Eq for $type {}
83
84 impl PartialOrd for $type {
85 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
86 Some(self.cmp(other))
87 }
88 }
89
90 impl Ord for $type {
91 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
92 let address_left = alloc::sync::Arc::as_ptr(&self $($access)*);
93 let address_right = alloc::sync::Arc::as_ptr(&other $($access)*);
94
95 address_left.cmp(&address_right)
96 }
97 }
98
99 impl core::hash::Hash for $type {
100 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
101 let address = alloc::sync::Arc::as_ptr(&self $($access)*);
102 address.hash(state)
103 }
104 }
105 };
106}
107
108#[cfg_attr(not(any(wgpu_core, custom)), expect(unused_imports))]
109pub(crate) use {impl_eq_ord_hash_arc_address, impl_eq_ord_hash_proxy};