1use std::{
3 fmt::{self, Debug},
4 hash::Hash,
5 marker::PhantomData,
6 ops,
7};
8
9#[cfg(test)]
10mod tests;
11
12pub trait NumericId: Copy + Clone + PartialEq + Eq + PartialOrd + Ord + Hash + Send + Sync {
14 type Rep;
15 type Atomic;
16 fn new(val: Self::Rep) -> Self;
17 fn from_usize(index: usize) -> Self;
18 fn index(self) -> usize;
19 fn rep(self) -> Self::Rep;
20 fn inc(self) -> Self {
21 Self::from_usize(self.index() + 1)
22 }
23}
24
25impl NumericId for usize {
26 type Rep = usize;
27 type Atomic = std::sync::atomic::AtomicUsize;
28 fn new(val: usize) -> Self {
29 val
30 }
31 fn from_usize(index: usize) -> Self {
32 index
33 }
34
35 fn rep(self) -> usize {
36 self
37 }
38
39 fn index(self) -> usize {
40 self
41 }
42}
43
44#[derive(Clone, PartialEq, Eq, Hash)]
49pub struct DenseIdMap<K, V> {
50 data: Vec<Option<V>>,
51 _marker: PhantomData<K>,
52}
53
54impl<K: NumericId + Debug, V: Debug> Debug for DenseIdMap<K, V> {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 let mut map = f.debug_map();
57 for (k, v) in self.iter() {
58 map.entry(&k, v);
59 }
60 map.finish()
61 }
62}
63
64impl<K, V> Default for DenseIdMap<K, V> {
65 fn default() -> Self {
66 Self {
67 data: Vec::new(),
68 _marker: PhantomData,
69 }
70 }
71}
72
73impl<K: NumericId, V> DenseIdMap<K, V> {
74 pub fn with_capacity(n: usize) -> Self {
76 let mut res = Self::new();
77 res.reserve_space(K::from_usize(n.saturating_sub(1)));
78 res
79 }
80
81 pub fn new() -> Self {
83 Self::default()
84 }
85
86 pub fn clear(&mut self) {
88 self.data.clear();
89 }
90
91 pub fn capacity(&self) -> usize {
93 self.data.capacity()
94 }
95
96 pub fn n_ids(&self) -> usize {
99 self.data.len()
100 }
101
102 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
104 self.reserve_space(key);
105 self.data[key.index()].replace(value)
106 }
107
108 pub fn next_id(&self) -> K {
110 K::from_usize(self.data.len())
111 }
112
113 pub fn push(&mut self, val: V) -> K {
116 let res = self.next_id();
117 self.data.push(Some(val));
118 res
119 }
120
121 pub fn contains_key(&self, key: K) -> bool {
123 self.data.get(key.index()).is_some_and(Option::is_some)
124 }
125
126 pub fn get(&self, key: K) -> Option<&V> {
128 self.data.get(key.index())?.as_ref()
129 }
130
131 pub fn get_mut(&mut self, key: K) -> Option<&mut V> {
133 self.reserve_space(key);
134 self.data.get_mut(key.index())?.as_mut()
135 }
136
137 pub fn unwrap_val(&mut self, key: K) -> V {
142 self.reserve_space(key);
143 self.data.get_mut(key.index()).unwrap().take().unwrap()
144 }
145
146 pub fn take(&mut self, key: K) -> Option<V> {
148 self.reserve_space(key);
149 self.data.get_mut(key.index()).unwrap().take()
150 }
151
152 pub fn get_or_insert(&mut self, key: K, f: impl FnOnce() -> V) -> &mut V {
155 self.reserve_space(key);
156 self.data[key.index()].get_or_insert_with(f)
157 }
158
159 pub fn raw(&self) -> &[Option<V>] {
160 &self.data
161 }
162
163 pub fn raw_mut(&mut self) -> &mut [Option<V>] {
164 &mut self.data
165 }
166
167 pub fn iter(&self) -> impl Iterator<Item = (K, &V)> {
168 self.data
169 .iter()
170 .enumerate()
171 .filter_map(|(i, v)| Some((K::from_usize(i), v.as_ref()?)))
172 }
173
174 pub fn iter_mut(&mut self) -> impl Iterator<Item = (K, &mut V)> {
175 self.data
176 .iter_mut()
177 .enumerate()
178 .filter_map(|(i, v)| Some((K::from_usize(i), v.as_mut()?)))
179 }
180
181 #[allow(clippy::should_implement_trait)]
182 pub fn into_iter(self) -> impl Iterator<Item = (K, V)> {
183 self.data
184 .into_iter()
185 .enumerate()
186 .filter_map(|(i, v)| Some((K::from_usize(i), v?)))
187 }
188
189 pub fn reserve_space(&mut self, key: K) {
191 let index = key.index();
192 if index >= self.data.len() {
193 self.data.resize_with(index + 1, || None);
194 }
195 }
196
197 pub fn drain(&mut self) -> impl Iterator<Item = (K, V)> + '_ {
198 self.data
200 .drain(..)
201 .enumerate()
202 .filter_map(|(i, v)| Some((K::from_usize(i), v?)))
203 }
204
205 pub fn retain(&mut self, mut f: impl FnMut(K, &V) -> bool) {
206 for (i, v) in self.data.iter_mut().enumerate() {
207 if let Some(inner) = v
208 && !f(K::from_usize(i), inner)
209 {
210 *v = None;
211 }
212 }
213 }
214
215 pub fn len(&self) -> usize {
216 self.data.iter().filter(|v| v.is_some()).count()
217 }
218
219 pub fn is_empty(&self) -> bool {
220 self.data.iter().all(|v| v.is_none())
221 }
222}
223
224impl<K: NumericId, V> ops::Index<K> for DenseIdMap<K, V> {
225 type Output = V;
226
227 fn index(&self, key: K) -> &Self::Output {
228 self.get(key).unwrap()
229 }
230}
231
232impl<K: NumericId, V> ops::IndexMut<K> for DenseIdMap<K, V> {
233 fn index_mut(&mut self, key: K) -> &mut Self::Output {
234 self.get_mut(key).unwrap()
235 }
236}
237
238impl<K: NumericId, V: Default> DenseIdMap<K, V> {
239 pub fn get_or_default(&mut self, key: K) -> &mut V {
240 self.get_or_insert(key, V::default)
241 }
242}
243
244impl<K: NumericId, V: Clone> FromIterator<(K, V)> for DenseIdMap<K, V> {
245 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
246 let mut res = DenseIdMap::new();
247 for (k, v) in iter {
248 res.insert(k, v);
249 }
250 res
251 }
252}
253
254#[derive(Debug)]
255pub struct IdVec<K, V> {
256 data: Vec<V>,
257 _marker: std::marker::PhantomData<K>,
258}
259
260impl<K, V> IdVec<K, V> {
261 pub fn clear(&mut self) {
262 self.data.clear();
263 }
264 pub fn len(&self) -> usize {
265 self.data.len()
266 }
267 pub fn capacity(&self) -> usize {
268 self.data.capacity()
269 }
270}
271
272impl<K, V> Default for IdVec<K, V> {
273 fn default() -> IdVec<K, V> {
274 IdVec {
275 data: Default::default(),
276 _marker: std::marker::PhantomData,
277 }
278 }
279}
280
281impl<K, V: Clone> Clone for IdVec<K, V> {
282 fn clone(&self) -> Self {
283 IdVec {
284 data: self.data.clone(),
285 _marker: std::marker::PhantomData,
286 }
287 }
288}
289
290#[derive(Clone)]
292pub struct DenseIdMapWithReuse<K, V> {
293 data: DenseIdMap<K, V>,
294 free: Vec<K>,
295}
296
297impl<K, V> Default for DenseIdMapWithReuse<K, V> {
298 fn default() -> Self {
299 Self {
300 data: Default::default(),
301 free: Default::default(),
302 }
303 }
304}
305
306impl<K: NumericId, V> DenseIdMapWithReuse<K, V> {
307 pub fn reserve_slot(&mut self) -> K {
309 match self.free.pop() {
310 Some(res) => res,
311 None => {
312 let res = self.data.next_id();
313 self.data.reserve_space(res);
314 res
315 }
316 }
317 }
318
319 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
324 self.data.insert(key, value)
325 }
326
327 pub fn push(&mut self, value: V) -> K {
329 let res = self.reserve_slot();
330 self.insert(res, value);
331 res
332 }
333
334 pub fn take(&mut self, id: K) -> Option<V> {
336 let res = self.data.take(id);
337 if res.is_some() {
338 self.free.push(id);
339 }
340 res
341 }
342}
343
344impl<K: NumericId, V> std::ops::Index<K> for DenseIdMapWithReuse<K, V> {
345 type Output = V;
346 fn index(&self, key: K) -> &V {
347 &self.data[key]
348 }
349}
350
351impl<K: NumericId, V> std::ops::IndexMut<K> for DenseIdMapWithReuse<K, V> {
352 fn index_mut(&mut self, key: K) -> &mut V {
353 &mut self.data[key]
354 }
355}
356
357impl<K: NumericId, V> IdVec<K, V> {
358 pub fn with_capacity(cap: usize) -> IdVec<K, V> {
359 IdVec {
360 data: Vec::with_capacity(cap),
361 _marker: std::marker::PhantomData,
362 }
363 }
364
365 pub fn push(&mut self, elt: V) -> K {
366 let res = K::from_usize(self.data.len());
367 self.data.push(elt);
368 res
369 }
370
371 pub fn resize_with(&mut self, size: usize, init: impl FnMut() -> V) {
372 self.data.resize_with(size, init)
373 }
374
375 pub fn is_empty(&self) -> bool {
376 self.data.is_empty()
377 }
378
379 pub fn values(&self) -> impl Iterator<Item = &V> {
380 self.data.iter()
381 }
382
383 pub fn iter(&self) -> impl Iterator<Item = (K, &V)> {
384 self.data
385 .iter()
386 .enumerate()
387 .map(|(i, v)| (K::from_usize(i), v))
388 }
389 pub fn iter_mut(&mut self) -> impl Iterator<Item = (K, &mut V)> {
390 self.data
391 .iter_mut()
392 .enumerate()
393 .map(|(i, v)| (K::from_usize(i), v))
394 }
395 pub fn drain(&mut self) -> impl Iterator<Item = (K, V)> + '_ {
396 self.data
397 .drain(..)
398 .enumerate()
399 .map(|(i, v)| (K::from_usize(i), v))
400 }
401 pub fn get(&self, key: K) -> Option<&V> {
402 self.data.get(key.index())
403 }
404
405 pub fn as_mut_slice(&mut self) -> &mut [V] {
406 &mut self.data
407 }
408}
409
410impl<K: NumericId, V> ops::Index<K> for IdVec<K, V> {
411 type Output = V;
412
413 fn index(&self, key: K) -> &Self::Output {
414 &self.data[key.index()]
415 }
416}
417
418impl<K: NumericId, V> ops::IndexMut<K> for IdVec<K, V> {
419 fn index_mut(&mut self, key: K) -> &mut Self::Output {
420 &mut self.data[key.index()]
421 }
422}
423
424#[macro_export]
425#[doc(hidden)]
426macro_rules! atomic_of {
427 (usize) => {
428 std::sync::atomic::AtomicUsize
429 };
430 (u8) => {
431 std::sync::atomic::AtomicU8
432 };
433 (u16) => {
434 std::sync::atomic::AtomicU16
435 };
436 (u32) => {
437 std::sync::atomic::AtomicU32
438 };
439 (u64) => {
440 std::sync::atomic::AtomicU64
441 };
442}
443
444#[macro_export]
445macro_rules! define_id {
446 ($v:vis $name:ident, $repr:tt) => { define_id!($v $name, $repr, "", pretty ""); };
447 ($v:vis $name:ident, $repr:tt, $doc:tt) => { define_id!($v $name, $repr, $doc, pretty ""); };
448 ($v:vis $name:ident, $repr:tt, pretty $pretty_name:expr) => { define_id!($v $name, $repr, "", pretty $pretty_name); };
449 ($v:vis $name:ident, $repr:tt, $doc:tt, pretty $pretty_name:tt) => {
450 #[derive(Copy, Clone)]
451 #[doc = $doc]
452 $v struct $name {
453 rep: $repr,
454 }
455
456 impl PartialEq for $name {
457 fn eq(&self, other: &Self) -> bool {
458 self.rep == other.rep
459 }
460 }
461
462 impl Eq for $name {}
463
464 impl PartialOrd for $name {
465 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
466 Some(self.cmp(other))
467 }
468 }
469
470 impl Ord for $name {
471 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
472 self.rep.cmp(&other.rep)
473 }
474 }
475
476 impl std::hash::Hash for $name {
477 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
478 self.rep.hash(state);
479 }
480 }
481
482 impl $name {
483 #[allow(unused)]
484 $v const fn new_const(id: $repr) -> Self {
485 $name {
486 rep: id,
487 }
488 }
489
490 #[allow(unused)]
491 $v fn range(low: Self, high: Self) -> impl Iterator<Item = Self> {
492 use $crate::NumericId;
493 (low.rep..high.rep).map(|i| $name::new(i))
494 }
495
496 }
497
498 impl $crate::NumericId for $name {
499 type Rep = $repr;
500 type Atomic = $crate::atomic_of!($repr);
501 fn new(id: $repr) -> Self {
502 Self::new_const(id)
503 }
504 fn from_usize(index: usize) -> Self {
505 assert!(<$repr>::MAX as usize >= index,
506 "overflowing id type {} (represented as {}) with index {}", stringify!($name), stringify!($repr), index);
507 $name::new(index as $repr)
508 }
509 fn index(self) -> usize {
511 self.rep as usize
512 }
513 fn rep(self) -> $repr {
515 self.rep
516 }
517 }
518
519 impl std::fmt::Debug for $name {
520 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
521 let name = if $pretty_name.is_empty() {
522 stringify!($name).to_string()
523 } else {
524 $pretty_name.to_string()
525 };
526 write!(fmt, "{}({:?})", name, self.rep)
527 }
528 }
529 };
530}