Skip to content

Commit

Permalink
Merge pull request #3 from timholy/teh/show_docstrings
Browse files Browse the repository at this point in the history
More fleshing out of the basic API (including show and docstrings)
  • Loading branch information
timholy committed Apr 18, 2016
2 parents cd31dd3 + 5bf4354 commit 024273a
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 11 deletions.
50 changes: 42 additions & 8 deletions src/ArrayIterationPlayground.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module ArrayIterationPlayground

using Base: ViewIndex
import Base: getindex, setindex!, start, next, done, length, eachindex
import Base: getindex, setindex!, start, next, done, length, eachindex, show

export inds, index, stored, each

Expand All @@ -20,8 +20,39 @@ immutable ArrayIndexingWrapper{A, I<:Tuple{Vararg{ViewIndex}}, isindex, isstored
data::A
indexes::I
end
show(io::IO, W::ArrayIndexingWrapper) = print(io, "iteration hint over ", hint_string(W), " of a ", summary(W.data), " over the region ", W.indexes)
hint_string{A,I}(::ArrayIndexingWrapper{A,I,false,false}) = "values"
hint_string{A,I}(::ArrayIndexingWrapper{A,I,true,false}) = "indexes"
hint_string{A,I}(::ArrayIndexingWrapper{A,I,false,true}) = "stored values"
hint_string{A,I}(::ArrayIndexingWrapper{A,I,true,true}) = "indexes of stored values"

"""
`index(A)`
`index(A, indexes...)`
`index` creates an "iteration hint" that records the region of `A`
that you wish to iterate over. The iterator will return the indexes,
rather than values, of `A`. "iteration hints" are not iterables; to
create an iterator from a hint, call `each` on the resulting object.
In contrast to `eachindex` iteration over a subarray of `A`, the
indexes are for `A` itself.
See also: `stored`, `each`.
"""
index{A,I,isindex,isstored}(w::ArrayIndexingWrapper{A,I,isindex,isstored}) = ArrayIndexingWrapper{A,I,true,isstored}(w.data, w.indexes)

"""
`stored(A)`
`stored(A, indexes...)`
`stored` creates an "iteration hint" that records the region of `A`
that you wish to iterate over. The iterator will return just the
stored values of `A`. "iteration hints" are not iterables; to create
an iterator from a hint, call `each` on the resulting object.
See also: `index`, `each`.
"""
stored{A,I,isindex,isstored}(w::ArrayIndexingWrapper{A,I,isindex,isstored}) = ArrayIndexingWrapper{A,I,isindex,true}(w.data, w.indexes)

allindexes{T,N}(A::AbstractArray{T,N}) = ntuple(d->Colon(),Val{N})
Expand All @@ -35,12 +66,13 @@ stored(A::AbstractArray, I::ViewIndex...) = stored(A, I)
stored{T,N}(A::AbstractArray{T,N}, indexes::NTuple{N,ViewIndex}) = ArrayIndexingWrapper{typeof(A),typeof(indexes),false,true}(A, indexes)

"""
`each(obj)`
`each(obj, indexes...)`
`each(iterhint)`
`each(iterhint, indexes...)`
`each` instantiates the iterator associated with `obj`. In conjunction
with `index` and `stored`, you may choose to iterate over either
indexes or values, and o ver all elements or just the stored elements.
`each` instantiates the iterator associated with `iterhint`. In
conjunction with `index` and `stored`, you may choose to iterate over
either indexes or values, as well as choosing whether to iterate over
all elements or just the stored elements.
"""
each(A::AbstractArray) = each(A, allindexes(A))
each(A::AbstractArray, indexes::ViewIndex...) = each(A, indexes)
Expand All @@ -53,8 +85,10 @@ immutable ValueIterator{A<:AbstractArray,I}
iter::I
end

each{A,I,stored}(W::ArrayIndexingWrapper{A,I,false,stored}) = (itr = each(index(W)); ValueIterator{A,typeof(itr)}(W.data, itr))
each{A,I}(W::ArrayIndexingWrapper{A,I,true}) = CartesianRange(ranges(W))
# Fallback definitions for each
each{A,I,isstored}(W::ArrayIndexingWrapper{A,I,false,isstored}) = (itr = each(index(W)); ValueIterator{A,typeof(itr)}(W.data, itr))
each{A,N,isstored}(W::ArrayIndexingWrapper{A,NTuple{N,Colon},true,isstored}) = eachindex(W.data)
each{A,I,isstored}(W::ArrayIndexingWrapper{A,I,true,isstored}) = CartesianRange(ranges(W))

start(vi::ValueIterator) = start(vi.iter)
done(vi::ValueIterator, s) = done(vi.iter, s)
Expand Down
4 changes: 2 additions & 2 deletions src/sparse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,6 @@ next{S<:SubSparseMatrixCSC}(iter::ColIteratorCSC{true,S}, s) = (@inbounds row =

# nextstored{S<:SparseMatrixCSC}(iter::ColIteratorCSC{S}, s, index::Integer) =

each{A<:SparseMatrixCSC,I}(w::ArrayIndexingWrapper{A,I,true,false}) = ColIteratorCSC{false}(w.data, w.indexes...)
each{A<:SparseMatrixCSC,I}(w::ArrayIndexingWrapper{A,I,true,true}) = ColIteratorCSC{true}(w.data, w.indexes...)
each{A<:SparseMatrixCSC,N,isstored}(w::ArrayIndexingWrapper{A,NTuple{N,Colon},true,isstored}) = ColIteratorCSC{isstored}(w.data, w.indexes...) # ambig.
each{A<:SparseMatrixCSC,I,isstored}(w::ArrayIndexingWrapper{A,I,true,isstored}) = ColIteratorCSC{isstored}(w.data, w.indexes...)
each{A<:SparseMatrixCSC,I,isstored}(w::ArrayIndexingWrapper{A,I,false,isstored}) = ValueIterator(w.data, ColIteratorCSC{isstored}(w.data, w.indexes...))
20 changes: 19 additions & 1 deletion test/dense.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
A = [1 5 -5;
0 3 2]
B = sub(A, 1:2, 1:3)

@test each(index(A)) == CartesianRange((1:2, 1:3))
@test each(index(A)) == eachindex(A) == 1:length(A)
@test each(index(B)) == CartesianRange((1:2, 1:3))
@test each(index(A, :, 1:2)) == CartesianRange((1:2, 1:2))
@test each(index(A, :, 2:3)) == CartesianRange((1:2, 2:3))
@test each(index(A, 1, :)) == CartesianRange((1, 1:3))

k = 0
for v in each(A)
@test v == A[k+=1]
end

k = 0
for I in each(index(A))
@test A[I] == A[k+=1]
end

k = 0
for I in eachindex(A)
@test A[I] == A[k+=1]
end

k = 0
for j in inds(A, 2)
Expand Down
16 changes: 16 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,21 @@ A = zeros(2,3)
@test inds(A, 3) == 1:1
@test inds(A) == (1:2, 1:3)

io = IOBuffer()
show(io, index(A))
@test takebuf_string(io) == "iteration hint over indexes of a "*summary(A)*" over the region (Colon(),Colon())"
io = IOBuffer()
show(io, index(A, :, 2:3))
@test takebuf_string(io) == "iteration hint over indexes of a "*summary(A)*" over the region (Colon(),2:3)"
io = IOBuffer()
show(io, stored(A, 1, 2:3))
@test takebuf_string(io) == "iteration hint over stored values of a "*summary(A)*" over the region (1,2:3)"
io = IOBuffer()
show(io, index(stored(A, 1:2, :)))
@test takebuf_string(io) == "iteration hint over indexes of stored values of a "*summary(A)*" over the region (1:2,Colon())"
io = IOBuffer()
show(io, stored(index(A, 1:2, :)))
@test takebuf_string(io) == "iteration hint over indexes of stored values of a "*summary(A)*" over the region (1:2,Colon())"

include("dense.jl")
include("sparse.jl")

0 comments on commit 024273a

Please sign in to comment.