1use {IdRange, IntegerHandle, Identifier, FromUsize, ToUsize};
2use core::marker::PhantomData;
3use core::fmt;
4use core::ops::{Add, Sub};
5use core::hash::{Hash, Hasher};
6use num_traits::One;
7
8#[repr(C)]
9pub struct Id<Tag, Handle = u32> {
10 pub handle: Handle,
11 pub _marker: PhantomData<Tag>,
12}
13
14impl<T, H: fmt::Display> fmt::Debug for Id<T, H> {
15 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
16 write!(f, "Id#{}", self.handle)
17 }
18}
19
20impl<T, H: Copy> Copy for Id<T, H> {}
21
22impl<T, H: Copy> Clone for Id<T, H> {
23 #[inline]
24 fn clone(&self) -> Id<T, H> {
25 *self
26 }
27}
28
29impl<T, H: PartialEq> PartialEq for Id<T, H> {
30 #[inline]
31 fn eq(&self, other: &Id<T, H>) -> bool {
32 self.handle.eq(&other.handle)
33 }
34}
35
36impl<T, H: Copy + Eq> Eq for Id<T, H> {}
37
38impl<T, H: IntegerHandle> Id<T, H> {
39 #[inline]
40 pub fn new(idx: H) -> Id<T, H> {
41 Id {
42 handle: idx,
43 _marker: PhantomData,
44 }
45 }
46
47 #[inline]
48 pub fn as_range(&self) -> IdRange<T, H> {
49 IdRange::new(self.handle..self.handle + One::one())
50 }
51}
52
53impl<T, H: IntegerHandle> Identifier for Id<T, H> {
54 type Handle = H;
55 type Tag = T;
56}
57
58impl<T, H: ToUsize> ToUsize for Id<T, H> {
59 #[inline]
60 fn to_usize(&self) -> usize {
61 self.handle.to_usize()
62 }
63}
64
65impl<T, H: IntegerHandle> FromUsize for Id<T, H> {
66 #[inline]
67 fn from_usize(idx: usize) -> Id<T, H> {
68 Id::new(FromUsize::from_usize(idx))
69 }
70}
71
72impl<T, Handle: Hash> Hash for Id<T, Handle> {
73 #[inline]
74 fn hash<H: Hasher>(&self, state: &mut H) {
75 self.handle.hash(state);
76 }
77}
78
79impl<T, Handle: IntegerHandle> Add<Handle> for Id<T, Handle> {
80 type Output = Self;
81 #[inline]
82 fn add(self, offset: Handle) -> Self {
83 Id::new(self.handle + offset)
84 }
85}
86
87impl<T, Handle: IntegerHandle> Sub<Handle> for Id<T, Handle> {
88 type Output = Self;
89 #[inline]
90 fn sub(self, offset: Handle) -> Self {
91 Id::new(self.handle - offset)
92 }
93}