Skip to content

Commit

Permalink
Refactor iteration for CartesianRange
Browse files Browse the repository at this point in the history
Simplify index creation in next; use `ifelse` and boolean arithmetic to eliminate a few branches. Only pass around the next index as state and perform the done check in `done`.

Add a few more inline annotations.
  • Loading branch information
mbauman committed Apr 1, 2015
1 parent 39ef7c4 commit 1caa7c5
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 15 deletions.
4 changes: 2 additions & 2 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -341,12 +341,12 @@ zero{T}(x::AbstractArray{T}) = fill!(similar(x), zero(T))
macro _inline_meta()
Expr(:meta, :inline)
end
start(A::AbstractArray) = (itr = eachindex(A); (itr, start(itr)))
start(A::AbstractArray) = (@_inline_meta(); itr = eachindex(A); (itr, start(itr)))
next(A::AbstractArray,i) = (@_inline_meta(); (idx, s) = next(i[1], i[2]); (A[idx], (i[1], s)))
done(A::AbstractArray,i) = done(i[1], i[2])

# eachindex iterates over all indices. LinearSlow is later in bootstrap
eachindex(A::AbstractArray) = eachindex(linearindexing(A), A)
eachindex(A::AbstractArray) = (@_inline_meta; eachindex(linearindexing(A), A))
eachindex(::LinearFast, A::AbstractArray) = 1:length(A)

isempty(a::AbstractArray) = (length(a) == 0)
Expand Down
25 changes: 12 additions & 13 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,31 +113,30 @@ CartesianRange{N}(sz::NTuple{N,Int}) = CartesianRange(CartesianIndex(sz))
stagedfunction eachindex{T,N}(::LinearSlow, A::AbstractArray{T,N})
startargs = fill(1, N)
stopargs = [:(size(A,$i)) for i=1:N]
:(CartesianRange(CartesianIndex{$N}($(startargs...)), CartesianIndex{$N}($(stopargs...))))
meta = Expr(:meta, :inline)
:($meta; CartesianRange(CartesianIndex{$N}($(startargs...)), CartesianIndex{$N}($(stopargs...))))
end

eltype{I}(::Type{CartesianRange{I}}) = I
eltype{I}(::CartesianRange{I}) = I

stagedfunction start{I}(iter::CartesianRange{I})
N=length(I)
finishedex = Expr(:(||), [:(iter.stop[$i] < iter.start[$i]) for i = 1:N]...)
:(return $finishedex, iter.start)
end

stagedfunction next{I<:CartesianIndex}(iter::CartesianRange{I}, state::(Bool, I))
start(iter::CartesianRange) = iter.start
stagedfunction next{I<:CartesianIndex}(iter::CartesianRange{I}, state::I)
N = length(I)
finishedex = (N==0 ? true : :(newindex[$N] > iter.stop[$N]))
meta = Expr(:meta, :inline)
quote
$meta
index=state[2]
newindex=@nif $N d->(index[d] < iter.stop[d]) d->@ncall($N, $I, k->(k>d ? index[k] : k==d ? index[k]+1 : iter.start[k]))
finished=$finishedex
index, (finished,newindex)
index=state
@nif $N d->(index[d] < iter.stop[d]) d->(@nexprs($N, k->(ind_k = ifelse(k>=d, index[k] + (k==d), iter.start[k]))))
newindex= @ncall $N $I ind
index, newindex
end
end
done{I<:CartesianIndex}(iter::CartesianRange{I}, state::(Bool, I)) = state[1]
stagedfunction done{I<:CartesianIndex}(iter::CartesianRange{I}, state::I)
N = length(I)
N==0 ? true : :(state[$N] > iter.stop[$N])
end

stagedfunction length{I<:CartesianIndex}(iter::CartesianRange{I})
N = length(I)
Expand Down

0 comments on commit 1caa7c5

Please sign in to comment.