diff options
Diffstat (limited to 'library/core/src')
| -rw-r--r-- | library/core/src/array/iter.rs | 14 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/by_ref_sized.rs | 4 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/chain.rs | 54 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/copied.rs | 4 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/cycle.rs | 21 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/enumerate.rs | 17 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/flatten.rs | 28 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/rev.rs | 4 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/skip.rs | 49 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/take.rs | 29 | ||||
| -rw-r--r-- | library/core/src/iter/range.rs | 24 | ||||
| -rw-r--r-- | library/core/src/iter/sources/repeat.rs | 8 | ||||
| -rw-r--r-- | library/core/src/iter/sources/repeat_n.rs | 8 | ||||
| -rw-r--r-- | library/core/src/iter/traits/double_ended.rs | 28 | ||||
| -rw-r--r-- | library/core/src/iter/traits/iterator.rs | 28 | ||||
| -rw-r--r-- | library/core/src/ops/index_range.rs | 14 | ||||
| -rw-r--r-- | library/core/src/slice/iter/macros.rs | 8 |
17 files changed, 154 insertions, 188 deletions
diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index 8259c087d22..2d853dd6684 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -284,12 +284,11 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> { self.next_back() } - fn advance_by(&mut self, n: usize) -> Result<(), usize> { - let original_len = self.len(); - + fn advance_by(&mut self, n: usize) -> usize { // This also moves the start, which marks them as conceptually "dropped", // so if anything goes bad then our drop impl won't double-free them. let range_to_drop = self.alive.take_prefix(n); + let remaining = n - range_to_drop.len(); // SAFETY: These elements are currently initialized, so it's fine to drop them. unsafe { @@ -297,7 +296,7 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> { ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice)); } - if n > original_len { Err(original_len) } else { Ok(()) } + remaining } } @@ -334,12 +333,11 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> { }) } - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { - let original_len = self.len(); - + fn advance_back_by(&mut self, n: usize) -> usize { // This also moves the end, which marks them as conceptually "dropped", // so if anything goes bad then our drop impl won't double-free them. let range_to_drop = self.alive.take_suffix(n); + let remaining = n - range_to_drop.len(); // SAFETY: These elements are currently initialized, so it's fine to drop them. unsafe { @@ -347,7 +345,7 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> { ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice)); } - if n > original_len { Err(original_len) } else { Ok(()) } + remaining } } diff --git a/library/core/src/iter/adapters/by_ref_sized.rs b/library/core/src/iter/adapters/by_ref_sized.rs index 477e7117c3e..ff28e5760d0 100644 --- a/library/core/src/iter/adapters/by_ref_sized.rs +++ b/library/core/src/iter/adapters/by_ref_sized.rs @@ -26,7 +26,7 @@ impl<I: Iterator> Iterator for ByRefSized<'_, I> { } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { I::advance_by(self.0, n) } @@ -62,7 +62,7 @@ impl<I: DoubleEndedIterator> DoubleEndedIterator for ByRefSized<'_, I> { } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { I::advance_back_by(self.0, n) } diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs index d4b2640e81d..965a33de1cd 100644 --- a/library/core/src/iter/adapters/chain.rs +++ b/library/core/src/iter/adapters/chain.rs @@ -95,38 +95,33 @@ where } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { - let mut rem = n; - + fn advance_by(&mut self, mut n: usize) -> usize { if let Some(ref mut a) = self.a { - match a.advance_by(rem) { - Ok(()) => return Ok(()), - Err(k) => rem -= k, + n = a.advance_by(n); + if n == 0 { + return n; } self.a = None; } if let Some(ref mut b) = self.b { - match b.advance_by(rem) { - Ok(()) => return Ok(()), - Err(k) => rem -= k, - } + n = b.advance_by(n); // we don't fuse the second iterator } - if rem == 0 { Ok(()) } else { Err(n - rem) } + n } #[inline] fn nth(&mut self, mut n: usize) -> Option<Self::Item> { if let Some(ref mut a) = self.a { - match a.advance_by(n) { - Ok(()) => match a.next() { - None => n = 0, + n = match a.advance_by(n) { + 0 => match a.next() { + None => 0, x => return x, }, - Err(k) => n -= k, - } + k => k, + }; self.a = None; } @@ -186,38 +181,33 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { - let mut rem = n; - + fn advance_back_by(&mut self, mut n: usize) -> usize { if let Some(ref mut b) = self.b { - match b.advance_back_by(rem) { - Ok(()) => return Ok(()), - Err(k) => rem -= k, + n = b.advance_back_by(n); + if n == 0 { + return n; } self.b = None; } if let Some(ref mut a) = self.a { - match a.advance_back_by(rem) { - Ok(()) => return Ok(()), - Err(k) => rem -= k, - } + n = a.advance_back_by(n); // we don't fuse the second iterator } - if rem == 0 { Ok(()) } else { Err(n - rem) } + n } #[inline] fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> { if let Some(ref mut b) = self.b { - match b.advance_back_by(n) { - Ok(()) => match b.next_back() { - None => n = 0, + n = match b.advance_back_by(n) { + 0 => match b.next_back() { + None => 0, x => return x, }, - Err(k) => n -= k, - } + k => k, + }; self.b = None; } diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index a076ab925e3..7533de588db 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -89,7 +89,7 @@ where } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { self.it.advance_by(n) } @@ -130,7 +130,7 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { self.it.advance_back_by(n) } } diff --git a/library/core/src/iter/adapters/cycle.rs b/library/core/src/iter/adapters/cycle.rs index 02b5939072e..2d1fcf667bf 100644 --- a/library/core/src/iter/adapters/cycle.rs +++ b/library/core/src/iter/adapters/cycle.rs @@ -81,23 +81,22 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { - let mut rem = n; - match self.iter.advance_by(rem) { - ret @ Ok(_) => return ret, - Err(advanced) => rem -= advanced, + fn advance_by(&mut self, n: usize) -> usize { + let mut n = self.iter.advance_by(n); + if n == 0 { + return n; } - while rem > 0 { + while n > 0 { self.iter = self.orig.clone(); - match self.iter.advance_by(rem) { - ret @ Ok(_) => return ret, - Err(0) => return Err(n - rem), - Err(advanced) => rem -= advanced, + let rem = self.iter.advance_by(n); + if rem == n { + return n; } + n = rem; } - Ok(()) + 0 } // No `fold` override, because `fold` doesn't make much sense for `Cycle`, diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index 8c32a35a12f..30017d13a6c 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -114,17 +114,10 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { - match self.iter.advance_by(n) { - ret @ Ok(_) => { - self.count += n; - ret - } - ret @ Err(advanced) => { - self.count += advanced; - ret - } - } + fn advance_by(&mut self, n: usize) -> usize { + let n = self.iter.advance_by(n); + self.count += n; + n } #[rustc_inherit_overflow_checks] @@ -208,7 +201,7 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { // we do not need to update the count since that only tallies the number of items // consumed from the front. consuming items from the back can never reduce that. self.iter.advance_back_by(n) diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index e4020c45f71..980c4bebc97 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -75,7 +75,7 @@ where } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { self.inner.advance_by(n) } @@ -120,7 +120,7 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { self.inner.advance_back_by(n) } } @@ -236,7 +236,7 @@ where } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { self.inner.advance_by(n) } @@ -281,7 +281,7 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { self.inner.advance_back_by(n) } } @@ -552,19 +552,19 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { #[inline] #[rustc_inherit_overflow_checks] fn advance<U: Iterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> { match iter.advance_by(n) { - Ok(()) => ControlFlow::Break(()), - Err(advanced) => ControlFlow::Continue(n - advanced), + 0 => ControlFlow::Break(()), + remaining => ControlFlow::Continue(remaining), } } match self.iter_try_fold(n, advance) { - ControlFlow::Continue(remaining) if remaining > 0 => Err(n - remaining), - _ => Ok(()), + ControlFlow::Continue(remaining) => remaining, + _ => 0, } } @@ -642,19 +642,19 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { #[inline] #[rustc_inherit_overflow_checks] fn advance<U: DoubleEndedIterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> { match iter.advance_back_by(n) { - Ok(()) => ControlFlow::Break(()), - Err(advanced) => ControlFlow::Continue(n - advanced), + 0 => ControlFlow::Break(()), + remaining => ControlFlow::Continue(remaining), } } match self.iter_try_rfold(n, advance) { - ControlFlow::Continue(remaining) if remaining > 0 => Err(n - remaining), - _ => Ok(()), + ControlFlow::Continue(remaining) => remaining, + _ => 0, } } } diff --git a/library/core/src/iter/adapters/rev.rs b/library/core/src/iter/adapters/rev.rs index 8ae6d96fde4..b64baf838a2 100644 --- a/library/core/src/iter/adapters/rev.rs +++ b/library/core/src/iter/adapters/rev.rs @@ -38,7 +38,7 @@ where } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { self.iter.advance_back_by(n) } @@ -83,7 +83,7 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { self.iter.advance_by(n) } diff --git a/library/core/src/iter/adapters/skip.rs b/library/core/src/iter/adapters/skip.rs index c6334880db5..bb32e19b542 100644 --- a/library/core/src/iter/adapters/skip.rs +++ b/library/core/src/iter/adapters/skip.rs @@ -128,34 +128,21 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { - let mut rem = n; - let step_one = self.n.saturating_add(rem); - - match self.iter.advance_by(step_one) { - Ok(_) => { - rem -= step_one - self.n; - self.n = 0; - } - Err(advanced) => { - let advanced_without_skip = advanced.saturating_sub(self.n); - self.n = self.n.saturating_sub(advanced); - return if n == 0 { Ok(()) } else { Err(advanced_without_skip) }; - } - } - - // step_one calculation may have saturated - if unlikely(rem > 0) { - return match self.iter.advance_by(rem) { - ret @ Ok(_) => ret, - Err(advanced) => { - rem -= advanced; - Err(n - rem) - } - }; + fn advance_by(&mut self, mut n: usize) -> usize { + let skip_inner = self.n; + let skip_and_advance = skip_inner.saturating_add(n); + + let remainder = self.iter.advance_by(skip_and_advance); + let advanced_inner = skip_and_advance - remainder; + n -= advanced_inner.saturating_sub(skip_inner); + self.n = self.n.saturating_sub(advanced_inner); + + // skip_and_advance may have saturated + if unlikely(remainder == 0 && n > 0) { + n = self.iter.advance_by(n); } - Ok(()) + n } } @@ -209,13 +196,13 @@ where impl_fold_via_try_fold! { rfold -> try_rfold } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { let min = crate::cmp::min(self.len(), n); - return match self.iter.advance_back_by(min) { - ret @ Ok(_) if n <= min => ret, - Ok(_) => Err(min), - _ => panic!("ExactSizeIterator contract violation"), + let rem = self.iter.advance_back_by(min); + if rem != 0 { + panic!("ExactSizeIterator contract violation"); }; + n - min } } diff --git a/library/core/src/iter/adapters/take.rs b/library/core/src/iter/adapters/take.rs index d947c7b0e30..12e2395fe68 100644 --- a/library/core/src/iter/adapters/take.rs +++ b/library/core/src/iter/adapters/take.rs @@ -121,18 +121,12 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { let min = self.n.min(n); - match self.iter.advance_by(min) { - Ok(_) => { - self.n -= min; - if min < n { Err(min) } else { Ok(()) } - } - ret @ Err(advanced) => { - self.n -= advanced; - ret - } - } + let rem = self.iter.advance_by(min); + let advanced = min - rem; + self.n -= advanced; + n - advanced } } @@ -223,7 +217,7 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { // The amount by which the inner iterator needs to be shortened for it to be // at most as long as the take() amount. let trim_inner = self.iter.len().saturating_sub(self.n); @@ -232,12 +226,11 @@ where // about having to advance more than usize::MAX here. let advance_by = trim_inner.saturating_add(n); - let advanced = match self.iter.advance_back_by(advance_by) { - Ok(_) => advance_by - trim_inner, - Err(advanced) => advanced - trim_inner, - }; - self.n -= advanced; - return if advanced < n { Err(advanced) } else { Ok(()) }; + let remainder = self.iter.advance_back_by(advance_by); + let advanced_by_inner = advance_by - remainder; + let advanced_by = advanced_by_inner - trim_inner; + self.n -= advanced_by; + n - advanced_by } } diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index f19636fba5d..63c719f8b3a 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -530,12 +530,12 @@ trait RangeIteratorImpl { // Iterator fn spec_next(&mut self) -> Option<Self::Item>; fn spec_nth(&mut self, n: usize) -> Option<Self::Item>; - fn spec_advance_by(&mut self, n: usize) -> Result<(), usize>; + fn spec_advance_by(&mut self, n: usize) -> usize; // DoubleEndedIterator fn spec_next_back(&mut self) -> Option<Self::Item>; fn spec_nth_back(&mut self, n: usize) -> Option<Self::Item>; - fn spec_advance_back_by(&mut self, n: usize) -> Result<(), usize>; + fn spec_advance_back_by(&mut self, n: usize) -> usize; } impl<A: ~const Step + ~const Destruct> const RangeIteratorImpl for ops::Range<A> { @@ -567,7 +567,7 @@ impl<A: ~const Step + ~const Destruct> const RangeIteratorImpl for ops::Range<A> } #[inline] - default fn spec_advance_by(&mut self, n: usize) -> Result<(), usize> { + default fn spec_advance_by(&mut self, n: usize) -> usize { let available = if self.start <= self.end { Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) } else { @@ -579,7 +579,7 @@ impl<A: ~const Step + ~const Destruct> const RangeIteratorImpl for ops::Range<A> self.start = Step::forward_checked(self.start.clone(), taken).expect("`Step` invariants not upheld"); - if taken < n { Err(taken) } else { Ok(()) } + n - taken } #[inline] @@ -608,7 +608,7 @@ impl<A: ~const Step + ~const Destruct> const RangeIteratorImpl for ops::Range<A> } #[inline] - default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), usize> { + default fn spec_advance_back_by(&mut self, n: usize) -> usize { let available = if self.start <= self.end { Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) } else { @@ -620,7 +620,7 @@ impl<A: ~const Step + ~const Destruct> const RangeIteratorImpl for ops::Range<A> self.end = Step::backward_checked(self.end.clone(), taken).expect("`Step` invariants not upheld"); - if taken < n { Err(taken) } else { Ok(()) } + n - taken } } @@ -651,7 +651,7 @@ impl<T: ~const TrustedStep + ~const Destruct> const RangeIteratorImpl for ops::R } #[inline] - fn spec_advance_by(&mut self, n: usize) -> Result<(), usize> { + fn spec_advance_by(&mut self, n: usize) -> usize { let available = if self.start <= self.end { Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) } else { @@ -666,7 +666,7 @@ impl<T: ~const TrustedStep + ~const Destruct> const RangeIteratorImpl for ops::R // Otherwise 0 is returned which always safe to use. self.start = unsafe { Step::forward_unchecked(self.start.clone(), taken) }; - if taken < n { Err(taken) } else { Ok(()) } + n - taken } #[inline] @@ -695,7 +695,7 @@ impl<T: ~const TrustedStep + ~const Destruct> const RangeIteratorImpl for ops::R } #[inline] - fn spec_advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn spec_advance_back_by(&mut self, n: usize) -> usize { let available = if self.start <= self.end { Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) } else { @@ -707,7 +707,7 @@ impl<T: ~const TrustedStep + ~const Destruct> const RangeIteratorImpl for ops::R // SAFETY: same as the spec_advance_by() implementation self.end = unsafe { Step::backward_unchecked(self.end.clone(), taken) }; - if taken < n { Err(taken) } else { Ok(()) } + n - taken } } @@ -757,7 +757,7 @@ impl<A: ~const Step + ~const Destruct> const Iterator for ops::Range<A> { } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { self.spec_advance_by(n) } @@ -836,7 +836,7 @@ impl<A: ~const Step + ~const Destruct> const DoubleEndedIterator for ops::Range< } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { self.spec_advance_back_by(n) } } diff --git a/library/core/src/iter/sources/repeat.rs b/library/core/src/iter/sources/repeat.rs index 733142ed011..56a6d973705 100644 --- a/library/core/src/iter/sources/repeat.rs +++ b/library/core/src/iter/sources/repeat.rs @@ -80,10 +80,10 @@ impl<A: Clone> Iterator for Repeat<A> { } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { // Advancing an infinite iterator of a single element is a no-op. let _ = n; - Ok(()) + 0 } #[inline] @@ -109,10 +109,10 @@ impl<A: Clone> DoubleEndedIterator for Repeat<A> { } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { // Advancing an infinite iterator of a single element is a no-op. let _ = n; - Ok(()) + 0 } #[inline] diff --git a/library/core/src/iter/sources/repeat_n.rs b/library/core/src/iter/sources/repeat_n.rs index dc61d6065b8..918f2a36ed0 100644 --- a/library/core/src/iter/sources/repeat_n.rs +++ b/library/core/src/iter/sources/repeat_n.rs @@ -137,7 +137,7 @@ impl<A: Clone> Iterator for RepeatN<A> { } #[inline] - fn advance_by(&mut self, skip: usize) -> Result<(), usize> { + fn advance_by(&mut self, skip: usize) -> usize { let len = self.count; if skip >= len { @@ -145,10 +145,10 @@ impl<A: Clone> Iterator for RepeatN<A> { } if skip > len { - Err(len) + skip - len } else { self.count = len - skip; - Ok(()) + 0 } } @@ -178,7 +178,7 @@ impl<A: Clone> DoubleEndedIterator for RepeatN<A> { } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { self.advance_by(n) } diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index 7a10dea500a..06538d61aa0 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -100,10 +100,10 @@ pub trait DoubleEndedIterator: Iterator { /// eagerly skip `n` elements starting from the back by calling [`next_back`] up /// to `n` times until [`None`] is encountered. /// - /// `advance_back_by(n)` will return [`Ok(())`] if the iterator successfully advances by - /// `n` elements, or [`Err(k)`] if [`None`] is encountered, where `k` is the number of - /// elements the iterator is advanced by before running out of elements (i.e. the length - /// of the iterator). Note that `k` is always less than `n`. + /// `advance_back_by(n)` will return `0` if the iterator successfully advances by + /// `n` elements, or an usize `k` if [`None`] is encountered, where `k` is remaining number + /// of steps that could not be advanced because the iterator ran out. + /// Note that `k` is always less than `n`. /// /// Calling `advance_back_by(0)` can do meaningful work, for example [`Flatten`] can advance its /// outer iterator until it finds an inner iterator that is not empty, which then often @@ -123,24 +123,26 @@ pub trait DoubleEndedIterator: Iterator { /// let a = [3, 4, 5, 6]; /// let mut iter = a.iter(); /// - /// assert_eq!(iter.advance_back_by(2), Ok(())); + /// assert_eq!(iter.advance_back_by(2), 0); /// assert_eq!(iter.next_back(), Some(&4)); - /// assert_eq!(iter.advance_back_by(0), Ok(())); - /// assert_eq!(iter.advance_back_by(100), Err(1)); // only `&3` was skipped + /// assert_eq!(iter.advance_back_by(0), 0); + /// assert_eq!(iter.advance_back_by(100), 99); // only `&3` was skipped /// ``` /// /// [`Ok(())`]: Ok /// [`Err(k)`]: Err #[inline] #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> + fn advance_back_by(&mut self, n: usize) -> usize where Self::Item: ~const Destruct, { for i in 0..n { - self.next_back().ok_or(i)?; + if self.next_back().is_none() { + return n - i; + } } - Ok(()) + 0 } /// Returns the `n`th element from the end of the iterator. @@ -188,7 +190,9 @@ pub trait DoubleEndedIterator: Iterator { #[stable(feature = "iter_nth_back", since = "1.37.0")] #[rustc_do_not_const_check] fn nth_back(&mut self, n: usize) -> Option<Self::Item> { - self.advance_back_by(n).ok()?; + if self.advance_back_by(n) > 0 { + return None; + } self.next_back() } @@ -374,7 +378,7 @@ impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I { fn next_back(&mut self) -> Option<I::Item> { (**self).next_back() } - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { (**self).advance_back_by(n) } fn nth_back(&mut self, n: usize) -> Option<I::Item> { diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 16c9f668b8e..f2de040c635 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -308,10 +308,10 @@ pub trait Iterator { /// This method will eagerly skip `n` elements by calling [`next`] up to `n` /// times until [`None`] is encountered. /// - /// `advance_by(n)` will return [`Ok(())`][Ok] if the iterator successfully advances by - /// `n` elements, or [`Err(k)`][Err] if [`None`] is encountered, where `k` is the number - /// of elements the iterator is advanced by before running out of elements (i.e. the - /// length of the iterator). Note that `k` is always less than `n`. + /// `advance_by(n)` will return `0` if the iterator successfully advances by + /// `n` elements, or an usize `k` if [`None`] is encountered, where `k` is remaining number + /// of steps that could not be advanced because the iterator ran out. + /// Note that `k` is always less than `n`. /// /// Calling `advance_by(0)` can do meaningful work, for example [`Flatten`] /// can advance its outer iterator until it finds an inner iterator that is not empty, which @@ -330,21 +330,23 @@ pub trait Iterator { /// let a = [1, 2, 3, 4]; /// let mut iter = a.iter(); /// - /// assert_eq!(iter.advance_by(2), Ok(())); + /// assert_eq!(iter.advance_by(2), 0); /// assert_eq!(iter.next(), Some(&3)); - /// assert_eq!(iter.advance_by(0), Ok(())); - /// assert_eq!(iter.advance_by(100), Err(1)); // only `&4` was skipped + /// assert_eq!(iter.advance_by(0), 0); + /// assert_eq!(iter.advance_by(100), 99); // only `&4` was skipped /// ``` #[inline] #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")] - fn advance_by(&mut self, n: usize) -> Result<(), usize> + fn advance_by(&mut self, n: usize) -> usize where Self::Item: ~const Destruct, { for i in 0..n { - self.next().ok_or(i)?; + if self.next().is_none() { + return n - i; + } } - Ok(()) + 0 } /// Returns the `n`th element of the iterator. @@ -392,7 +394,9 @@ pub trait Iterator { where Self::Item: ~const Destruct, { - self.advance_by(n).ok()?; + if self.advance_by(n) > 0 { + return None; + } self.next() } @@ -4013,7 +4017,7 @@ impl<I: Iterator + ?Sized> Iterator for &mut I { fn size_hint(&self) -> (usize, Option<usize>) { (**self).size_hint() } - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { (**self).advance_by(n) } fn nth(&mut self, n: usize) -> Option<Self::Item> { diff --git a/library/core/src/ops/index_range.rs b/library/core/src/ops/index_range.rs index 3e06776d2c6..744ec3b0245 100644 --- a/library/core/src/ops/index_range.rs +++ b/library/core/src/ops/index_range.rs @@ -132,10 +132,9 @@ impl Iterator for IndexRange { } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { - let original_len = self.len(); - self.take_prefix(n); - if n > original_len { Err(original_len) } else { Ok(()) } + fn advance_by(&mut self, n: usize) -> usize { + let taken = self.take_prefix(n); + n - taken.len() } } @@ -151,10 +150,9 @@ impl DoubleEndedIterator for IndexRange { } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { - let original_len = self.len(); - self.take_suffix(n); - if n > original_len { Err(original_len) } else { Ok(()) } + fn advance_back_by(&mut self, n: usize) -> usize { + let taken = self.take_suffix(n); + n - taken.len() } } diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index a800da546b4..d3e9b9c2b22 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -176,11 +176,11 @@ macro_rules! iterator { } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { let advance = cmp::min(len!(self), n); // SAFETY: By construction, `advance` does not exceed `self.len()`. unsafe { self.post_inc_start(advance) }; - if advance == n { Ok(()) } else { Err(advance) } + n - advance } #[inline] @@ -371,11 +371,11 @@ macro_rules! iterator { } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { let advance = cmp::min(len!(self), n); // SAFETY: By construction, `advance` does not exceed `self.len()`. unsafe { self.pre_dec_end(advance) }; - if advance == n { Ok(()) } else { Err(advance) } + n - advance } } |
