Skip to content

Commit

Permalink
more iterator trait declarations
Browse files Browse the repository at this point in the history
make HasEltype and HasLength the default
  • Loading branch information
JeffBezanson committed Mar 8, 2016
1 parent 8bd8ea3 commit 3630dd3
Show file tree
Hide file tree
Showing 13 changed files with 36 additions and 20 deletions.
2 changes: 2 additions & 0 deletions base/channels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,5 @@ function done(c::Channel, state::Ref)
end
end
next{T}(c::Channel{T}, state) = (v=get(state[]); state[]=nothing; (v, state))

iteratorsize{C<:Channel}(::Type{C}) = SizeUnknown()
3 changes: 0 additions & 3 deletions base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@

abstract Associative{K,V}

iteratorsize{T<:Associative}(::Type{T}) = HasLength()
iteratoreltype{T<:Associative}(::Type{T}) = HasEltype()

const secret_table_token = :__c782dbf1cf4d6a2e5e3865d7e95634f2e09b5902__

haskey(d::Associative, k) = in(k,keys(d))
Expand Down
10 changes: 4 additions & 6 deletions base/generator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ abstract IteratorSize
immutable SizeUnknown <: IteratorSize end
immutable HasLength <: IteratorSize end
immutable HasShape <: IteratorSize end
immutable IsInfinite <: IteratorSize end

iteratorsize(x) = iteratorsize(typeof(x))
iteratorsize(::Type) = SizeUnknown()
iteratorsize(::Type) = HasLength() # HasLength is the default

and_iteratorsize{T}(isz::T, ::T) = isz
and_iteratorsize(::HasLength, ::HasShape) = HasLength()
Expand All @@ -40,19 +41,16 @@ immutable EltypeUnknown <: IteratorEltype end
immutable HasEltype <: IteratorEltype end

iteratoreltype(x) = iteratoreltype(typeof(x))
iteratoreltype(::Type) = EltypeUnknown()
iteratoreltype(::Type) = HasEltype() # HasEltype is the default

and_iteratoreltype{T}(iel::T, ::T) = iel
and_iteratoreltype(a, b) = EltypeUnknown()

iteratorsize{T<:AbstractArray}(::Type{T}) = HasShape()
iteratorsize{T<:AbstractString}(::Type{T}) = HasLength()
iteratorsize{T<:Tuple}(::Type{T}) = HasLength()
iteratorsize{I,F}(::Type{Generator{I,F}}) = iteratorsize(I)
length(g::Generator) = length(g.iter)
size(g::Generator) = size(g.iter)

iteratoreltype{T<:AbstractArray}(::Type{T}) = HasEltype()
iteratoreltype{T<:AbstractString}(::Type{T}) = HasEltype()
iteratoreltype{I,T}(::Type{Generator{I,T}}) = EltypeUnknown()
iteratoreltype{I,T}(::Type{Generator{I,Type{T}}}) = HasEltype()
eltype{I,T}(::Type{Generator{I,Type{T}}}) = T
2 changes: 2 additions & 0 deletions base/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ eltype(::Type{EachLine}) = ByteString

readlines(s=STDIN) = collect(eachline(s))

iteratorsize(::Type{EachLine}) = SizeUnknown()

# IOStream Marking
# Note that these functions expect that io.mark exists for
# the concrete IO type. This may not be true for IO types
Expand Down
10 changes: 8 additions & 2 deletions base/iterator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ done(f::Filter, s) = s[1]

eltype{I}(::Type{Filter{I}}) = eltype(I)
iteratoreltype{F,I}(::Type{Filter{F,I}}) = iteratoreltype(I)
iteratorsize{T<:Filter}(::Type{T}) = SizeUnknown()

# Rest -- iterate starting at the given state

Expand All @@ -140,6 +141,7 @@ done(i::Rest, st) = done(i.itr, st)

eltype{I}(::Type{Rest{I}}) = eltype(I)
iteratoreltype{I,S}(::Type{Rest{I,S}}) = iteratoreltype(I)
iteratorsize{T<:Rest}(::Type{T}) = SizeUnknown()

# Count -- infinite counting

Expand All @@ -152,12 +154,13 @@ countfrom(start::Number) = Count(start, one(start))
countfrom() = Count(1, 1)

eltype{S}(::Type{Count{S}}) = S
iteratoreltype{I<:Count}(::Type{I}) = HasEltype()

start(it::Count) = it.start
next(it::Count, state) = (state, state + it.step)
done(it::Count, state) = false

iteratorsize{S}(::Type{Count{S}}) = IsInfinite()

# Take -- iterate through the first n elements

immutable Take{I}
Expand All @@ -168,6 +171,7 @@ take(xs, n::Int) = Take(xs, n)

eltype{I}(::Type{Take{I}}) = eltype(I)
iteratoreltype{I}(::Type{Take{I}}) = iteratoreltype(I)
iteratorsize{T<:Take}(::Type{T}) = SizeUnknown() # TODO

start(it::Take) = (it.n, start(it.xs))

Expand All @@ -192,6 +196,7 @@ drop(xs, n::Int) = Drop(xs, n)

eltype{I}(::Type{Drop{I}}) = eltype(I)
iteratoreltype{I}(::Type{Drop{I}}) = iteratoreltype(I)
iteratorsize{T<:Drop}(::Type{T}) = SizeUnknown() # TODO

function start(it::Drop)
xs_state = start(it.xs)
Expand All @@ -217,6 +222,7 @@ cycle(xs) = Cycle(xs)

eltype{I}(::Type{Cycle{I}}) = eltype(I)
iteratoreltype{I}(::Type{Cycle{I}}) = iteratoreltype(I)
iteratorsize{I}(::Type{Cycle{I}}) = IsInfinite()

function start(it::Cycle)
s = start(it.xs)
Expand All @@ -241,7 +247,7 @@ immutable Repeated{O}
end
repeated(x) = Repeated(x)
eltype{O}(::Type{Repeated{O}}) = O
iteratoreltype{O}(::Type{Repeated{O}}) = HasEltype()
iteratorsize{O}(::Type{Repeated{O}}) = IsInfinite()
start(it::Repeated) = nothing
next(it::Repeated, state) = (it.x, nothing)
done(it::Repeated, state) = false
Expand Down
2 changes: 2 additions & 0 deletions base/libgit2/reference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ function Base.next(bi::GitBranchIter, state)
return (state[1:2], (GitReference(ref_ptr_ptr[]), btype[1], false))
end

Base.iteratorsize(::Type{GitBranchIter}) = Base.SizeUnknown()

function Base.map(f::Function, bi::GitBranchIter)
res = nothing
s = start(bi)
Expand Down
2 changes: 2 additions & 0 deletions base/libgit2/walker.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ function Base.next(w::GitRevWalker, state)
return (state[1], (id_ptr[], false))
end

Base.iteratorsize(::Type{GitRevWalker}) = Base.SizeUnknown()

function push_head!(w::GitRevWalker)
@check ccall((:git_revwalk_push_head, :libgit2), Cint, (Ptr{Void},), w.ptr)
return w
Expand Down
11 changes: 7 additions & 4 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
### Multidimensional iterators
module IteratorsMD

import Base: eltype, length, start, done, next, last, getindex, setindex!, linearindexing, min, max, eachindex, ndims
import Base: eltype, length, size, start, done, next, last, getindex, setindex!, linearindexing, min, max, eachindex, ndims, iteratorsize
importall ..Base.Operators
import Base: simd_outer_range, simd_inner_length, simd_index, @generated
import Base: @nref, @ncall, @nif, @nexprs, LinearFast, LinearSlow, to_index, AbstractCartesianIndex
Expand Down Expand Up @@ -103,6 +103,7 @@ end
end

eltype{I}(::Type{CartesianRange{I}}) = I
iteratorsize{I}(::Type{CartesianRange{I}}) = Base.HasShape()

@generated function start{I<:CartesianIndex}(iter::CartesianRange{I})
N = length(I)
Expand Down Expand Up @@ -135,13 +136,15 @@ start{I<:CartesianIndex{0}}(iter::CartesianRange{I}) = false
next{I<:CartesianIndex{0}}(iter::CartesianRange{I}, state) = iter.start, true
done{I<:CartesianIndex{0}}(iter::CartesianRange{I}, state) = state

@generated function length{I<:CartesianIndex}(iter::CartesianRange{I})
@generated function size{I<:CartesianIndex}(iter::CartesianRange{I})
N = length(I)
N == 0 && return 1
N == 0 && return ()
args = [:(iter.stop[$i]-iter.start[$i]+1) for i=1:N]
Expr(:call,:*,args...)
Expr(:tuple,args...)
end

length(iter::CartesianRange) = prod(size(iter))

last(iter::CartesianRange) = iter.stop

@generated function simd_outer_range{I}(iter::CartesianRange{I})
Expand Down
1 change: 1 addition & 0 deletions base/regex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ compile(itr::RegexMatchIterator) = (compile(itr.regex); itr)
eltype(::Type{RegexMatchIterator}) = RegexMatch
start(itr::RegexMatchIterator) = match(itr.regex, itr.string, 1, UInt32(0))
done(itr::RegexMatchIterator, prev_match) = (prev_match === nothing)
iteratorsize(::Type{RegexMatchIterator}) = SizeUnknown()

# Assumes prev_match is not nothing
function next(itr::RegexMatchIterator, prev_match)
Expand Down
2 changes: 2 additions & 0 deletions base/task.jl
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ function done(t::Task, val)
istaskdone(t)
end
next(t::Task, val) = (t.result, nothing)
iteratorsize(::Type{Task}) = SizeUnknown()
iteratoreltype(::Type{Task}) = EltypeUnknown()

isempty(::Task) = error("isempty not defined for Tasks")

Expand Down
1 change: 1 addition & 0 deletions test/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ type GenericIterator{N} end
Base.start{N}(::GenericIterator{N}) = 1
Base.next{N}(::GenericIterator{N}, i) = (i, i + 1)
Base.done{N}(::GenericIterator{N}, i) = i > N ? true : false
Base.iteratorsize{N}(::Type{GenericIterator{N}}) = Base.SizeUnknown()

function test_map(::Type{TestAbstractArray})

Expand Down
8 changes: 4 additions & 4 deletions test/simdloop.jl
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,17 @@ end
crng = CartesianRange(CartesianIndex{4}(2,0,1,3),
CartesianIndex{4}(4,1,1,5))
indexes = simd_cartesian_range!(Array(eltype(crng), 0), crng)
@test indexes == collect(crng)
@test indexes == vec(collect(crng))

crng = CartesianRange(CartesianIndex{2}(-1,1),
CartesianIndex{2}(1,3))
indexes = simd_cartesian_range!(Array(eltype(crng), 0), crng)
@test indexes == collect(crng)
@test indexes == vec(collect(crng))

crng = CartesianRange(CartesianIndex{2}(-1,1),
CartesianIndex{2}(-1,3))
indexes = simd_cartesian_range!(Array(eltype(crng), 0), crng)
@test indexes == collect(crng)
@test indexes == vec(collect(crng))

crng = CartesianRange(CartesianIndex{1}(2),
CartesianIndex{1}(4))
Expand All @@ -124,7 +124,7 @@ indexes = simd_cartesian_range!(Array(eltype(crng), 0), crng)
crng = CartesianRange(CartesianIndex{0}(),
CartesianIndex{0}())
indexes = simd_cartesian_range!(Array(eltype(crng), 0), crng)
@test indexes == collect(crng)
@test indexes == vec(collect(crng))

# @simd with array as "range"
# issue #13869
Expand Down
2 changes: 1 addition & 1 deletion test/unicode/utf8proc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ let grphtest = (("b\u0300lahβlahb\u0302láh", ["b\u0300","l","a","h",
@test typeof(first(graphemes(s_))) == SubString{typeof(s_)}
end
grph = collect(graphemes(s_))
@test isempty(grph) || eltype(grph) == SubString{typeof(s_)}
@test eltype(grph) == SubString{typeof(s_)}
@test grph == g_
@test length(graphemes(s_)) == length(grph)
end
Expand Down

0 comments on commit 3630dd3

Please sign in to comment.