Skip to content

Commit

Permalink
Add default IsScalar trait
Browse files Browse the repository at this point in the history
  • Loading branch information
pabloferz committed Jun 23, 2016
1 parent 45fa65f commit c2e633c
Show file tree
Hide file tree
Showing 9 changed files with 21 additions and 3 deletions.
3 changes: 2 additions & 1 deletion base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ promote_rule{T,n,S}(::Type{Array{T,n}}, ::Type{Array{S,n}}) = Array{promote_type

# make a collection similar to `c` and appropriate for collecting `itr`
_similar_for(c::AbstractArray, T, itr, ::SizeUnknown) = similar(c, T, 0)
_similar_for(c::AbstractArray, T, itr, ::IsScalar) = similar(c, T, ())
_similar_for(c::AbstractArray, T, itr, ::HasLength) = similar(c, T, Int(length(itr)::Integer))
_similar_for(c::AbstractArray, T, itr, ::HasShape) = similar(c, T, convert(Dims,size(itr)))
_similar_for(c, T, itr, isz) = similar(c, T)
Expand All @@ -226,7 +227,7 @@ collect(itr) = _collect(1:1 #= Array =#, itr, iteratoreltype(itr), iteratorsize(

collect_similar(cont, itr) = _collect(cont, itr, iteratoreltype(itr), iteratorsize(itr))

_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape,IsScalar}) =
copy!(_similar_for(cont, eltype(itr), itr, isz), itr)

function _collect(cont, itr, ::HasEltype, isz::SizeUnknown)
Expand Down
2 changes: 2 additions & 0 deletions base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ _tt1{A,B}(::Type{Pair{A,B}}) = A
_tt2{A,B}(::Type{Pair{A,B}}) = B
eltype{D}(::Type{KeyIterator{D}}) = _tt1(eltype(D))
eltype{D}(::Type{ValueIterator{D}}) = _tt2(eltype(D))
iteratorsize{T<:Union{KeyIterator,ValueIterator}}(::Type{T}) = HasLength()

start(v::Union{KeyIterator,ValueIterator}) = start(v.dict)
done(v::Union{KeyIterator,ValueIterator}, state) = done(v.dict, state)
Expand Down Expand Up @@ -272,6 +273,7 @@ function filter(f, d::Associative)
end

eltype{K,V}(::Type{Associative{K,V}}) = Pair{K,V}
iteratorsize{T<:Union{Associative,AbstractSet}}(::Type{T}) = HasLength()

function isequal(l::Associative, r::Associative)
l === r && return true
Expand Down
1 change: 1 addition & 0 deletions base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ done(v::SimpleVector,i) = (i > v.length)
isempty(v::SimpleVector) = (v.length == 0)
indices(v::SimpleVector, d) = d == 1 ? (1:length(v)) : (1:1)
linearindices(v::SimpleVector) = indices(v, 1)
iteratorsize(::Type{SimpleVector}) = HasLength()

function ==(v1::SimpleVector, v2::SimpleVector)
length(v1)==length(v2) || return false
Expand Down
5 changes: 4 additions & 1 deletion base/generator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,19 @@ end

abstract IteratorSize
immutable SizeUnknown <: IteratorSize end
immutable IsScalar <: IteratorSize end
immutable HasLength <: IteratorSize end
immutable HasShape <: IteratorSize end
immutable IsInfinite <: IteratorSize end

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

and_iteratorsize{T}(isz::T, ::T) = isz
and_iteratorsize(::HasLength, ::HasShape) = HasLength()
and_iteratorsize(::HasShape, ::HasLength) = HasLength()
and_iteratorsize(::IsScalar, ::Union{HasLength,HasShape}) = IsScalar()
and_iteratorsize(::Union{HasLength,HasShape}, ::IsScalar) = IsScalar()
and_iteratorsize(a, b) = SizeUnknown()

abstract IteratorEltype
Expand Down
5 changes: 5 additions & 0 deletions base/iterator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ iteratoreltype{I}(::Type{Enumerate{I}}) = iteratoreltype(I)
abstract AbstractZipIterator

zip_iteratorsize(a, b) = and_iteratorsize(a,b) # as `and_iteratorsize` but inherit `Union{HasLength,IsInfinite}` of the shorter iterator
zip_iteratorsize(::IsScalar, ::IsInfinite) = IsScalar()
zip_iteratorsize(::HasLength, ::IsInfinite) = HasLength()
zip_iteratorsize(::HasShape, ::IsInfinite) = HasLength()
zip_iteratorsize(a::IsInfinite, b) = zip_iteratorsize(b,a)
Expand Down Expand Up @@ -413,6 +414,9 @@ iteratorsize{I1,I2}(::Type{Prod{I1,I2}}) = prod_iteratorsize(iteratorsize(I1),it
((x[1][1],x[1][2]...), x[2])
end

prod_iteratorsize(::IsScalar, ::IsScalar) = IsScalar()
prod_iteratorsize(::IsScalar, isz::Union{HasLength,HasShape}) = isz
prod_iteratorsize(isz::Union{HasLength,HasShape}, ::IsScalar) = isz
prod_iteratorsize(::Union{HasLength,HasShape}, ::Union{HasLength,HasShape}) = HasShape()
# products can have an infinite iterator
prod_iteratorsize(::IsInfinite, ::IsInfinite) = IsInfinite()
Expand Down Expand Up @@ -534,6 +538,7 @@ type PartitionIterator{T}
end

eltype{T}(::Type{PartitionIterator{T}}) = Vector{eltype(T)}
iteratorsize(::Type{PartitionIterator}) = HasLength()

function length(itr::PartitionIterator)
l = length(itr.c)
Expand Down
1 change: 1 addition & 0 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ isempty(m::MethodList) = isempty(m.ms)
start(m::MethodList) = start(m.ms)
done(m::MethodList, s) = done(m.ms, s)
next(m::MethodList, s) = next(m.ms, s)
iteratorsize(::Type{MethodList}) = HasLength()

function MethodList(mt::MethodTable)
ms = Method[]
Expand Down
2 changes: 2 additions & 0 deletions base/strings/basic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## core string functions ##

iteratorsize{T<:AbstractString}(::Type{T}) = HasLength()

endof(s::AbstractString) = error("you must implement endof(", typeof(s), ")")
next(s::AbstractString, i::Int) = error("you must implement next(", typeof(s), ",Int)")
next(s::DirectIndexString, i::Int) = (s[i],i+1)
Expand Down
3 changes: 2 additions & 1 deletion base/strings/utf8proc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Various Unicode functionality from the utf8proc library
module UTF8proc

import Base: show, ==, hash, string, Symbol, isless, length, eltype, start, next, done, convert, isvalid, lowercase, uppercase
import Base: show, ==, hash, string, Symbol, isless, length, eltype, iteratorsize, start, next, done, convert, isvalid, lowercase, uppercase

export isgraphemebreak

Expand Down Expand Up @@ -190,6 +190,7 @@ end
graphemes(s::AbstractString) = GraphemeIterator{typeof(s)}(s)

eltype{S}(::Type{GraphemeIterator{S}}) = SubString{S}
iteratorsize(::Type{GraphemeIterator}) = Base.HasLength()

function length(g::GraphemeIterator)
c0 = Char(0x00ad) # soft hyphen (grapheme break always allowed after this)
Expand Down
2 changes: 2 additions & 0 deletions base/tuple.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ getindex(t::Tuple, b::AbstractArray{Bool}) = getindex(t,find(b))

## iterating ##

iteratorsize{T<:Tuple}(::Type{T}) = HasLength()

start(t::Tuple) = 1
done(t::Tuple, i::Int) = (length(t) < i)
next(t::Tuple, i::Int) = (t[i], i+1)
Expand Down

0 comments on commit c2e633c

Please sign in to comment.