Skip to content

Commit 8873710

Browse files
committed
Add Visit iterator and speed up enumerate for LinearSlow arrays
1 parent 6056e10 commit 8873710

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

base/exports.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ export
125125
VecOrMat,
126126
Vector,
127127
VersionNumber,
128+
Visit,
128129
WeakKeyDict,
129130
WorkerConfig,
130131
WString,
@@ -981,6 +982,7 @@ export
981982
enumerate,
982983
next,
983984
start,
985+
visit,
984986
zip,
985987
rest,
986988
countfrom,

base/iterator.jl

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,43 @@ enumerate(itr) = Enumerate(itr)
2121

2222
length(e::Enumerate) = length(e.itr)
2323
size(e::Enumerate) = size(e.itr)
24-
start(e::Enumerate) = (1, start(e.itr))
25-
function next(e::Enumerate, state)
24+
@inline start(e::Enumerate) = (1, start(e.itr))
25+
@inline function next(e::Enumerate, state)
2626
n = next(e.itr,state[2])
2727
(state[1],n[1]), (state[1]+1,n[2])
2828
end
29-
done(e::Enumerate, state) = done(e.itr, state[2])
29+
@inline done(e::Enumerate, state) = done(e.itr, state[2])
3030

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

3333
iteratorsize{I}(::Type{Enumerate{I}}) = iteratorsize(I)
3434
iteratoreltype{I}(::Type{Enumerate{I}}) = iteratoreltype(I)
3535

36+
# visit
37+
# visit is like enumerate, except rather than counting entries it
38+
# returns the index associated with each entry
39+
40+
immutable Visit{I,A<:AbstractArray}
41+
data::A
42+
itr::I
43+
end
44+
visit(A::AbstractArray) = Visit(A, eachindex(A))
45+
46+
Base.length(v::Visit) = length(v.itr)
47+
Base.size(v::Visit) = size(v.itr)
48+
@inline Base.start(v::Visit) = start(v.itr)
49+
@inline function Base.next(v::Visit, state)
50+
indx, n = next(v.itr, state)
51+
@inbounds item = v.data[indx]
52+
(indx, item), n
53+
end
54+
@inline Base.done(v::Visit, state) = done(v.itr, state)
55+
56+
Base.eltype{I,A}(::Type{Visit{I,A}}) = Tuple{eltype(I), eltype(A)}
57+
58+
Base.iteratorsize{I}(::Type{Visit{I}}) = iteratorsize(I)
59+
Base.iteratoreltype{I}(::Type{Visit{I}}) = iteratoreltype(I)
60+
3661
# zip
3762

3863
abstract AbstractZipIterator

test/arrayops.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,13 @@ let a36 = boo32_64()
936936
end
937937
@test isequal([1,2,3], [a for (a,b) in enumerate(2:4)])
938938
@test isequal([2,3,4], [b for (a,b) in enumerate(2:4)])
939+
A14 = [11 13; 12 14]
940+
B14 = sub(A14, 1:2, 1:2)
941+
@test isa(Base.linearindexing(B14), Base.LinearSlow)
942+
@test isequal([1,2,3,4], [a for (a,b) in visit(A14)])
943+
@test isequal(vec(collect(eachindex(B14))), [a for (a,b) in visit(B14)])
944+
@test isequal([11,12,13,14], [b for (a,b) in visit(A14)])
945+
@test isequal([11,12,13,14], [b for (a,b) in visit(B14)])
939946

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

0 commit comments

Comments
 (0)