-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Iterator::advance_by and DoubleEndedIterator::advance_back_by #76909
Conversation
r? @dtolnay (rust_highfive has picked a reviewer for you, use r? to override) |
I'll add that this would also make I find this change pretty elegant: #[inline]
fn last(mut self) -> Option<I::Item> {
- if self.n > 0 {
- // nth(n) skips n+1
- self.iter.nth(self.n - 1)?;
- }
+ self.iter.advance_by(self.n).ok()?;
self.iter.last()
} Both for simpler code and because it folds the Edit: It would also accomplish the goal I'd mentioned in https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Eager.20skipping.20for.20iterators/near/209044788. The suggested solution in https://users.rust-lang.org/t/hide-beginning-of-vec/48274/3?u=scottmcm wouldn't need the |
3e4e529
to
ecacc75
Compare
The problem with using |
Yeah, code that calls For a couple iterator types that don't wrap another iterator (such as |
If advance_by were implemented on |
@the8472 You're certainly right, but on Implementing |
@bors r+ |
📌 Commit ecacc75 has been approved by |
Rollup of 12 pull requests Successful merges: - rust-lang#76909 (Add Iterator::advance_by and DoubleEndedIterator::advance_back_by) - rust-lang#77153 (Fix recursive nonterminal expansion during pretty-print/reparse check) - rust-lang#77202 (Defer Apple SDKROOT detection to link time.) - rust-lang#77303 (const evaluatable: improve `TooGeneric` handling) - rust-lang#77305 (move candidate_from_obligation_no_cache) - rust-lang#77315 (Rename AllocErr to AllocError) - rust-lang#77319 (Stable hashing: add comments and tests concerning platform-independence) - rust-lang#77324 (Don't fire `const_item_mutation` lint on writes through a pointer) - rust-lang#77343 (Validate `rustc_args_required_const`) - rust-lang#77349 (Update cargo) - rust-lang#77360 (References to ZSTs may be at arbitrary aligned addresses) - rust-lang#77371 (Remove trailing space in error message) Failed merges: r? `@ghost`
@timvermeulen The rollup containing this PR caused a large regression in instruction counts in the Reverting the changes to |
That's this one, right? https://github.com/rust-lang/rustc-perf/blob/master/collector/benchmarks/deeply-nested/src/lib.rs I think that one will regress massively any time an object-safe method is added to That said, the small regressions in other things are worth looking at. |
Ah, didn't even notice the trait object aspect of that benchmark. I'm more concerned about the small regression elsewhere, but perhaps it's a similar issue. I think it's worth doing a perf run with the changes to |
Yeah, that does sound like a reasonable thing to try. I'd also suggest manually implementing it for |
I was going to add |
Alright, that doesn't really seem to have changed anything. Let's try reverting the |
This PR adds the iterator method
that advances the iterator by
n
elements, returningOk(())
if this succeeds orErr(len)
if the length of the iterator was less thann
.Currently
Iterator::nth
is the method to override for efficiently advancing an iterator by multiple elements at once.advance_by
is superior for this purpose becauseChain
andFlatMap
can implementadvance_by
in terms ofadvance_by
on their inner iterators, but they cannot implementnth
in terms ofnth
on their inner iterators (seeIterator::nth
doesn't compose well #60395)nth
can trivially be implemented in terms ofadvance_by
andnext
, which this PR also doesThis PR also adds
DoubleEndedIterator::advance_back_by
for all the same reasons.I'll make a tracking issue if it's decided this is worth merging. Also let me know if anything can be improved, this went through several iterations so there might very well still be room for improvement (especially in the doc comments). I've written overrides of these methods for most iterators that already override
nth
/nth_back
, but those still need tests so I'll add them in a later PR.cc @cuviper @scottmcm @Amanieu