simplification: do not process the ArrayChunks remainder in fold()

This commit is contained in:
The 8472 2022-10-23 21:29:15 +02:00
parent cfcce8e684
commit 43c353fff7
2 changed files with 4 additions and 19 deletions

View File

@ -209,10 +209,6 @@ where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
if self.remainder.is_some() {
return init;
}
let mut accum = init;
let inner_len = self.iter.size();
let mut i = 0;
@ -233,20 +229,8 @@ where
i += N;
}
let remainder = inner_len % N;
let mut tail = MaybeUninit::uninit_array();
let mut guard = array::Guard { array_mut: &mut tail, initialized: 0 };
for i in 0..remainder {
// SAFETY: the remainder was not visited by the previous loop, so we're still only
// accessing each element once
let val = unsafe { self.iter.__iterator_get_unchecked(inner_len - remainder + i) };
guard.array_mut[i].write(val);
guard.initialized = i + 1;
}
mem::forget(guard);
// SAFETY: the loop above initialized elements up to the `remainder` index
self.remainder = Some(unsafe { array::IntoIter::new_unchecked(tail, 0..remainder) });
// unlike try_fold this method does not need to take care of the remainder
// since `self` will be dropped
accum
}

View File

@ -139,7 +139,8 @@ fn test_iterator_array_chunks_fold() {
let result =
(0..10).map(|_| CountDrop::new(&count)).array_chunks::<3>().fold(0, |acc, _item| acc + 1);
assert_eq!(result, 3);
assert_eq!(count.get(), 10);
// fold impls may or may not process the remainder
assert!(count.get() <= 10 && count.get() >= 9);
}
#[test]