1pub use wgpu_sync::atomic::{AtomicU64, Ordering};
8
9use core::num::NonZeroU64;
10
11static NEXT_ID: AtomicU64 = AtomicU64::new(1);
12
13#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
14pub struct Identifier {
15 inner: NonZeroU64,
16}
17
18impl Identifier {
19 pub fn create() -> Self {
20 let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
21 let inner = unsafe { NonZeroU64::new_unchecked(id) };
23 Self { inner }
24 }
25}
26
27macro_rules! impl_eq_ord_hash_proxy {
33 ($type:ty => $($access:tt)*) => {
34 impl PartialEq for $type {
35 fn eq(&self, other: &Self) -> bool {
36 self $($access)* == other $($access)*
37 }
38 }
39
40 impl Eq for $type {}
41
42 impl PartialOrd for $type {
43 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
44 Some(self.cmp(other))
45 }
46 }
47
48 impl Ord for $type {
49 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
50 self $($access)*.cmp(&other $($access)*)
51 }
52 }
53
54 impl core::hash::Hash for $type {
55 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
56 self $($access)*.hash(state)
57 }
58 }
59 };
60}
61
62#[cfg_attr(not(any(wgpu_core, custom)), expect(unused_macros))]
68macro_rules! impl_eq_ord_hash_arc_address {
69 ($type:ty => $($access:tt)*) => {
70 impl PartialEq for $type {
71 fn eq(&self, other: &Self) -> bool {
72 let address_left = alloc::sync::Arc::as_ptr(&self $($access)*);
73 let address_right = alloc::sync::Arc::as_ptr(&other $($access)*);
74
75 address_left == address_right
76 }
77 }
78
79 impl Eq for $type {}
80
81 impl PartialOrd for $type {
82 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
83 Some(self.cmp(other))
84 }
85 }
86
87 impl Ord for $type {
88 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
89 let address_left = alloc::sync::Arc::as_ptr(&self $($access)*);
90 let address_right = alloc::sync::Arc::as_ptr(&other $($access)*);
91
92 address_left.cmp(&address_right)
93 }
94 }
95
96 impl core::hash::Hash for $type {
97 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
98 let address = alloc::sync::Arc::as_ptr(&self $($access)*);
99 address.hash(state)
100 }
101 }
102 };
103}
104
105#[cfg_attr(not(any(wgpu_core, custom)), expect(unused_macros))]
111macro_rules! impl_eq_ord_hash_box_address {
112 ($type:ty => $($access:tt)*) => {
113 impl PartialEq for $type {
114 fn eq(&self, other: &Self) -> bool {
115 let address_left: *const _ = &self $($access)*;
116 let address_right: *const _ = &other $($access)*;
117
118 address_left == address_right
119 }
120 }
121
122 impl Eq for $type {}
123
124 impl PartialOrd for $type {
125 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
126 Some(self.cmp(other))
127 }
128 }
129
130 impl Ord for $type {
131 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
132 let address_left: *const _ = &self $($access)*;
133 let address_right: *const _ = &other $($access)*;
134
135 address_left.cmp(&address_right)
136 }
137 }
138
139 impl core::hash::Hash for $type {
140 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
141 let address: *const _ = &self $($access)*;
142 address.hash(state)
143 }
144 }
145 };
146}
147
148#[cfg_attr(not(any(wgpu_core, custom)), expect(unused_imports))]
149pub(crate) use {
150 impl_eq_ord_hash_arc_address, impl_eq_ord_hash_box_address, impl_eq_ord_hash_proxy,
151};