|
| 1 | +use std::iter::Enumerate; |
1 | 2 | use std::marker::PhantomData;
|
2 | 3 |
|
3 | 4 | use crate::Idx;
|
@@ -94,12 +95,6 @@ impl<T, V> ArenaMap<Idx<T>, V> {
|
94 | 95 | .filter_map(|(idx, o)| Some((Self::from_idx(idx), o.as_mut()?)))
|
95 | 96 | }
|
96 | 97 |
|
97 |
| - /// Returns an iterator over the arena indexes and values in the map. |
98 |
| - // FIXME: Implement `IntoIterator` trait. |
99 |
| - pub fn into_iter(self) -> impl Iterator<Item = (Idx<T>, V)> + DoubleEndedIterator { |
100 |
| - self.v.into_iter().enumerate().filter_map(|(idx, o)| Some((Self::from_idx(idx), o?))) |
101 |
| - } |
102 |
| - |
103 | 98 | /// Gets the given key's corresponding entry in the map for in-place manipulation.
|
104 | 99 | pub fn entry(&mut self, idx: Idx<T>) -> Entry<'_, Idx<T>, V> {
|
105 | 100 | let idx = Self::to_idx(idx);
|
@@ -154,6 +149,63 @@ impl<T, V> FromIterator<(Idx<V>, T)> for ArenaMap<Idx<V>, T> {
|
154 | 149 | }
|
155 | 150 | }
|
156 | 151 |
|
| 152 | +pub struct ArenaMapIter<IDX, V> { |
| 153 | + iter: Enumerate<std::vec::IntoIter<Option<V>>>, |
| 154 | + _ty: PhantomData<IDX>, |
| 155 | +} |
| 156 | + |
| 157 | +impl<T, V> IntoIterator for ArenaMap<Idx<T>, V> { |
| 158 | + type Item = (Idx<T>, V); |
| 159 | + |
| 160 | + type IntoIter = ArenaMapIter<Idx<T>, V>; |
| 161 | + |
| 162 | + fn into_iter(self) -> Self::IntoIter { |
| 163 | + let iter = self.v.into_iter().enumerate(); |
| 164 | + Self::IntoIter { iter, _ty: PhantomData } |
| 165 | + } |
| 166 | +} |
| 167 | + |
| 168 | +impl<T, V> ArenaMapIter<Idx<T>, V> { |
| 169 | + fn mapper((idx, o): (usize, Option<V>)) -> Option<(Idx<T>, V)> { |
| 170 | + Some((ArenaMap::<Idx<T>, V>::from_idx(idx), o?)) |
| 171 | + } |
| 172 | +} |
| 173 | + |
| 174 | +impl<T, V> Iterator for ArenaMapIter<Idx<T>, V> { |
| 175 | + type Item = (Idx<T>, V); |
| 176 | + |
| 177 | + #[inline] |
| 178 | + fn next(&mut self) -> Option<Self::Item> { |
| 179 | + for next in self.iter.by_ref() { |
| 180 | + match Self::mapper(next) { |
| 181 | + Some(r) => return Some(r), |
| 182 | + None => continue, |
| 183 | + } |
| 184 | + } |
| 185 | + |
| 186 | + None |
| 187 | + } |
| 188 | + |
| 189 | + #[inline] |
| 190 | + fn size_hint(&self) -> (usize, Option<usize>) { |
| 191 | + self.iter.size_hint() |
| 192 | + } |
| 193 | +} |
| 194 | + |
| 195 | +impl<T, V> DoubleEndedIterator for ArenaMapIter<Idx<T>, V> { |
| 196 | + #[inline] |
| 197 | + fn next_back(&mut self) -> Option<Self::Item> { |
| 198 | + while let Some(next_back) = self.iter.next_back() { |
| 199 | + match Self::mapper(next_back) { |
| 200 | + Some(r) => return Some(r), |
| 201 | + None => continue, |
| 202 | + } |
| 203 | + } |
| 204 | + |
| 205 | + None |
| 206 | + } |
| 207 | +} |
| 208 | + |
157 | 209 | /// A view into a single entry in a map, which may either be vacant or occupied.
|
158 | 210 | ///
|
159 | 211 | /// This `enum` is constructed from the [`entry`] method on [`ArenaMap`].
|
|
0 commit comments