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