1#![deny(missing_docs, missing_debug_implementations)]
21
22extern crate id_set;
23
24#[cfg(test)]
25mod tests;
26
27pub use id_set::Id;
28
29use std::iter::FromIterator;
30use std::ops::{Index, IndexMut};
31use std::{cmp, fmt, mem, ptr};
32
33use id_set::IdSet;
34
35pub struct IdMap<T> {
37 ids: IdSet,
39 values: Vec<T>,
41 space: Id,
43}
44
45impl<T> IdMap<T> {
46 #[inline]
47 pub fn new() -> Self {
49 IdMap {
50 ids: IdSet::new(),
51 values: Vec::new(),
52 space: 0,
53 }
54 }
55
56 #[inline]
57 pub fn with_capacity(cap: usize) -> Self {
59 IdMap {
60 ids: IdSet::with_capacity(cap),
61 values: Vec::with_capacity(cap),
62 space: 0,
63 }
64 }
65
66 #[inline]
67 pub fn clear(&mut self) {
69 unsafe { self.drop_values() }
70 self.ids.clear();
71 }
72
73 #[inline]
74 pub fn next_id(&self) -> Id {
76 self.space
77 }
78
79 #[inline]
80 pub fn len(&self) -> usize {
82 self.ids.len()
83 }
84
85 #[inline]
86 pub fn capacity(&self) -> usize {
88 self.ids.capacity()
89 }
90
91 #[inline]
92 pub fn reserve(&mut self, cap: usize) {
94 self.ids.reserve(cap);
95 self.values.reserve(cap);
96 }
97
98 #[inline]
99 pub fn shrink_to_fit(&mut self) {
101 self.ids.shrink_to_fit();
102 unsafe {
103 let cap = cmp::min(self.values.capacity(), self.ids.capacity());
104 self.values.set_len(cap);
105 self.values.shrink_to_fit();
106 self.values.set_len(0);
107 }
108 }
109
110 #[inline]
111 pub fn as_set(&self) -> &IdSet {
113 &self.ids
114 }
115
116 #[inline]
117 pub fn insert(&mut self, val: T) -> Id {
119 let id = self.space;
120 if id == self.values.capacity() {
121 self.values.reserve(id + 1);
122 }
123 unsafe { ptr::write(self.values.get_unchecked_mut(id), val) }
124 self.ids.insert(id);
125 self.find_space();
126 id
127 }
128
129 #[inline]
130 pub fn insert_at(&mut self, id: Id, val: T) -> Option<T> {
132 if self.ids.insert(id) {
133 if id == self.space {
135 self.find_space();
136 }
137 if self.values.capacity() < id + 1 {
138 self.values.reserve(id + 1);
139 }
140 unsafe { ptr::write(self.values.get_unchecked_mut(id), val) }
141 None
142 } else {
143 Some(mem::replace(unsafe { self.values.get_unchecked_mut(id) }, val))
145 }
146 }
147
148 #[inline]
149 pub fn remove(&mut self, id: Id) -> Option<T> {
151 if self.ids.remove(id) {
152 self.space = cmp::min(self.space, id);
153 Some(unsafe { ptr::read(self.values.get_unchecked(id)) })
154 } else {
155 None
156 }
157 }
158
159 #[inline]
160 pub fn get_or_insert(&mut self, id: Id, val: T) -> &mut T {
162 self.get_or_insert_with(id, || val)
163 }
164
165 #[inline]
166 pub fn get_or_insert_with<F: FnOnce() -> T>(&mut self, id: Id, f: F) -> &mut T {
168 if self.ids.insert(id) {
169 if id == self.space {
171 self.find_space();
172 }
173 if self.values.capacity() < id + 1 {
174 self.values.reserve(id + 1);
175 }
176 unsafe {
177 let space = self.values.get_unchecked_mut(id);
178 ptr::write(space, f());
179 space
180 }
181 } else {
182 unsafe { self.values.get_unchecked_mut(id) }
183 }
184 }
185
186 #[inline]
187 pub fn remove_set(&mut self, set: &IdSet) {
189 {
190 let mut iter = self.ids.intersection(set).into_iter();
191
192 if let Some(first) = iter.next() {
193 self.space = cmp::min(self.space, first);
195 unsafe {
196 ptr::drop_in_place(self.values.get_unchecked_mut(first))
197 }
198 for id in iter {
199 unsafe {
200 ptr::drop_in_place(self.values.get_unchecked_mut(id))
201 }
202 }
203 }
204 }
205
206 self.ids.inplace_difference(set);
207 }
208
209 #[inline]
210 pub fn retain<F: FnMut(Id, &T) -> bool>(&mut self, mut pred: F) {
212 let ids = &mut self.ids;
213 let values = &mut self.values;
214 let space = &mut self.space;
215 ids.retain(|id| {
216 unsafe {
217 if pred(id, values.get_unchecked(id)) {
218 true
219 } else {
220 *space = cmp::min(*space, id);
221 ptr::drop_in_place(values.get_unchecked_mut(id));
222 false
223 }
224 }
225 })
226 }
227
228 #[inline]
229 pub fn contains(&self, id: Id) -> bool {
231 self.ids.contains(id)
232 }
233
234 #[inline]
235 pub fn get(&self, id: Id) -> Option<&T> {
237 if self.ids.contains(id) {
238 Some(unsafe { self.values.get_unchecked(id) })
239 } else {
240 None
241 }
242 }
243
244 #[inline]
245 pub fn get_mut(&mut self, id: Id) -> Option<&mut T> {
247 if self.ids.contains(id) {
248 Some(unsafe { self.values.get_unchecked_mut(id) })
249 } else {
250 None
251 }
252 }
253
254 #[inline]
255 pub fn ids(&self) -> Ids {
257 Ids {
258 ids: self.ids.iter(),
259 }
260 }
261
262 #[inline]
263 pub fn values(&self) -> Values<T> {
265 Values {
266 ids: self.ids.iter(),
267 values: self.values.as_ptr(),
268 }
269 }
270
271 #[inline]
272 pub fn values_mut(&mut self) -> ValuesMut<T> {
274 ValuesMut {
275 ids: self.ids.iter(),
276 values: self.values.as_mut_ptr(),
277 }
278 }
279
280 #[inline]
281 pub fn iter(&self) -> Iter<T> {
283 Iter {
284 ids: self.ids.iter(),
285 values: self.values.as_ptr(),
286 }
287 }
288
289 #[inline]
290 pub fn iter_mut(&mut self) -> IterMut<T> {
292 IterMut {
293 ids: self.ids.iter(),
294 values: self.values.as_mut_ptr(),
295 }
296 }
297
298 #[inline]
299 pub fn into_iter(self) -> IntoIter<T> {
301 let (ids, values) = unsafe {
303 (ptr::read(&self.ids), ptr::read(&self.values))
304 };
305 mem::forget(self);
306 IntoIter {
307 ids: ids.into_iter(),
308 values: values,
309 }
310 }
311
312 #[cfg(test)]
313 fn assert_invariant(&self) {
314 for id in 0..self.space {
316 assert!(self.ids.contains(id));
317 }
318 assert!(!self.ids.contains(self.space));
319 for id in &self.ids {
321 assert!(id < self.values.capacity())
322 }
323 }
324
325 unsafe fn drop_values(&mut self) {
327 for id in &self.ids {
328 ptr::drop_in_place(self.values.get_unchecked_mut(id))
329 }
330 }
331
332 fn find_space(&mut self) {
334 self.space += 1;
336 while self.ids.contains(self.space) {
337 self.space += 1;
338 }
339 }
340}
341
342impl<T> Drop for IdMap<T> {
343 #[inline]
344 fn drop(&mut self) {
345 unsafe { self.drop_values() }
346 }
347}
348
349impl<T: Clone> Clone for IdMap<T> {
350 #[inline]
351 fn clone(&self) -> Self {
352 let ids = self.ids.clone();
353 let cap = self.values.capacity();
354 let mut values = Vec::with_capacity(cap);
355 unsafe {
356 for id in &ids {
357 ptr::write(values.get_unchecked_mut(id),
358 self.values.get_unchecked(id).clone());
359 }
360 }
361 IdMap {
362 ids,
363 values,
364 space: cap,
365 }
366 }
367
368 #[inline]
369 fn clone_from(&mut self, other: &Self) {
370 unsafe { self.drop_values() };
371 self.ids.clone_from(&other.ids);
372
373 let cap = other.values.capacity();
374 self.values.reserve(cap);
375 unsafe {
376 for id in &self.ids {
377 ptr::write(self.values.get_unchecked_mut(id),
378 other.values.get_unchecked(id).clone());
379 }
380 }
381 }
382}
383
384impl<T: fmt::Debug> fmt::Debug for IdMap<T> {
385 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
386 write!(f, "{{")?;
387 let mut iter = self.iter();
388 if let Some((id, val)) = iter.next() {
389 write!(f, "{:?}: {:?}", id, val)?;
390 for (id, val) in iter {
391 write!(f, ", {:?}: {:?}", id, val)?;
392 }
393 }
394 write!(f, "}}")
395 }
396}
397
398impl<T> Default for IdMap<T> {
399 #[inline]
400 fn default() -> Self {
401 IdMap::new()
402 }
403}
404
405impl<T: Eq> Eq for IdMap<T> {}
406
407impl<T: PartialEq> PartialEq for IdMap<T> {
408 fn eq(&self, other: &Self) -> bool {
409 self.ids == other.ids && self.ids
410 .iter()
411 .zip(&other.ids)
412 .all(|(l, r)| unsafe { self.values.get_unchecked(l) == other.values.get_unchecked(r) })
413 }
414}
415
416impl<T> Extend<T> for IdMap<T> {
417 #[inline]
418 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
419 for val in iter {
420 self.insert(val);
421 }
422 }
423}
424
425impl<T> FromIterator<T> for IdMap<T> {
426 #[inline]
427 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
428 let mut values = Vec::from_iter(iter);
429 unsafe { values.set_len(0) }
430 let space = values.capacity();
431 let ids = IdSet::new_filled(values.capacity());
432 IdMap {
433 values,
434 space,
435 ids,
436 }
437 }
438}
439
440impl<T> FromIterator<(Id, T)> for IdMap<T> {
441 #[inline]
442 fn from_iter<I: IntoIterator<Item = (Id, T)>>(iter: I) -> Self {
443 let iter = iter.into_iter();
444 let mut map = IdMap::with_capacity(iter.size_hint().0);
445 for (id, val) in iter {
446 map.insert_at(id, val);
447 }
448 map
449 }
450}
451
452impl<'a, T> IntoIterator for &'a IdMap<T> {
453 type Item = (Id, &'a T);
454 type IntoIter = Iter<'a, T>;
455
456 #[inline]
457 fn into_iter(self) -> Self::IntoIter {
458 self.iter()
459 }
460}
461
462impl<'a, T> IntoIterator for &'a mut IdMap<T> {
463 type Item = (Id, &'a mut T);
464 type IntoIter = IterMut<'a, T>;
465
466 #[inline]
467 fn into_iter(self) -> Self::IntoIter {
468 self.iter_mut()
469 }
470}
471
472impl<T> IntoIterator for IdMap<T> {
473 type Item = (Id, T);
474 type IntoIter = IntoIter<T>;
475
476 #[inline]
477 fn into_iter(self) -> Self::IntoIter {
478 self.into_iter()
479 }
480}
481
482impl<T> Index<Id> for IdMap<T> {
483 type Output = T;
484
485 #[inline]
486 fn index(&self, id: Id) -> &Self::Output {
487 assert!(self.ids.contains(id), "id {} out of bounds", id);
488 unsafe { self.values.get_unchecked(id) }
489 }
490}
491
492impl<T> IndexMut<Id> for IdMap<T> {
493 #[inline]
494 fn index_mut(&mut self, id: Id) -> &mut Self::Output {
495 assert!(self.ids.contains(id), "id {} out of bounds", id);
496 unsafe { self.values.get_unchecked_mut(id) }
497 }
498}
499
500#[derive(Clone, Debug)]
501pub struct Ids<'a> {
503 ids: id_set::Iter<'a>,
504}
505
506impl<'a> Iterator for Ids<'a> {
507 type Item = Id;
508
509 #[inline]
510 fn next(&mut self) -> Option<Self::Item> {
511 self.ids.next()
512 }
513
514 #[inline]
515 fn size_hint(&self) -> (usize, Option<usize>) {
516 self.ids.size_hint()
517 }
518}
519
520impl<'a> ExactSizeIterator for Ids<'a> {
521 #[inline]
522 fn len(&self) -> usize {
523 self.ids.len()
524 }
525}
526
527#[derive(Debug)]
528pub struct Values<'a, T: 'a> {
530 ids: id_set::Iter<'a>,
531 values: *const T,
532}
533
534impl<'a, T: 'a> Iterator for Values<'a, T> {
535 type Item = &'a T;
536
537 #[inline]
538 fn next(&mut self) -> Option<Self::Item> {
539 self.ids.next().map(|id| unsafe { &*self.values.offset(id as isize) })
540 }
541
542 #[inline]
543 fn size_hint(&self) -> (usize, Option<usize>) {
544 self.ids.size_hint()
545 }
546}
547
548impl<'a, T: 'a> ExactSizeIterator for Values<'a, T> {
549 #[inline]
550 fn len(&self) -> usize {
551 self.ids.len()
552 }
553}
554
555impl<'a, T: 'a> Clone for Values<'a, T> {
556 #[inline]
557 fn clone(&self) -> Self {
558 Values {
559 ids: self.ids.clone(),
560 values: self.values,
561 }
562 }
563}
564
565#[derive(Debug)]
566pub struct ValuesMut<'a, T: 'a> {
568 ids: id_set::Iter<'a>,
569 values: *mut T,
570}
571
572impl<'a, T: 'a> Iterator for ValuesMut<'a, T> {
573 type Item = &'a mut T;
574
575 #[inline]
576 fn next(&mut self) -> Option<Self::Item> {
577 self.ids.next().map(|id| unsafe { &mut *self.values.offset(id as isize) })
578 }
579
580 #[inline]
581 fn size_hint(&self) -> (usize, Option<usize>) {
582 self.ids.size_hint()
583 }
584}
585
586impl<'a, T: 'a> ExactSizeIterator for ValuesMut<'a, T> {
587 #[inline]
588 fn len(&self) -> usize {
589 self.ids.len()
590 }
591}
592
593#[derive(Debug)]
594pub struct Iter<'a, T: 'a> {
596 ids: id_set::Iter<'a>,
597 values: *const T,
598}
599
600impl<'a, T: 'a> Iterator for Iter<'a, T> {
601 type Item = (Id, &'a T);
602
603 #[inline]
604 fn next(&mut self) -> Option<Self::Item> {
605 self.ids.next().map(|id| (id, unsafe { &*self.values.offset(id as isize) }))
606 }
607
608 #[inline]
609 fn size_hint(&self) -> (usize, Option<usize>) {
610 self.ids.size_hint()
611 }
612}
613
614impl<'a, T: 'a> ExactSizeIterator for Iter<'a, T> {
615 #[inline]
616 fn len(&self) -> usize {
617 self.ids.len()
618 }
619}
620
621impl<'a, T: 'a> Clone for Iter<'a, T> {
622 #[inline]
623 fn clone(&self) -> Self {
624 Iter {
625 ids: self.ids.clone(),
626 values: self.values,
627 }
628 }
629}
630
631#[derive(Debug)]
632pub struct IterMut<'a, T: 'a> {
634 ids: id_set::Iter<'a>,
635 values: *mut T,
636}
637
638impl<'a, T: 'a> Iterator for IterMut<'a, T> {
639 type Item = (Id, &'a mut T);
640
641 #[inline]
642 fn next(&mut self) -> Option<Self::Item> {
643 self.ids.next().map(|id| (id, unsafe { &mut *self.values.offset(id as isize) }))
644 }
645
646 #[inline]
647 fn size_hint(&self) -> (usize, Option<usize>) {
648 self.ids.size_hint()
649 }
650}
651
652impl<'a, T: 'a> ExactSizeIterator for IterMut<'a, T> {
653 #[inline]
654 fn len(&self) -> usize {
655 self.ids.len()
656 }
657}
658
659#[derive(Clone, Debug)]
660pub struct IntoIter<T> {
662 ids: id_set::IntoIter,
663 values: Vec<T>,
664}
665
666impl<T> Iterator for IntoIter<T> {
667 type Item = (Id, T);
668
669 #[inline]
670 fn next(&mut self) -> Option<Self::Item> {
671 self.ids.next().map(|id| (id, unsafe { ptr::read(self.values.get_unchecked(id)) }))
672 }
673
674 #[inline]
675 fn size_hint(&self) -> (usize, Option<usize>) {
676 self.ids.size_hint()
677 }
678}