use crate::{ const_closure::ConstFnMutClosure, ops::{NeverShortCircuit, Try}, }; /// Like `Iterator::by_ref`, but requiring `Sized` so it can forward generics. /// /// Ideally this will no longer be required, eventually, but as can be seen in /// the benchmarks (as of Feb 2022 at least) `by_ref` can have performance cost. #[unstable(feature = "std_internals", issue = "none")] #[derive(Debug)] pub struct ByRefSized<'a, I>(pub &'a mut I); // The following implementations use UFCS-style, rather than trusting autoderef, // to avoid accidentally calling the `&mut Iterator` implementations. #[unstable(feature = "std_internals", issue = "none")] impl Iterator for ByRefSized<'_, I> { type Item = I::Item; #[inline] fn next(&mut self) -> Option { I::next(self.0) } #[inline] fn size_hint(&self) -> (usize, Option) { I::size_hint(self.0) } #[inline] fn advance_by(&mut self, n: usize) -> Result<(), usize> { I::advance_by(self.0, n) } #[inline] fn nth(&mut self, n: usize) -> Option { I::nth(self.0, n) } #[inline] fn fold(self, init: B, mut f: F) -> B where F: FnMut(B, Self::Item) -> B, { // `fold` needs ownership, so this can't forward directly. I::try_fold(self.0, init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp)) .0 } #[inline] fn try_fold(&mut self, init: B, f: F) -> R where F: FnMut(B, Self::Item) -> R, R: Try, { I::try_fold(self.0, init, f) } } #[unstable(feature = "std_internals", issue = "none")] impl DoubleEndedIterator for ByRefSized<'_, I> { #[inline] fn next_back(&mut self) -> Option { I::next_back(self.0) } #[inline] fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { I::advance_back_by(self.0, n) } #[inline] fn nth_back(&mut self, n: usize) -> Option { I::nth_back(self.0, n) } #[inline] fn rfold(self, init: B, mut f: F) -> B where F: FnMut(B, Self::Item) -> B, { // `rfold` needs ownership, so this can't forward directly. I::try_rfold( self.0, init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp), ) .0 } #[inline] fn try_rfold(&mut self, init: B, f: F) -> R where F: FnMut(B, Self::Item) -> R, R: Try, { I::try_rfold(self.0, init, f) } }