Skip to content

Add next_chunk_back to DoubleEndedIterator #734

@vinDelphini

Description

@vinDelphini

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    ACP-acceptedAPI Change Proposal is accepted (seconded with no objections)T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions