id_vec/
vec.rs

1
2use ::std::collections::HashSet;
3use ::id::*;
4
5
6/// Create a new id_vec by entering a series of values
7#[macro_export]
8macro_rules! id_vec {
9    ( $($element:expr),* ) => {
10        IdVec::from_vec(vec![ $($element),* ])
11    };
12}
13
14
15/// Inserting elements into this map yields a persistent, type-safe Index to that new element.
16/// It does not try to preserve the order of the inserted items.
17///
18/// The IdVec does not actively try to preserve order of inserted elements,
19/// but a packed IdVec will append elements to the end of the internal vector.
20#[derive(Clone, Default)] // manual impl: Eq, PartialEq
21pub struct IdVec<T> {
22    /// Packed dense vector, containing alive and dead elements.
23    /// Because removing the last element directly can be done efficiently,
24    /// it is guaranteed that the last element is never unused.
25    elements: Vec<T>,
26
27    /// Contains all unused ids which are allowed to be overwritten,
28    /// will never contain the last used ID, because the last id can be removed directly
29    unused_indices: HashSet<Index>, // TODO if iteration is too slow, use both Vec<NextUnusedIndex> and BitVec
30}
31
32
33// TODO use rusts safety mechanisms to allow (but not enforce) stronger id lifetime safety? OwnedId<T>?
34
35impl<T> IdVec<T> {
36
37    /// Does not allocate heap memory
38    pub fn new() -> Self {
39        Self::with_capacity(0)
40    }
41
42    pub fn with_capacity(capacity: usize) -> Self {
43        Self::from(Vec::with_capacity(capacity))
44    }
45
46    /// Create a map containing these elements.
47    /// Directly uses the specified vector,
48    /// so no heap allocation is made calling this function.
49    pub fn from_vec(elements: Vec<T>) -> Self {
50        IdVec {
51            unused_indices: HashSet::new(), // no elements deleted
52            elements,
53        }
54    }
55
56
57
58
59    /// Returns if this id is not deleted (does not check if index is inside vector range)
60    fn index_is_currently_used(&self, index: Index) -> bool {
61        index + 1 == self.elements.len() || // fast return for last element is always used
62            !self.unused_indices.contains(&index)
63    }
64
65    fn index_is_in_range(&self, index: Index) -> bool {
66        index < self.elements.len()
67    }
68
69    #[inline(always)]
70    fn debug_assert_id_validity(&self, element: Id<T>, validity: bool){
71        debug_assert!(
72            self.contains_id(element) == validity,
73            "Expected {:?} validity to be {}, but was not", element, validity
74        );
75    }
76    
77    #[inline(always)]
78    fn debug_assert_last_element_is_used(&self){
79        if !self.is_empty() {
80            debug_assert!(
81                self.contains_id(Id::from_index(self.elements.len() - 1)),
82                "IdMap has invalid state: Last element is unused."
83            );
84        }
85    }
86
87
88
89    pub fn len(&self) -> usize {
90        debug_assert!(self.elements.len() >= self.unused_indices.len(), "More ids are unused than exist");
91        self.elements.len() - self.unused_indices.len()
92    }
93
94    /// Used to estimate the maximal `index_value()` of all ids inside this IdVec.
95    /// This IdVec will not contain an id with an index value greater than or equal to this value.
96    pub fn id_index_limit(&self) -> usize {
97        self.elements.len()
98    }
99
100    pub fn capacity(&self) -> usize {
101        self.elements.capacity()
102    }
103
104    pub fn is_empty(&self) -> bool {
105        self.len() == 0
106    }
107
108    /// Excludes deleted elements, and indices out of range
109    pub fn contains_id(&self, element: Id<T>) -> bool {
110        self.index_is_in_range(element.index_value())
111            && self.index_is_currently_used(element.index_value())
112    }
113
114    /// Returns if the internal vector does not contain any deleted elements
115    pub fn is_packed(&self) -> bool {
116        self.unused_indices.is_empty()
117    }
118
119
120
121    /// Enable the specified id to be overwritten when a new element is inserted.
122    /// This does not directly deallocate the element.
123    /// Make sure that no ids pointing to that element exist after this call.
124    /// Ignores invalid and deleted ids.
125    pub fn remove(&mut self, element: Id<T>) {
126        self.debug_assert_last_element_is_used();
127
128        if self.index_is_in_range(element.index_value()) {
129
130            // if exactly the last element, remove without inserting into unused_ids
131            if element.index_value() + 1 == self.elements.len() {
132                self.elements.pop();
133
134                // remove all unused elements at the end of the vector
135                // which may have been guarded by the (now removed) last element
136                self.pop_back_unused();
137
138            } else { // remove not-the-last element
139                self.unused_indices.insert(element.index_value()); // may overwrite existing index
140            }
141        }
142
143        self.debug_assert_id_validity(element, false);
144        self.debug_assert_last_element_is_used();
145    }
146
147    /// Removes an id and the associated element.
148    /// See `pop_element` for more information.
149    pub fn pop(&mut self) -> Option<(Id<T>, T)> {
150        self.debug_assert_last_element_is_used();
151
152        let popped = self.elements.pop().map(|element|{
153            (Id::from_index(self.elements.len()), element)
154        });
155
156        self.pop_back_unused();
157        popped
158    }
159
160    /// Removes an element from this map, returns the element:
161    /// Removes the one element which is the least work to remove, the one with the highest id.
162    /// May deallocate unused elements. Returns None if this map is empty.
163    pub fn pop_element(&mut self) -> Option<T> {
164        self.pop().map(|(_, element)| element)
165    }
166
167    /// Recover from possibly invalid state
168    /// by removing any non-used elements from the back of the vector
169    fn pop_back_unused(&mut self){
170        if self.elements.len() == self.unused_indices.len() {
171            self.clear();
172
173        } else {
174            while !self.elements.is_empty() // prevent overflow at len() - 1
175                && self.unused_indices.remove(&(self.elements.len() - 1)) {
176
177                self.elements.pop(); // pop the index that has just been removed from the unused-set
178            }
179        }
180
181        self.debug_assert_last_element_is_used();
182    }
183
184    /// Associate the specified element with a currently unused id.
185    /// This may overwrite (thus drop) unused elements.
186    pub fn insert(&mut self, element: T) -> Id<T> {
187        let id = Id::from_index({
188            if let Some(previously_unused_index) = self.unused_indices.iter().next().map(|i| *i) {
189                self.debug_assert_id_validity(Id::from_index(previously_unused_index), false);
190                self.unused_indices.remove(&previously_unused_index);
191                self.elements[previously_unused_index] = element;
192                previously_unused_index
193            } else {
194                self.elements.push(element);
195                self.elements.len() - 1
196            }
197        });
198
199        self.debug_assert_last_element_is_used();
200        self.debug_assert_id_validity(id, true);
201        id
202    }
203
204
205
206    /// Return a reference to the element that this id points to
207    pub fn get(&self, element: Id<T>) -> Option<&T> {
208        if self.index_is_currently_used(element.index_value()) {
209            self.elements.get(element.index_value())
210        } else { None }
211    }
212
213    /// Return a mutable reference to the element that this id points to
214    pub fn get_mut<'s>(&'s mut self, element: Id<T>) -> Option<&'s mut T> {
215        if self.index_is_currently_used(element.index_value()) {
216            self.elements.get_mut(element.index_value())
217        } else { None }
218    }
219
220
221    /// Swap the elements pointed to. Panic on invalid Id parameter.
222    pub fn swap_elements(&mut self, id1: Id<T>, id2: Id<T>){
223        self.debug_assert_id_validity(id1, true);
224        self.debug_assert_id_validity(id2, true);
225        self.elements.swap(id1.index_value(), id2.index_value());
226    }
227
228    /// Removes all elements, instantly deallocating
229    pub fn clear(&mut self){
230        self.elements.clear();
231        self.unused_indices.clear();
232        debug_assert!(self.is_empty());
233    }
234
235    /// Shrinks the internal vector itself
236    pub fn shrink_to_fit(&mut self){
237        self.elements.shrink_to_fit();
238        self.unused_indices.shrink_to_fit(); // bottleneck? reinserts all elements into a new map
239        self.debug_assert_last_element_is_used();
240    }
241
242    /// Reserve space for more elements, avoiding frequent reallocation
243    pub fn reserve(&mut self, additional: usize){
244        self.elements.reserve(additional)
245    }
246
247    /// Retain only the elements specified by the predicate. May deallocate unused elements.
248    pub fn retain<F>(&mut self, predicate: F) where F: Fn(Id<T>, &T) -> bool {
249        for index in 0..self.elements.len() {
250            let id = Id::from_index(index);
251            if !self.unused_indices.contains(&index)
252                && !predicate(id, &self.elements[index])
253            {
254                self.unused_indices.insert(index);
255            }
256        }
257
258        self.pop_back_unused();
259    }
260
261    /// Make this map have a continuous flow of indices, having no wasted allocation
262    /// and calling remap(old_id, new_id) for every element that has been moved to a new Id
263    /// It does not preserve order of the inserted items.
264    pub fn pack<F>(&mut self, mut remap: F) where F: FnMut(Id<T>, Id<T>) {
265        let mut unused_indices = ::std::mem::replace(
266            &mut self.unused_indices,
267            HashSet::new() // does not allocate
268        );
269
270        while let Some(&unused_index) = unused_indices.iter().next() {
271            // unused_index may have already been removed in a previous iteration at pop_back_unused, so check for:
272            if unused_index < self.elements.len() {
273                let last_used_element_index = self.elements.len() - 1;
274                debug_assert_ne!(unused_index, last_used_element_index, "Last element of IdMap is not used");
275
276                self.elements.swap(last_used_element_index, unused_index);
277                remap(Id::from_index(last_used_element_index), Id::from_index(unused_index));
278
279                // pop the (last, unused) element
280                unused_indices.remove(&unused_index); // must be updated to avoid popping already swapped elements
281                self.elements.pop();
282
283                // pop all previously guarded unused elements
284                while unused_indices.remove(&(self.elements.len() - 1)) {
285                    self.elements.pop();
286                }
287            }
288        }
289
290        self.shrink_to_fit();
291    }
292
293
294    /// Used for immutable access to ids and elements
295    pub fn iter<'s>(&'s self) -> Iter<'s, T> {
296        Iter {
297            inclusive_front_index: 0,
298            exclusive_back_index: self.elements.len(),
299            storage: self
300        }
301    }
302
303    // pub fn iter_mut<'s>(&'s mut self) -> IterMut cannot be implemented safely
304    // because it would require multiple mutable references
305
306    /// Iterate over the elements, consuming this IdVec
307    pub fn into_elements(self) -> IntoElements<T> {
308        IntoElements {
309            exclusive_max_index: self.elements.len(),
310            unused_ids: self.unused_indices,
311            iter: self.elements.into_iter(),
312            next_index: 0,
313        }
314    }
315
316    /// Iterate over the elements, clearing this IdVec
317    pub fn drain_elements(&mut self) -> DrainElements<T> {
318        DrainElements {
319            exclusive_max_index: self.elements.len(),
320            unused_ids: &mut self.unused_indices,
321            iter: self.elements.drain(..),
322            next_index: 0,
323        }
324    }
325
326    /// Used for immutable direct access to all used elements
327    pub fn elements<'s>(&'s self) -> ElementIter<'s, T> {
328        ElementIter { iter: self.iter() }
329    }
330
331    /// Used for immutable indirect access
332    pub fn ids<'s>(&'s self) -> IdIter<'s, T> {
333        IdIter { iter: self.iter() }
334    }
335
336    /// Used for full mutable access, while allowing inserting and deleting while iterating.
337    /// The iterator will keep an independent state, in order to un-borrow the underlying map.
338    /// This may be more expensive than `iter`,
339    /// because it needs to clone the internal set of unused ids.
340    pub fn get_ids(&self) -> OwnedIdIter<T> {
341        OwnedIdIter {
342            inclusive_front_index: 0,
343            exclusive_back_index: self.elements.len(),
344            unused_ids: self.unused_indices.clone(), // TODO without clone // TODO try copy-on-write?
345            marker: ::std::marker::PhantomData,
346        }
347    }
348
349
350    /// Compares if two id-maps contain the same ids, ignoring elements.
351    /// Complexity of O(n)
352    pub fn ids_eq(&self, other: &Self) -> bool {
353        self.len() == other.len()
354            && self.ids().all(|id| other.contains_id(id))
355    }
356
357    /// Compares if two id-maps contain the same elements, ignoring ids.
358    /// Worst case complexity of O(n^2)
359    pub fn elements_eq(&self, other: &Self) -> bool where T: PartialEq {
360        self.len() == other.len() && self.elements().all(|element| {
361            other.contains_element(element)
362        })
363    }
364
365    /// Worst case complexity of O(n)
366    pub fn contains_element(&self, element: &T) -> bool where T: PartialEq {
367        // cannot use self.elements.contains() because it contains removed elements
368        self.find_id_of_element(element).is_some()
369    }
370
371    /// Worst case complexity of O(n)
372    pub fn find_id_of_element(&self, element: &T) -> Option<Id<T>> where T: PartialEq {
373        self.iter().find(|&(_, e)| element == e)
374            .map(|(id, _)| id)
375    }
376
377}
378
379
380// enable using .collect() on an iterator to construct self
381impl<T> ::std::iter::FromIterator<T> for IdVec<T> {
382    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> Self {
383        IdVec::from_vec(iter.into_iter().collect())
384    }
385}
386
387// enable using .collect() on self
388impl<T> ::std::iter::IntoIterator for IdVec<T> {
389    type Item = T;
390    type IntoIter = IntoElements<T>;
391    fn into_iter(self) -> Self::IntoIter {
392        self.into_elements()
393    }
394}
395
396impl<T> From<Vec<T>> for IdVec<T> {
397    fn from(vec: Vec<T>) -> Self {
398        IdVec::from_vec(vec)
399    }
400}
401
402
403
404impl<T> ::std::ops::Index<Id<T>> for IdVec<T> {
405    type Output = T;
406    fn index(&self, element: Id<T>) -> &T {
407        debug_assert!(self.contains_id(element), "Indexing with invalid Id: `{:?}` ", element);
408        &self.elements[element.index_value()]
409    }
410}
411
412impl<T> ::std::ops::IndexMut<Id<T>> for IdVec<T> {
413    fn index_mut(&mut self, element: Id<T>) -> &mut T {
414        debug_assert!(self.contains_id(element), "Indexing-Mut with invalid Id: `{:?}` ", element);
415        &mut self.elements[element.index_value()]
416    }
417}
418
419
420/// Equality means: The same Ids pointing to the same elements, ignoring deleted elements.
421/// Complexity of O(n)
422impl<T> Eq for IdVec<T> where T: Eq {}
423impl<T> PartialEq for IdVec<T> where T: PartialEq {
424    fn eq(&self, other: &Self) -> bool {
425        self.len() == other.len() && self.iter()
426            .zip(other.iter()) // use iterators to automatically ignore deleted elements
427            .all(|((id_a, element_a), (id_b, element_b))| {
428                id_a == id_b && element_a == element_b
429            })
430    }
431}
432
433use ::std::fmt::Debug;
434impl<T> Debug for IdVec<T> where T: Debug {
435    fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
436        write!(formatter, "{{ ")?;
437
438        for (id, element) in self.iter() {
439            write!(formatter, "{:?}: {:?}, ", id, element)?;
440        }
441
442        write!(formatter, "}}")?;
443        Ok(())
444    }
445}
446
447
448
449
450// TODO all iterators can be ExactSizeIterators if they count how many deleted objects they have passed
451
452
453fn iter_next(
454    inclusive_front_index: &mut Index,
455    exclusive_back_index: &Index,
456    unused_ids: &HashSet<Index>
457) -> Option<Index>
458{
459    // skip unused elements
460    while *inclusive_front_index < *exclusive_back_index &&
461        unused_ids.contains(inclusive_front_index)
462    {
463        *inclusive_front_index += 1;
464    }
465
466    // consume next element
467    let index = *inclusive_front_index;
468    *inclusive_front_index += 1;
469
470    if index < *exclusive_back_index {
471        Some(index)
472    } else { None }
473}
474
475fn iter_next_back(
476    inclusive_front_index: &Index,
477    exclusive_back_index: &mut Index,
478    unused_ids: &HashSet<Index>
479) -> Option<Index>
480{
481    // skip unused elements
482    while *exclusive_back_index > *inclusive_front_index
483        && unused_ids.contains(&(*exclusive_back_index - 1))
484    {
485        *exclusive_back_index -= 1;
486    }
487
488    // consume next element
489    // back_index - 1 now points to exactly the next_back element
490    if *exclusive_back_index > *inclusive_front_index {
491        *exclusive_back_index -= 1;
492        Some(*exclusive_back_index)
493
494    } else {
495        None
496    }
497}
498
499
500
501
502pub struct Iter<'s, T: 's> {
503    inclusive_front_index: Index,
504    exclusive_back_index: Index,
505    storage: &'s IdVec<T>,
506}
507
508impl<'s, T: 's> Iterator for Iter<'s, T> {
509    type Item = (Id<T>, &'s T);
510
511    fn next(&mut self) -> Option<Self::Item> {
512        iter_next(
513            &mut self.inclusive_front_index,
514            &self.exclusive_back_index,
515            &self.storage.unused_indices
516        ).map(|index|{
517            let id = Id::from_index(index);
518            (id, &self.storage[id])
519        })
520    }
521
522    fn size_hint(&self) -> (usize, Option<usize>) {
523        let max_remaining = self.exclusive_back_index - self.inclusive_front_index;
524        let unused_elements = self.storage.unused_indices.len();
525        let min_remaining = max_remaining.checked_sub(unused_elements).unwrap_or(0);
526        (min_remaining, Some(max_remaining))
527    }
528}
529
530impl<'s, T: 's> DoubleEndedIterator for Iter<'s, T> {
531    fn next_back(&mut self) -> Option<Self::Item> {
532        iter_next_back(
533            &self.inclusive_front_index,
534            &mut self.exclusive_back_index,
535            &self.storage.unused_indices
536        ).map(|index|{
537            let id = Id::from_index(index);
538            (id, &self.storage[id])
539        })
540    }
541}
542
543
544
545pub struct ElementIter<'s, T: 's> {
546    iter: Iter<'s, T>,
547}
548
549impl<'s, T: 's> Iterator for ElementIter<'s, T> {
550    type Item = &'s T;
551
552    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
553        self.iter.next().map(|(_, element)| element)
554    }
555
556    fn size_hint(&self) -> (usize, Option<usize>) {
557        self.iter.size_hint()
558    }
559}
560
561impl<'s, T: 's> DoubleEndedIterator for ElementIter<'s, T> {
562    fn next_back(&mut self) -> Option<<Self as Iterator>::Item> {
563        self.iter.next_back().map(|(_, element)| element)
564    }
565}
566
567
568/// Note: always iterates backwards, because it just calls IdMap.pop()
569pub struct IntoElements<T> {
570    iter: ::std::vec::IntoIter<T>,
571    unused_ids: HashSet<Index>,
572    exclusive_max_index: Index,
573    next_index: Index,
574}
575
576impl<T> ExactSizeIterator for IntoElements<T> {}
577impl<T> Iterator for IntoElements<T> {
578    type Item = T;
579
580    fn next(&mut self) -> Option<Self::Item> {
581        while self.unused_ids.remove(&self.next_index) {
582            self.next_index += 1;
583            self.iter.next().unwrap(); // skip deleted element
584        }
585
586        if self.next_index < self.exclusive_max_index {
587            self.next_index += 1;
588            Some(self.iter.next().unwrap())
589
590        } else {
591            None
592        }
593    }
594
595    fn size_hint(&self) -> (usize, Option<usize>) {
596        let elements = self.exclusive_max_index - self.next_index;
597        let used = elements - self.unused_ids.len(); // self.unused_ids is updated on self.next()
598        (used, Some(used))
599    }
600}
601
602
603/// Note: always iterates backwards, because it just calls IdMap.pop()
604pub struct DrainElements<'s, T: 's> {
605    iter: ::std::vec::Drain<'s, T>,
606    unused_ids: &'s mut HashSet<Index>,
607    exclusive_max_index: Index,
608    next_index: Index,
609}
610
611impl<'s, T: 's> ExactSizeIterator for DrainElements<'s, T> {}
612impl<'s, T: 's> Iterator for DrainElements<'s, T> {
613    type Item = T;
614
615    fn next(&mut self) -> Option<Self::Item> {
616        while self.unused_ids.remove(&self.next_index) {
617            self.next_index += 1;
618            self.iter.next().unwrap(); // skip deleted element
619        }
620
621        if self.next_index < self.exclusive_max_index {
622            self.next_index += 1;
623            Some(self.iter.next().unwrap())
624
625        } else {
626            None
627        }
628    }
629
630    fn size_hint(&self) -> (usize, Option<usize>) {
631        let elements = self.exclusive_max_index - self.next_index;
632        let used = elements - self.unused_ids.len(); // self.unused_ids is updated on self.next()
633        (used, Some(used))
634    }
635}
636
637impl<'s, T: 's> Drop for DrainElements<'s, T> {
638    fn drop(&mut self) {
639        // map.elements is cleared by self.iter
640        self.unused_ids.clear();
641    }
642}
643
644
645
646
647pub struct IdIter<'s, T: 's> {
648    iter: Iter<'s, T>,
649}
650
651impl<'s, T: 's> Iterator for IdIter<'s, T> {
652    type Item = Id<T>;
653
654    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
655        self.iter.next().map(|(id, _)| id) // relies on compiler optimization for performance
656    }
657
658    fn size_hint(&self) -> (usize, Option<usize>) {
659        self.iter.size_hint()
660    }
661}
662
663impl<'s, T: 's> DoubleEndedIterator for IdIter<'s, T> {
664    fn next_back(&mut self) -> Option<<Self as Iterator>::Item> {
665        self.iter.next_back().map(|(id, _)| id)
666    }
667}
668
669
670
671
672
673
674pub struct OwnedIdIter<T> {
675    inclusive_front_index: Index,
676    exclusive_back_index: Index,
677    unused_ids: HashSet<Index>,
678    marker: ::std::marker::PhantomData<T>,
679}
680
681impl<T> Iterator for OwnedIdIter<T> {
682    type Item = Id<T>;
683
684    fn next(&mut self) -> Option<Id<T>> {
685        iter_next(
686            &mut self.inclusive_front_index,
687            &self.exclusive_back_index,
688            &self.unused_ids
689        ).map(|index|
690            Id::from_index(index)
691        )
692    }
693
694    fn size_hint(&self) -> (usize, Option<usize>) {
695        let max_remaining = self.exclusive_back_index - self.inclusive_front_index;
696        let unused_elements = self.unused_ids.len();
697        let min_remaining = max_remaining.checked_sub(unused_elements).unwrap_or(0);
698        (min_remaining, Some(max_remaining))
699    }
700}
701
702impl<T> DoubleEndedIterator for OwnedIdIter<T> {
703    fn next_back(&mut self) -> Option<<Self as Iterator>::Item> {
704        iter_next_back(
705            &self.inclusive_front_index,
706            &mut self.exclusive_back_index,
707            &self.unused_ids
708        ).map(|index|
709            Id::from_index(index)
710        )
711    }
712}
713
714
715
716
717
718
719
720
721
722
723
724
725#[cfg(test)]
726mod test {
727    use super::*;
728
729    #[test]
730    pub fn test_from_iterator(){
731        let vec = vec![0, 1, 2, 5];
732        let map = vec.into_iter().collect::<IdVec<_>>();
733        assert_eq!(map.elements, vec![0, 1, 2, 5]);
734    }
735
736    #[test]
737    pub fn test_from_vec(){
738        let vec = vec![0, 1, 2, 5];
739        let map = IdVec::from_vec(vec);
740        assert_eq!(map.elements, vec![0, 1, 2, 5]);
741    }
742
743    #[test]
744    pub fn test_from_macro(){
745        let map = id_vec!(0, 1, 2, 5);
746        assert_eq!(map.elements, vec![0, 1, 2, 5]);
747    }
748
749    #[test]
750    pub fn test_insert_and_remove_single_element(){
751        let mut map = IdVec::new();
752
753        let id_0 = map.insert(0); {
754            assert_eq!(map.len(), 1, "map length after inserting");
755            assert!(!map.is_empty(), "map emptiness after inserting");
756            assert!(map.contains_id(id_0), "containing `0` after inserting `0`");
757            assert_eq!(map.get(id_0), Some(&0), "indexing `Some` after inserting `0`");
758        }
759
760        map.remove(id_0); {
761            assert_eq!(map.get(id_0), None, "indexing `None` after deleting");
762            assert_eq!(map.len(), 0, "map length after deleting");
763            assert!(!map.contains_id(id_0), "not containing `0` after removing `0`");
764            assert!(map.is_empty(), "map emptiness after deleting");
765        }
766
767        let id_1 = map.insert(1); {
768            assert!(map.contains_id(id_0), "containing overwritten `0` after inserting `1` into deleted slot");
769            assert!(map.contains_id(id_1), "containing `1` after inserting `1` into deleted slot");
770            assert_eq!(map.get(id_1), Some(&1), "indexing `Some` after inserting into deleted slot");
771            assert_eq!(map.get(id_0), Some(&1), "reusing unused id (old id pointing to new element)");
772            assert_eq!(map.len(), 1, "map length after inserting into deleted slot");
773            assert!(!map.is_empty(), "map emptiness after inserting into deleted slot");
774        }
775    }
776
777    #[test]
778    pub fn test_insert_and_remove_multiple_elements(){
779        let mut map = IdVec::new();
780        let len = 42;
781
782        for i in 0..42 {
783            assert!(!map.contains_id(Id::from_index(i)), "unused it being invalid");
784            let id = map.insert(i);
785            assert!(map.contains_id(id), "used id being valid");
786        }
787
788        assert_eq!(map.len(), len, "map length after inserting multiple elements");
789
790        while let Some(remaining_id) = map.ids().next() {
791            assert!(map.contains_id(remaining_id), "used id being valid");
792            map.remove(remaining_id);
793            assert!(!map.contains_id(remaining_id), "unused it being invalid");
794        }
795    }
796
797    #[test]
798    pub fn test_pop(){
799        let mut map = id_vec!(0, 2, 5);
800        assert_eq!(map.pop(), Some((Id::from_index(2), 5)), "`pop()` returning the last element");
801        assert!(map.is_packed(), "`pop()`not inserting into `unused_ids`");
802
803        map.remove(Id::from_index(0));
804        assert!(!map.is_empty());
805        assert!(!map.is_packed());
806
807        assert_eq!(map.pop(), Some((Id::from_index(1), 2)));
808        assert!(map.is_empty(), "`pop()` clearing the map");
809        assert!(map.is_packed(), "`pop()` removing unused ids at the back");
810
811        assert_eq!(map.pop(), None, "`pop()` returning `None` from map");
812        assert!(map.is_empty());
813    }
814
815    #[test]
816    pub fn test_into_iterator(){
817        let map = IdVec {
818            elements: vec![0, 2, 3, 4],
819            unused_indices: HashSet::new(),
820        };
821
822        assert_eq!(
823            map.into_iter().collect::<Vec<_>>(),
824            vec![0, 2, 3, 4],
825            "into_iterator containing all elements"
826        );
827    }
828
829    #[test]
830    pub fn test_drain(){
831        let mut map = id_vec!(0, 1, 2, 3);
832        assert_eq!(map.drain_elements().next(), Some(0));
833        assert!(map.is_empty(), "aborting drain clears map");
834
835        // test element in the middle removed
836        map.insert(12);
837        map.insert(4);
838        map.insert(5);
839        map.remove(Id::from_index(1));
840        assert_eq!(map.drain_elements().collect::<Vec<_>>(), vec![12, 5]);
841
842        // test first and last element removed
843        map.insert(14);
844        map.insert(44);
845        map.insert(500);
846        map.remove(Id::from_index(0));
847        map.remove(Id::from_index(2));
848        assert_eq!(map.drain_elements().collect::<Vec<_>>(), vec![44]);
849    }
850
851    #[test]
852    pub fn test_contains_element(){
853        let map = id_vec!(0, 1, 2, 3);
854        assert!(map.contains_element(&2), "containing element");
855        assert!(!map.contains_element(&4), "not containing element");
856    }
857
858    #[test]
859    pub fn test_into_iterator_with_deleted_elements(){
860        let mut map = IdVec::new();
861        let zero = map.insert(0);
862        let two = map.insert(2);
863        map.insert(3);
864        map.insert(4);
865
866        map.remove(zero);
867        map.remove(two);
868
869        assert_eq!(
870            map.into_iter().collect::<Vec<_>>(), vec![3, 4],
871            "into_iter containing only non-removed elements"
872        )
873    }
874
875    #[test]
876    pub fn test_elements_iter(){
877        let mut map = id_vec!(0, 1, 2, 5);
878
879        map.remove(Id::from_index(1));
880        assert_eq!(map.len(), 3, "removing decrements len");
881        assert!(!map.is_packed());
882
883        assert_eq!(
884            map.elements().collect::<Vec<_>>(),
885            vec![&0, /*deleted 1,*/ &2, &5],
886            "iter non-removed elements"
887        );
888
889        assert_eq!(
890            map.elements().rev().collect::<Vec<_>>(),
891            vec![&5, /*deleted 1,*/ &2, &0],
892            "double ended element iter"
893        );
894
895        assert_eq!(
896            map.ids()
897                .map(|id| id.index_value())
898                .collect::<Vec<_>>(),
899
900            vec![0, /*deleted 1,*/ 2, 3],
901            "iter non-removed ids"
902        );
903
904        assert_eq!(
905            map.ids().rev()
906                .map(|id| id.index_value())
907                .collect::<Vec<_>>(),
908
909            vec![3, /*deleted 1,*/ 2, 0],
910            "double ended id iter"
911        );
912
913        assert_eq!(
914            map.get_ids()
915                .map(|id| {
916                    let (_old_id, element) = map.pop().unwrap();
917                    map.insert(element);
918
919                    id.index_value()
920                })
921                .collect::<Vec<_>>(),
922
923            vec![0, /*deleted 1,*/ 2, 3],
924            "owning id iter"
925        );
926    }
927
928    #[test]
929    pub fn test_deleted_elements_iter(){
930        let mut map = id_vec!(0, 1, 2, 5);
931
932        // remove first and last element
933        map.remove(Id::from_index(0));
934        map.pop();
935
936        assert_eq!(
937            map.elements().collect::<Vec<_>>(),
938            vec![&1, &2], "iter non-removed elements"
939        );
940
941        assert_eq!(
942            map.elements().rev().collect::<Vec<_>>(),
943            vec![&2, &1], "double ended element iter"
944        );
945
946        assert_eq!(
947            map.ids()
948                .map(|id| id.index_value())
949                .collect::<Vec<_>>(),
950
951            vec![1, 2], "iter non-removed ids"
952        );
953
954        assert_eq!(
955            map.ids().rev()
956                .map(|id| id.index_value())
957                .collect::<Vec<_>>(),
958
959            vec![2, 1], "double ended id iter"
960        );
961
962        assert_eq!(
963            map.get_ids()
964                .map(|id| {
965                    let (_old_id, element) = map.pop().unwrap();
966                    map.insert(element);
967
968                    id.index_value()
969                })
970                .collect::<Vec<_>>(),
971
972            vec![1, 2],
973            "owning id iter"
974        );
975    }
976
977
978    /// Eq considers maps equal which have
979    /// the same ids pointing to the same elements
980    #[test]
981    pub fn test_eq(){
982        let mut map1 = id_vec!(0,2,2,4,4);
983        let mut map2 = id_vec!(1,2,3,4,5);
984        assert_ne!(map1, map2);
985
986        map1.remove(Id::from_index(0));
987        map1.remove(Id::from_index(2));
988        map1.remove(Id::from_index(4));
989        assert_ne!(map1, map2);
990
991        map2.remove(Id::from_index(4));
992        map2.remove(Id::from_index(0));
993        map2.remove(Id::from_index(2));
994        assert_eq!(map1, map2);
995    }
996
997
998    #[test]
999    pub fn test_elements_eq(){
1000        let     map1 = id_vec!(3,4,2,5,1);
1001        let mut map2 = id_vec!(1,2,3,4,5);
1002        assert!(map1.elements_eq(&map2));
1003
1004        map2.pop();
1005        assert!(!map1.elements_eq(&map2));
1006    }
1007
1008    #[test]
1009    pub fn test_ids_eq(){
1010        let mut map1 = id_vec!(3,4,2,5,1);
1011        let mut map2 = id_vec!(1,2,3,4,5);
1012
1013        map1.remove(Id::from_index(0));
1014        map1.remove(Id::from_index(3));
1015        assert!(!map1.ids_eq(&map2));
1016
1017        map2.remove(Id::from_index(0));
1018        map2.remove(Id::from_index(3));
1019        assert!(map1.ids_eq(&map2));
1020    }
1021
1022    #[test]
1023    pub fn test_swap(){
1024        let mut map = id_vec!(1,2,3);
1025
1026        map.swap_elements(
1027            Id::from_index(0),
1028            Id::from_index(1),
1029        );
1030
1031        assert_eq!(map.elements, vec![2, 1, 3]);
1032    }
1033
1034
1035    #[test]
1036    pub fn test_retain(){
1037        let mut map = id_vec!(1,2,3,4,5,6);
1038        map.retain(|_id, elem| {
1039            elem % 2 == 0 // keep even elements
1040        });
1041
1042        assert_eq!(map.elements().collect::<Vec<_>>(), vec![&2, &4, &6]);
1043    }
1044
1045
1046
1047    #[test]
1048    pub fn test_iter_size_hint(){
1049        let mut map = id_vec!(1,2,3,4,5,6);
1050
1051        assert_eq!(map.iter().size_hint(), (6, Some(6)));
1052        assert_eq!(map.ids().size_hint(), (6, Some(6)));
1053        assert_eq!(map.elements().size_hint(), (6, Some(6)));
1054        assert_eq!(map.get_ids().size_hint(), (6, Some(6)));
1055        assert_eq!(map.clone().into_elements().size_hint(), (6, Some(6)));
1056
1057        map.remove(Id::from_index(1));
1058        map.remove(Id::from_index(3));
1059
1060        assert_eq!(map.iter().size_hint(), (4, Some(6)));
1061        assert_eq!(map.ids().size_hint(), (4, Some(6)));
1062        assert_eq!(map.elements().size_hint(), (4, Some(6)));
1063        assert_eq!(map.get_ids().size_hint(), (4, Some(6)));
1064
1065
1066        // exact size:
1067        assert_eq!(map.clone().into_elements().size_hint(), (4, Some(4)));
1068        {
1069            let mut cloned = map.clone();
1070            let drain_size = cloned.drain_elements().size_hint();
1071            assert_eq!(drain_size, (4, Some(4)));
1072        }
1073
1074    }
1075
1076
1077
1078    #[test]
1079    pub fn test_packing(){
1080        let mut map = id_vec!(0,1,2,3,4,5,6);
1081        assert_eq!(map.elements.len(), 7);
1082        assert!(map.contains_element(&2));
1083        assert!(map.contains_element(&3));
1084        assert!(map.is_packed());
1085
1086        map.remove(Id::from_index(1));
1087        map.remove(Id::from_index(2));
1088        map.remove(Id::from_index(4));
1089
1090        assert_eq!(map.len(), 4);
1091        assert_eq!(map.elements.len(), 7);
1092        assert!(!map.contains_element(&2));
1093        assert!(map.contains_element(&3));
1094        assert!(!map.is_packed());
1095
1096        map.pack(|old_id, new_id| {
1097            assert!([4, 5, 6].contains(&old_id.index_value())); // popped element indices
1098            assert!([1, 2, 4].contains(&new_id.index_value())); // previously empty slots
1099        });
1100
1101        assert!(!map.contains_element(&2));
1102        assert!(map.contains_element(&0));
1103        assert!(map.contains_element(&3));
1104
1105        assert!(map.is_packed());
1106        assert_eq!(map.len(), 4);
1107        assert_eq!(map.elements.len(), 4);
1108    }
1109
1110
1111
1112
1113    // TODO test repeated random removing and inserting
1114
1115}