Skip to content

Commit

Permalink
Add Visit iterator and speed up enumerate for LinearSlow arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
timholy committed May 15, 2016
1 parent 6056e10 commit 8873710
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
2 changes: 2 additions & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ export
VecOrMat,
Vector,
VersionNumber,
Visit,
WeakKeyDict,
WorkerConfig,
WString,
Expand Down Expand Up @@ -981,6 +982,7 @@ export
enumerate,
next,
start,
visit,
zip,
rest,
countfrom,
Expand Down
31 changes: 28 additions & 3 deletions base/iterator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,43 @@ enumerate(itr) = Enumerate(itr)

length(e::Enumerate) = length(e.itr)
size(e::Enumerate) = size(e.itr)
start(e::Enumerate) = (1, start(e.itr))
function next(e::Enumerate, state)
@inline start(e::Enumerate) = (1, start(e.itr))
@inline function next(e::Enumerate, state)
n = next(e.itr,state[2])
(state[1],n[1]), (state[1]+1,n[2])
end
done(e::Enumerate, state) = done(e.itr, state[2])
@inline done(e::Enumerate, state) = done(e.itr, state[2])

eltype{I}(::Type{Enumerate{I}}) = Tuple{Int, eltype(I)}

iteratorsize{I}(::Type{Enumerate{I}}) = iteratorsize(I)
iteratoreltype{I}(::Type{Enumerate{I}}) = iteratoreltype(I)

# visit
# visit is like enumerate, except rather than counting entries it
# returns the index associated with each entry

immutable Visit{I,A<:AbstractArray}
data::A
itr::I
end
visit(A::AbstractArray) = Visit(A, eachindex(A))

Base.length(v::Visit) = length(v.itr)
Base.size(v::Visit) = size(v.itr)
@inline Base.start(v::Visit) = start(v.itr)
@inline function Base.next(v::Visit, state)
indx, n = next(v.itr, state)
@inbounds item = v.data[indx]
(indx, item), n
end
@inline Base.done(v::Visit, state) = done(v.itr, state)

Base.eltype{I,A}(::Type{Visit{I,A}}) = Tuple{eltype(I), eltype(A)}

Base.iteratorsize{I}(::Type{Visit{I}}) = iteratorsize(I)
Base.iteratoreltype{I}(::Type{Visit{I}}) = iteratoreltype(I)

# zip

abstract AbstractZipIterator
Expand Down
7 changes: 7 additions & 0 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,13 @@ let a36 = boo32_64()
end
@test isequal([1,2,3], [a for (a,b) in enumerate(2:4)])
@test isequal([2,3,4], [b for (a,b) in enumerate(2:4)])
A14 = [11 13; 12 14]
B14 = sub(A14, 1:2, 1:2)
@test isa(Base.linearindexing(B14), Base.LinearSlow)
@test isequal([1,2,3,4], [a for (a,b) in visit(A14)])
@test isequal(vec(collect(eachindex(B14))), [a for (a,b) in visit(B14)])
@test isequal([11,12,13,14], [b for (a,b) in visit(A14)])
@test isequal([11,12,13,14], [b for (a,b) in visit(B14)])

# comprehension in let-bound function
let xy = sum([x[i]*y[i] for i=1:length(x)])
Expand Down

0 comments on commit 8873710

Please sign in to comment.