Add iterator method .rfold(init, function); the reverse of fold#44682
Merged
bors merged 7 commits intorust-lang:masterfrom Sep 22, 2017
Merged
Add iterator method .rfold(init, function); the reverse of fold#44682bors merged 7 commits intorust-lang:masterfrom
bors merged 7 commits intorust-lang:masterfrom
Conversation
Adaptors are things that take iterators and adapt them into other iterators. With this definition, fold is just a usual method, because it doesn't normally make an iterator.
rfold is the reverse version of fold. Fold allows iterators to implement a different (non-resumable) internal iteration when it is more efficient than the external iteration implemented through the next method. (Common examples are VecDeque and .chain()). Introduce rfold() so that the same customization is available for reverse iteration. This is achieved by both adding the method, and by having the Rev<I> adaptor connect Rev::rfold -> I::fold, Rev::fold -> I::rfold.
With both in place, we can cross them over in rev, and we give rfold behaviour to .rev().fold() and so on.
Contributor
|
r? @dtolnay (rust_highfive has picked a reviewer for you, use r? to override) |
Contributor
|
cc @rust-lang/libs |
Member
|
Note that I added |
Member
|
What determines whether this goes on the DoubleEndedIterator trait like rfind or on the Iterator trait like rposition? fn rfold<B, F>(self, accum: B, f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
Self: Sized + DoubleEndedIterator; |
Member
Member
|
Seems like a fine addition to me! |
Member
|
SGTM |
Contributor
Author
|
great, done. @bors r=dtolnay |
Collaborator
|
📌 Commit 41a4226 has been approved by |
Collaborator
bors
added a commit
that referenced
this pull request
Sep 21, 2017
Add iterator method .rfold(init, function); the reverse of fold rfold is the reverse version of fold. Fold allows iterators to implement a different (non-resumable) internal iteration when it is more efficient than the external iteration implemented through the next method. (Common examples are VecDeque and .chain()). Introduce rfold() so that the same customization is available for reverse iteration. This is achieved by both adding the method, and by having the Rev\<I> adaptor connect Rev::rfold → I::fold and Rev::fold → I::rfold. On the surface, rfold(..) is just .rev().fold(..), but the special case implementations allow a data structure specific fold to be used through for example .iter().rev(); we thus have gains even for users never calling exactly rfold themselves.
Collaborator
|
💔 Test failed - status-travis |
Member
|
@bors: retry Looks like this was spuriously canceled? not sure why... |
Collaborator
bors
added a commit
that referenced
this pull request
Sep 21, 2017
Add iterator method .rfold(init, function); the reverse of fold rfold is the reverse version of fold. Fold allows iterators to implement a different (non-resumable) internal iteration when it is more efficient than the external iteration implemented through the next method. (Common examples are VecDeque and .chain()). Introduce rfold() so that the same customization is available for reverse iteration. This is achieved by both adding the method, and by having the Rev\<I> adaptor connect Rev::rfold → I::fold and Rev::fold → I::rfold. On the surface, rfold(..) is just .rev().fold(..), but the special case implementations allow a data structure specific fold to be used through for example .iter().rev(); we thus have gains even for users never calling exactly rfold themselves.
Collaborator
|
☀️ Test successful - status-appveyor, status-travis |
bors
added a commit
that referenced
this pull request
Nov 17, 2017
Short-circuiting internal iteration with Iterator::try_fold & try_rfold These are the core methods in terms of which the other methods (`fold`, `all`, `any`, `find`, `position`, `nth`, ...) can be implemented, allowing Iterator implementors to get the full goodness of internal iteration by only overriding one method (per direction). Based off the `Try` trait, so works with both `Result` and `Option` (:tada: #42526). The `try_fold` rustdoc examples use `Option` and the `try_rfold` ones use `Result`. AKA continuing in the vein of PRs #44682 & #44856 for more of `Iterator`. New bench following the pattern from the latter of those: ``` test iter::bench_take_while_chain_ref_sum ... bench: 1,130,843 ns/iter (+/- 25,110) test iter::bench_take_while_chain_sum ... bench: 362,530 ns/iter (+/- 391) ``` I also ran the benches without the `fold` & `rfold` overrides to test their new default impls, with basically no change. I left them there, though, to take advantage of existing overrides and because `AlwaysOk` has some sub-optimality due to #43278 (which 45225 should fix). If you're wondering why there are three type parameters, see issue #45462 Thanks for @bluss for the [original IRLO thread](https://internals.rust-lang.org/t/pre-rfc-fold-ok-is-composable-internal-iteration/4434) and the rfold PR and to @cuviper for adding so many folds, [encouraging me](#45379 (comment)) to make this PR, and finding a catastrophic bug in a pre-review.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
rfold is the reverse version of fold.
Fold allows iterators to implement a different (non-resumable) internal
iteration when it is more efficient than the external iteration implemented
through the next method. (Common examples are VecDeque and .chain()).
Introduce rfold() so that the same customization is available for reverse
iteration. This is achieved by both adding the method, and by having the
Rev<I> adaptor connect Rev::rfold → I::fold and Rev::fold → I::rfold.
On the surface, rfold(..) is just .rev().fold(..), but the special case
implementations allow a data structure specific fold to be used through for
example .iter().rev(); we thus have gains even for users never calling exactly
rfold themselves.