1 //! A double-ended iterator over entity references.
2 //!
3 //! When `core::iter::Step` is stabilized, `Keys` could be implemented as a wrapper around
4 //! `core::ops::Range`, but for now, we implement it manually.
5 
6 use crate::EntityRef;
7 use core::marker::PhantomData;
8 
9 /// Iterate over all keys in order.
10 pub struct Keys<K: EntityRef> {
11     pos: usize,
12     rev_pos: usize,
13     unused: PhantomData<K>,
14 }
15 
16 impl<K: EntityRef> Keys<K> {
17     /// Create a `Keys` iterator that visits `len` entities starting from 0.
with_len(len: usize) -> Self18     pub fn with_len(len: usize) -> Self {
19         Self {
20             pos: 0,
21             rev_pos: len,
22             unused: PhantomData,
23         }
24     }
25 }
26 
27 impl<K: EntityRef> Iterator for Keys<K> {
28     type Item = K;
29 
next(&mut self) -> Option<Self::Item>30     fn next(&mut self) -> Option<Self::Item> {
31         if self.pos < self.rev_pos {
32             let k = K::new(self.pos);
33             self.pos += 1;
34             Some(k)
35         } else {
36             None
37         }
38     }
39 
size_hint(&self) -> (usize, Option<usize>)40     fn size_hint(&self) -> (usize, Option<usize>) {
41         let size = self.rev_pos - self.pos;
42         (size, Some(size))
43     }
44 }
45 
46 impl<K: EntityRef> DoubleEndedIterator for Keys<K> {
next_back(&mut self) -> Option<Self::Item>47     fn next_back(&mut self) -> Option<Self::Item> {
48         if self.rev_pos > self.pos {
49             let k = K::new(self.rev_pos - 1);
50             self.rev_pos -= 1;
51             Some(k)
52         } else {
53             None
54         }
55     }
56 }
57 
58 impl<K: EntityRef> ExactSizeIterator for Keys<K> {}
59