1 use crate::iter::adapters::{ 2 zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce, 3 }; 4 use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen}; 5 use crate::ops::Try; 6 7 /// An iterator that yields the current count and the element during iteration. 8 /// 9 /// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its 10 /// documentation for more. 11 /// 12 /// [`enumerate`]: Iterator::enumerate 13 /// [`Iterator`]: trait.Iterator.html 14 #[derive(Clone, Debug)] 15 #[must_use = "iterators are lazy and do nothing unless consumed"] 16 #[stable(feature = "rust1", since = "1.0.0")] 17 pub struct Enumerate<I> { 18 iter: I, 19 count: usize, 20 } 21 impl<I> Enumerate<I> { new(iter: I) -> Enumerate<I>22 pub(in crate::iter) fn new(iter: I) -> Enumerate<I> { 23 Enumerate { iter, count: 0 } 24 } 25 } 26 27 #[stable(feature = "rust1", since = "1.0.0")] 28 impl<I> Iterator for Enumerate<I> 29 where 30 I: Iterator, 31 { 32 type Item = (usize, <I as Iterator>::Item); 33 34 /// # Overflow Behavior 35 /// 36 /// The method does no guarding against overflows, so enumerating more than 37 /// `usize::MAX` elements either produces the wrong result or panics. If 38 /// debug assertions are enabled, a panic is guaranteed. 39 /// 40 /// # Panics 41 /// 42 /// Might panic if the index of the element overflows a `usize`. 43 #[inline] 44 #[rustc_inherit_overflow_checks] next(&mut self) -> Option<(usize, <I as Iterator>::Item)>45 fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> { 46 let a = self.iter.next()?; 47 let i = self.count; 48 self.count += 1; 49 Some((i, a)) 50 } 51 52 #[inline] size_hint(&self) -> (usize, Option<usize>)53 fn size_hint(&self) -> (usize, Option<usize>) { 54 self.iter.size_hint() 55 } 56 57 #[inline] 58 #[rustc_inherit_overflow_checks] nth(&mut self, n: usize) -> Option<(usize, I::Item)>59 fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> { 60 let a = self.iter.nth(n)?; 61 let i = self.count + n; 62 self.count = i + 1; 63 Some((i, a)) 64 } 65 66 #[inline] count(self) -> usize67 fn count(self) -> usize { 68 self.iter.count() 69 } 70 71 #[inline] try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Output = Acc>,72 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R 73 where 74 Self: Sized, 75 Fold: FnMut(Acc, Self::Item) -> R, 76 R: Try<Output = Acc>, 77 { 78 #[inline] 79 fn enumerate<'a, T, Acc, R>( 80 count: &'a mut usize, 81 mut fold: impl FnMut(Acc, (usize, T)) -> R + 'a, 82 ) -> impl FnMut(Acc, T) -> R + 'a { 83 #[rustc_inherit_overflow_checks] 84 move |acc, item| { 85 let acc = fold(acc, (*count, item)); 86 *count += 1; 87 acc 88 } 89 } 90 91 self.iter.try_fold(init, enumerate(&mut self.count, fold)) 92 } 93 94 #[inline] fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc,95 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc 96 where 97 Fold: FnMut(Acc, Self::Item) -> Acc, 98 { 99 #[inline] 100 fn enumerate<T, Acc>( 101 mut count: usize, 102 mut fold: impl FnMut(Acc, (usize, T)) -> Acc, 103 ) -> impl FnMut(Acc, T) -> Acc { 104 #[rustc_inherit_overflow_checks] 105 move |acc, item| { 106 let acc = fold(acc, (count, item)); 107 count += 1; 108 acc 109 } 110 } 111 112 self.iter.fold(init, enumerate(self.count, fold)) 113 } 114 115 #[inline] 116 #[rustc_inherit_overflow_checks] advance_by(&mut self, n: usize) -> Result<(), usize>117 fn advance_by(&mut self, n: usize) -> Result<(), usize> { 118 match self.iter.advance_by(n) { 119 ret @ Ok(_) => { 120 self.count += n; 121 ret 122 } 123 ret @ Err(advanced) => { 124 self.count += advanced; 125 ret 126 } 127 } 128 } 129 130 #[rustc_inherit_overflow_checks] 131 #[doc(hidden)] __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item where Self: TrustedRandomAccessNoCoerce,132 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item 133 where 134 Self: TrustedRandomAccessNoCoerce, 135 { 136 // SAFETY: the caller must uphold the contract for 137 // `Iterator::__iterator_get_unchecked`. 138 let value = unsafe { try_get_unchecked(&mut self.iter, idx) }; 139 (self.count + idx, value) 140 } 141 } 142 143 #[stable(feature = "rust1", since = "1.0.0")] 144 impl<I> DoubleEndedIterator for Enumerate<I> 145 where 146 I: ExactSizeIterator + DoubleEndedIterator, 147 { 148 #[inline] next_back(&mut self) -> Option<(usize, <I as Iterator>::Item)>149 fn next_back(&mut self) -> Option<(usize, <I as Iterator>::Item)> { 150 let a = self.iter.next_back()?; 151 let len = self.iter.len(); 152 // Can safely add, `ExactSizeIterator` promises that the number of 153 // elements fits into a `usize`. 154 Some((self.count + len, a)) 155 } 156 157 #[inline] nth_back(&mut self, n: usize) -> Option<(usize, <I as Iterator>::Item)>158 fn nth_back(&mut self, n: usize) -> Option<(usize, <I as Iterator>::Item)> { 159 let a = self.iter.nth_back(n)?; 160 let len = self.iter.len(); 161 // Can safely add, `ExactSizeIterator` promises that the number of 162 // elements fits into a `usize`. 163 Some((self.count + len, a)) 164 } 165 166 #[inline] try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Output = Acc>,167 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R 168 where 169 Self: Sized, 170 Fold: FnMut(Acc, Self::Item) -> R, 171 R: Try<Output = Acc>, 172 { 173 // Can safely add and subtract the count, as `ExactSizeIterator` promises 174 // that the number of elements fits into a `usize`. 175 fn enumerate<T, Acc, R>( 176 mut count: usize, 177 mut fold: impl FnMut(Acc, (usize, T)) -> R, 178 ) -> impl FnMut(Acc, T) -> R { 179 move |acc, item| { 180 count -= 1; 181 fold(acc, (count, item)) 182 } 183 } 184 185 let count = self.count + self.iter.len(); 186 self.iter.try_rfold(init, enumerate(count, fold)) 187 } 188 189 #[inline] rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc,190 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc 191 where 192 Fold: FnMut(Acc, Self::Item) -> Acc, 193 { 194 // Can safely add and subtract the count, as `ExactSizeIterator` promises 195 // that the number of elements fits into a `usize`. 196 fn enumerate<T, Acc>( 197 mut count: usize, 198 mut fold: impl FnMut(Acc, (usize, T)) -> Acc, 199 ) -> impl FnMut(Acc, T) -> Acc { 200 move |acc, item| { 201 count -= 1; 202 fold(acc, (count, item)) 203 } 204 } 205 206 let count = self.count + self.iter.len(); 207 self.iter.rfold(init, enumerate(count, fold)) 208 } 209 210 #[inline] advance_back_by(&mut self, n: usize) -> Result<(), usize>211 fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { 212 // we do not need to update the count since that only tallies the number of items 213 // consumed from the front. consuming items from the back can never reduce that. 214 self.iter.advance_back_by(n) 215 } 216 } 217 218 #[stable(feature = "rust1", since = "1.0.0")] 219 impl<I> ExactSizeIterator for Enumerate<I> 220 where 221 I: ExactSizeIterator, 222 { len(&self) -> usize223 fn len(&self) -> usize { 224 self.iter.len() 225 } 226 is_empty(&self) -> bool227 fn is_empty(&self) -> bool { 228 self.iter.is_empty() 229 } 230 } 231 232 #[doc(hidden)] 233 #[unstable(feature = "trusted_random_access", issue = "none")] 234 unsafe impl<I> TrustedRandomAccess for Enumerate<I> where I: TrustedRandomAccess {} 235 236 #[doc(hidden)] 237 #[unstable(feature = "trusted_random_access", issue = "none")] 238 unsafe impl<I> TrustedRandomAccessNoCoerce for Enumerate<I> 239 where 240 I: TrustedRandomAccessNoCoerce, 241 { 242 const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT; 243 } 244 245 #[stable(feature = "fused", since = "1.26.0")] 246 impl<I> FusedIterator for Enumerate<I> where I: FusedIterator {} 247 248 #[unstable(feature = "trusted_len", issue = "37572")] 249 unsafe impl<I> TrustedLen for Enumerate<I> where I: TrustedLen {} 250 251 #[unstable(issue = "none", feature = "inplace_iteration")] 252 unsafe impl<I> SourceIter for Enumerate<I> 253 where 254 I: SourceIter, 255 { 256 type Source = I::Source; 257 258 #[inline] as_inner(&mut self) -> &mut I::Source259 unsafe fn as_inner(&mut self) -> &mut I::Source { 260 // SAFETY: unsafe function forwarding to unsafe function with the same requirements 261 unsafe { SourceIter::as_inner(&mut self.iter) } 262 } 263 } 264 265 #[unstable(issue = "none", feature = "inplace_iteration")] 266 unsafe impl<I: InPlaceIterable> InPlaceIterable for Enumerate<I> {} 267