Skip to content

Commit

Permalink
Make iterate(::Reverse) use indexing by default (JuliaLang#43110)
Browse files Browse the repository at this point in the history
Co-authored-by: Jeff Bezanson <[email protected]>

Co-authored-by: Jeff Bezanson <[email protected]>
Co-authored-by: Jameson Nash <[email protected]>
  • Loading branch information
3 people authored Nov 20, 2021
1 parent f9e40ef commit b64f1cd
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 0 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Language changes
* `@time` and `@timev` now take an optional description to allow annotating the source of time reports.
i.e. `@time "Evaluating foo" foo()` ([#42431])
* New `@showtime` macro to show both the line being evaluated and the `@time` report ([#42431])
* Iterating an `Iterators.Reverse` now falls back on reversing the eachindex interator, if possible ([#43110]).
* Unbalanced Unicode bidirectional formatting directives are now disallowed within strings and comments,
to mitigate the ["trojan source"](https://www.trojansource.codes) vulnerability ([#42918]).

Expand Down
9 changes: 9 additions & 0 deletions base/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,15 @@ first(r::Reverse) = last(r.itr) # and the last shall be first
(A.itr[idx], (state[1], itrs))
end

# Fallback method of `iterate(::Reverse{T})` which assumes the collection has `getindex(::T) and `reverse(eachindex(::T))`
# don't propagate inbounds for this just in case
function iterate(A::Reverse, state=(reverse(eachindex(A.itr)),))
y = iterate(state...)
y === nothing && return y
idx, itrs = y
(A.itr[idx], (state[1], itrs))
end

reverse(R::AbstractRange) = Base.reverse(R) # copying ranges is cheap
reverse(G::Generator) = Generator(G.f, reverse(G.iter))
reverse(r::Reverse) = r.itr
Expand Down

0 comments on commit b64f1cd

Please sign in to comment.