diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index bdf94c792c27c..8064b96ffbac1 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -362,13 +362,68 @@ pub trait DoubleEndedIterator: Iterator { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I { + #[inline] fn next_back(&mut self) -> Option { (**self).next_back() } + #[inline] fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { (**self).advance_back_by(n) } + #[inline] fn nth_back(&mut self, n: usize) -> Option { (**self).nth_back(n) } + #[inline] + fn try_rfold(&mut self, init: B, f: F) -> R + where + F: FnMut(B, Self::Item) -> R, + R: Try, + { + ByRefRFold::try_rfold(self, init, f) + } + #[inline] + fn rfold(mut self, init: B, f: F) -> B + where + F: FnMut(B, Self::Item) -> B, + { + #[inline] + fn ok(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result { + move |acc, x| Ok(f(acc, x)) + } + ByRefRFold::try_rfold(&mut self, init, ok(f)).unwrap() + } +} + +trait ByRefRFold: DoubleEndedIterator { + fn try_rfold(&mut self, init: B, f: F) -> R + where + F: FnMut(B, Self::Item) -> R, + R: Try; +} + +impl<'a, I: DoubleEndedIterator + ?Sized> ByRefRFold for &'a mut I { + #[inline] + default fn try_rfold(&mut self, init: B, mut f: F) -> R + where + F: FnMut(B, Self::Item) -> R, + R: Try, + { + let mut accum = init; + while let Some(x) = self.next() { + accum = f(accum, x)?; + } + try { accum } + } +} + +impl<'a, I: DoubleEndedIterator + Sized> ByRefRFold for &'a mut I { + #[inline] + default fn try_rfold(&mut self, init: B, f: F) -> R + where + F: FnMut(B, Self::Item) -> R, + R: Try, + { + (**self).try_rfold(init, f) + } } diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 275412b57b55f..0c5e43dda9989 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2076,11 +2076,12 @@ pub trait Iterator { /// assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds /// ``` #[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "62543")] - fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize + fn partition_in_place<'a, T: 'a, P>(mut self, mut predicate: P) -> usize where Self: Sized + DoubleEndedIterator, P: FnMut(&T) -> bool, { + let predicate = &mut predicate; // FIXME: should we worry about the count overflowing? The only way to have more than // `usize::MAX` mutable references is with ZSTs, which aren't useful to partition... @@ -3824,13 +3825,68 @@ impl Iterator for &mut I { fn next(&mut self) -> Option { (**self).next() } + #[inline] fn size_hint(&self) -> (usize, Option) { (**self).size_hint() } + #[inline] fn advance_by(&mut self, n: usize) -> Result<(), usize> { (**self).advance_by(n) } + #[inline] fn nth(&mut self, n: usize) -> Option { (**self).nth(n) } + #[inline] + fn try_fold(&mut self, init: B, f: F) -> R + where + F: FnMut(B, Self::Item) -> R, + R: Try, + { + ByRefFold::try_fold(self, init, f) + } + #[inline] + fn fold(mut self, init: B, f: F) -> B + where + F: FnMut(B, Self::Item) -> B, + { + #[inline] + fn ok(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result { + move |acc, x| Ok(f(acc, x)) + } + ByRefFold::try_fold(&mut self, init, ok(f)).unwrap() + } +} + +trait ByRefFold: Iterator { + fn try_fold(&mut self, init: B, f: F) -> R + where + F: FnMut(B, Self::Item) -> R, + R: Try; +} + +impl<'a, I: Iterator + ?Sized> ByRefFold for &'a mut I { + #[inline] + default fn try_fold(&mut self, init: B, mut f: F) -> R + where + F: FnMut(B, Self::Item) -> R, + R: Try, + { + let mut accum = init; + while let Some(x) = self.next() { + accum = f(accum, x)?; + } + try { accum } + } +} + +impl<'a, I: Iterator + Sized> ByRefFold for &'a mut I { + #[inline] + default fn try_fold(&mut self, init: B, f: F) -> R + where + F: FnMut(B, Self::Item) -> R, + R: Try, + { + (**self).try_fold(init, f) + } }