Proposal
Problem statement
Right now, if you want to pull a fixed-size chunk from the back of an iterator, you have to do a bit of a juggle. There isn't a direct way to get a chunk from the back of a DoubleEndedIterator while keeping everything in the correct order without doing multiple reversals.
Motivating examples or use cases
so motivtion here is cleaning up an old FIXME in the standard library itself. In library/core/src/iter/adapters/array_chunks.rs, the try_rfold implementation currently has to do this:
while let Ok(mut chunk) = iter.rev().next_chunk() {
// FIXME: do not do double reverse
// (we could instead add [next_chunk_back](cci:1://file:///home/centauri/open-source/rust/rust/library/core/src/array/mod.rs:1068:0-1096:1) for example)
chunk.reverse();
acc = f(acc, chunk)?
}
It’s reversing the iterator, pulling a chunk, and then reversing the array again. It works, but I feel it may not be ideal. Adding a proper next_chunk_back would let us just pull the items we need directly from the back in the right order and get rid of that workaround.
Solution sketch
I’m proposing we add next_chunk_back to DoubleEndedIterator. It’s intended to be the symmetric counterpart to the existing next_chunk.
pub trait DoubleEndedIterator: Iterator {
// ...
#[unstable(feature = "iter_next_chunk", issue = "98326")]
fn next_chunk_back<const N: usize>(
&mut self,
) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>>
where
Self: Sized,
{
crate::array::iter_next_chunk_back(self)
}
}
I’ve already got a working implementation for this in a PR. It uses a small GuardBack helper to make sure it's panic-safe—if next_back() panics halfway through, it correctly drops only the elements that were actually initialized at the end of the array.
Alternatives
We can keep the rev().next_chunk().reverse() pattern. It’s functional, but it is less efficient than it could be with FIXEME comment.
Links and related work
Proposal
Problem statement
Right now, if you want to pull a fixed-size chunk from the back of an iterator, you have to do a bit of a juggle. There isn't a direct way to get a chunk from the back of a
DoubleEndedIteratorwhile keeping everything in the correct order without doing multiple reversals.Motivating examples or use cases
so motivtion here is cleaning up an old
FIXMEin the standard library itself. Inlibrary/core/src/iter/adapters/array_chunks.rs, thetry_rfoldimplementation currently has to do this:It’s reversing the iterator, pulling a chunk, and then reversing the array again. It works, but I feel it may not be ideal. Adding a proper
next_chunk_backwould let us just pull the items we need directly from the back in the right order and get rid of that workaround.Solution sketch
I’m proposing we add
next_chunk_backtoDoubleEndedIterator. It’s intended to be the symmetric counterpart to the existingnext_chunk.I’ve already got a working implementation for this in a PR. It uses a small
GuardBackhelper to make sure it's panic-safe—ifnext_back()panics halfway through, it correctly drops only the elements that were actually initialized at the end of the array.Alternatives
We can keep the
rev().next_chunk().reverse()pattern. It’s functional, but it is less efficient than it could be withFIXEMEcomment.Links and related work