1use std::marker::PhantomData;
2use std::ops::Add;
3use std::hash::{ Hash, Hasher };
4
5mod id_vector;
6mod id_list;
7pub use id_vector::{ IdSlice, MutIdSlice, IdVec };
10pub use id_list::{ IdFreeList, NullId, NoneAsNullId };
11
12pub struct Id<Tag, Handle = u32> {
15 pub handle: Handle,
16 pub _marker: PhantomData<Tag>
17}
18
19impl<T, H: std::fmt::Display> std::fmt::Debug for Id<T, H> {
20 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
21 write!(f, "Id#{}", self.handle)
22 }
23}
24
25impl<T, H:Copy> Copy for Id<T, H> {}
26
27impl<T, H:Copy> Clone for Id<T, H> { fn clone(&self) -> Id<T, H> { *self } }
28
29impl<T, H:PartialEq> PartialEq for Id<T, H> {
30 fn eq(&self, other: &Id<T,H>) -> bool { self.handle.eq(&other.handle) }
31}
32
33impl<T, H:Copy+Eq> Eq for Id<T, H> {}
34
35impl<T, H:Copy> Id<T, H> {
36 pub fn new(idx: H) -> Id<T, H> { Id { handle: idx, _marker: PhantomData } }
37}
38
39impl<T, H:IntegerHandle> Identifier for Id<T, H> {
40 type Handle = H;
41 type Unit = T;
42}
43
44impl<T, H:ToIndex> ToIndex for Id<T, H> {
45 fn to_index(&self) -> usize { self.handle.to_index() }
46}
47
48impl<T, H:Copy+FromIndex> FromIndex for Id<T, H> {
49 fn from_index(idx: usize) -> Id<T, H> { Id::new(FromIndex::from_index(idx)) }
50}
51
52impl<T, Handle: Hash> Hash for Id<T, Handle> {
53 fn hash<H: Hasher>(&self, state: &mut H) {
54 self.handle.hash(state);
55 }
56}
57
58
59pub struct IdRange<T, H> {
62 pub first: Id<T, H>,
63 pub count: H,
64}
65
66impl<T, H: std::fmt::Display> std::fmt::Debug for IdRange<T, H> {
67 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
68 write!(f, "Id#[{}..{}]", self.first.handle, self.count)
69 }
70}
71
72impl<T, H:Copy> Copy for IdRange<T, H> {}
73
74impl<T, H:Copy> Clone for IdRange<T, H> { fn clone(&self) -> IdRange<T, H> { *self } }
75
76impl<T, H:PartialEq> PartialEq for IdRange<T, H> {
77 fn eq(&self, other: &IdRange<T,H>) -> bool { self.first.eq(&other.first) && self.count.eq(&other.count) }
78}
79
80impl<T, H:Copy+Eq> Eq for IdRange<T, H> {}
81
82impl<T, H:IntegerHandle> IdRange<T, H> {
83 pub fn new(first: H, count: H) -> IdRange<T, H> {
84 IdRange { first: Id::new(first), count: count }
85 }
86
87 pub fn len(self) -> usize { self.count.to_index() }
88
89 pub fn is_empty(self) -> bool { self.len() == 0 }
90
91 pub fn get(self, i: H) -> Id<T, H> {
92 debug_assert!(i < self.count);
93 return Id { handle: self.first.handle + i, _marker: PhantomData };
94 }
95
96 pub fn shrinked_left(self) -> Option<IdRange<T, H>> {
98 if self.is_empty() {
99 return None;
100 }
101 return Some(IdRange{
102 count: FromIndex::from_index(self.count.to_index() - 1),
103 first: FromIndex::from_index(self.first.to_index() + 1),
104 });
105 }
106
107 pub fn shrinked_right(self) -> Option<IdRange<T, H>> {
109 if self.is_empty() {
110 return None;
111 }
112 return Some(IdRange{
113 first: self.first,
114 count: FromIndex::from_index(self.count.to_index() - 1),
115 });
116 }
117}
118
119impl<T, H:IntegerHandle> Iterator for IdRange<T, H> {
120 type Item = Id<T, H>;
121 fn next(&mut self) -> Option<Id<T, H>> {
122 if self.count.to_index() == 0 {
123 return None;
124 }
125 let res = self.first;
126 self.count = FromIndex::from_index(self.count.to_index() - 1);
127 self.first = FromIndex::from_index(self.first.to_index() + 1);
128 return Some(res);
129 }
130
131 fn size_hint(&self) -> (usize, Option<usize>) {
132 return (self.count.to_index(), Some(self.count.to_index()));
133 }
134
135 fn count(self) -> usize { self.count.to_index() }
136}
137
138pub struct ReverseIdRange<T, H> {
139 range: IdRange<T, H>,
140}
141
142impl<T, H: std::fmt::Display> std::fmt::Debug for ReverseIdRange<T, H> {
143 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
144 write!(f, "ReverseId#[{}..{}]", self.range.first.handle, self.range.count)
145 }
146}
147
148impl<T, H:Copy> Copy for ReverseIdRange<T, H> {}
149
150impl<T, H:Copy> Clone for ReverseIdRange<T, H> { fn clone(&self) -> ReverseIdRange<T, H> { *self } }
151
152impl<T, H:PartialEq> PartialEq for ReverseIdRange<T, H> {
153 fn eq(&self, other: &ReverseIdRange<T,H>) -> bool { self.range.eq(&other.range) }
154}
155
156impl<T, H:Copy+Eq> Eq for ReverseIdRange<T, H> {}
157
158impl<T, H:IntegerHandle> ReverseIdRange<T, H> {
159
160 pub fn new(range: IdRange<T, H>) -> ReverseIdRange<T, H> { ReverseIdRange { range: range } }
161
162 pub fn len(&self) -> usize { self.range.len() }
163
164 pub fn is_empty(self) -> bool { self.len() == 0 }
165
166 pub fn get(self, i: H) -> Id<T, H> { self.range.get(i) }
167}
168
169impl<T, H:IntegerHandle> Iterator for ReverseIdRange<T, H> {
170 type Item = Id<T, H>;
171 fn next(&mut self) -> Option<Id<T, H>> {
172 if self.range.count.to_index() == 0 {
173 return None;
174 }
175 self.range.count = FromIndex::from_index(self.range.count.to_index() - 1);
176 return Some(FromIndex::from_index(self.range.first.to_index() + self.range.count.to_index()));
177 }
178
179 fn size_hint(&self) -> (usize, Option<usize>) {
180 self.range.size_hint()
181 }
182
183 fn count(self) -> usize { self.range.count() }
184}
185
186
187
188#[derive(Copy, Clone)]
192pub struct GenId<T, H:Copy, G> {
193 pub id: Id<T, H>,
194 pub gen: G,
195}
196
197impl<T, H: Copy+std::fmt::Display, G: std::fmt::Display> std::fmt::Debug for GenId<T, H, G> {
198 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
199 write!(f, "GenId#{}({})", self.id.handle, self.gen)
200 }
201}
202
203impl<T, H:IntegerHandle, G: PartialEq> PartialEq for GenId<T, H, G> {
204 fn eq(&self, other: &GenId<T, H, G>) -> bool { self.id == other.id && self.gen == other.gen }
205}
206
207impl<T, H:IntegerHandle, G> ToIndex for GenId<T, H, G> {
208 fn to_index(&self) -> usize { self.id.to_index() }
209}
210
211
212pub trait FromIndex { fn from_index(idx: usize) -> Self; }
215
216pub trait ToIndex { fn to_index(&self) -> usize; }
217
218pub trait Generation { fn get_gen(&self) -> u32; }
219
220pub trait IntegerHandle : Copy + Clone
221 + Add<Output=Self>
222 + PartialEq + PartialOrd
223 + FromIndex + ToIndex {}
224
225pub trait Identifier: Copy + FromIndex + ToIndex + PartialEq {
226 type Handle: IntegerHandle;
227 type Unit;
228}
229
230impl Identifier for u8 { type Handle = u8; type Unit = (); }
231impl Identifier for u16 { type Handle = u16; type Unit = (); }
232impl Identifier for u32 { type Handle = u32; type Unit = (); }
233impl Identifier for u64 { type Handle = u64; type Unit = (); }
234impl Identifier for i8 { type Handle = i8; type Unit = (); }
235impl Identifier for i16 { type Handle = i16; type Unit = (); }
236impl Identifier for i32 { type Handle = i32; type Unit = (); }
237impl Identifier for i64 { type Handle = i64; type Unit = (); }
238
239impl ToIndex for u8 { fn to_index(&self) -> usize { *self as usize } }
240impl ToIndex for u16 { fn to_index(&self) -> usize { *self as usize } }
241impl ToIndex for u32 { fn to_index(&self) -> usize { *self as usize } }
242impl ToIndex for u64 { fn to_index(&self) -> usize { *self as usize } }
243impl ToIndex for usize { fn to_index(&self) -> usize { *self } }
244impl ToIndex for i8 { fn to_index(&self) -> usize { *self as usize } }
245impl ToIndex for i16 { fn to_index(&self) -> usize { *self as usize } }
246impl ToIndex for i32 { fn to_index(&self) -> usize { *self as usize } }
247impl ToIndex for i64 { fn to_index(&self) -> usize { *self as usize } }
248impl ToIndex for isize { fn to_index(&self) -> usize { *self as usize } }
249
250impl FromIndex for u8 { fn from_index(idx: usize) -> u8 { idx as u8 } }
251impl FromIndex for u16 { fn from_index(idx: usize) -> u16 { idx as u16 } }
252impl FromIndex for u32 { fn from_index(idx: usize) -> u32 { idx as u32 } }
253impl FromIndex for u64 { fn from_index(idx: usize) -> u64 { idx as u64 } }
254impl FromIndex for usize { fn from_index(idx: usize) -> usize { idx } }
255impl FromIndex for i8 { fn from_index(idx: usize) -> i8 { idx as i8 } }
256impl FromIndex for i16 { fn from_index(idx: usize) -> i16 { idx as i16 } }
257impl FromIndex for i32 { fn from_index(idx: usize) -> i32 { idx as i32 } }
258impl FromIndex for i64 { fn from_index(idx: usize) -> i64 { idx as i64 } }
259impl FromIndex for isize { fn from_index(idx: usize) -> isize { idx as isize } }
260
261impl Generation for u8 { fn get_gen(&self) -> u32 { *self as u32 } }
262impl Generation for u16 { fn get_gen(&self) -> u32 { *self as u32 } }
263impl Generation for u32 { fn get_gen(&self) -> u32 { *self as u32 } }
264impl Generation for u64 { fn get_gen(&self) -> u32 { *self as u32 } }
265
266impl<T, H:Copy, G:Generation> Generation for GenId<T, H, G> {
267 fn get_gen(&self) -> u32 { self.gen.get_gen() }
268}
269
270impl IntegerHandle for u8 {}
271impl IntegerHandle for u16 {}
272impl IntegerHandle for u32 {}
273impl IntegerHandle for u64 {}
274impl IntegerHandle for usize {}
275impl IntegerHandle for i8 {}
276impl IntegerHandle for i16 {}
277impl IntegerHandle for i32 {}
278impl IntegerHandle for i64 {}
279impl IntegerHandle for isize {}
280
281
282#[test]
285fn test_copy_id() {
286 #[derive(Debug)]
287 struct Foo;
288
289 let a: Id<Foo, u32> = Id::new(0);
291 let b = a;
292 let c = a;
293 assert_eq!(b, c);
294
295 let r1 = IdRange {
297 first: a,
298 count: 10,
299 };
300
301 let r2 = r1;
302 let r3 = r1;
303 assert_eq!(r2, r3);
304}
305
306#[test]
307fn test_reverese_id_range() {
308 use std::iter::FromIterator;
309 fn range(first:u16, count:u16) -> IdRange<u16, u16> { IdRange::new(first, count) }
310 let v: Vec<Id<u16, u16>> = Vec::from_iter(ReverseIdRange::new(range(1, 5)));
311 assert_eq!(v, vec![Id::new(5), Id::new(4), Id::new(3), Id::new(2), Id::new(1)]);
312}