Skip to content

Commit ab15651

Browse files
committed
Add default IsScalar trait
1 parent 45fa65f commit ab15651

File tree

9 files changed

+36
-10
lines changed

9 files changed

+36
-10
lines changed

base/array.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ promote_rule{T,n,S}(::Type{Array{T,n}}, ::Type{Array{S,n}}) = Array{promote_type
206206

207207
# make a collection similar to `c` and appropriate for collecting `itr`
208208
_similar_for(c::AbstractArray, T, itr, ::SizeUnknown) = similar(c, T, 0)
209+
_similar_for(c::AbstractArray, T, itr, ::IsScalar) = similar(c, T, ())
209210
_similar_for(c::AbstractArray, T, itr, ::HasLength) = similar(c, T, Int(length(itr)::Integer))
210211
_similar_for(c::AbstractArray, T, itr, ::HasShape) = similar(c, T, convert(Dims,size(itr)))
211212
_similar_for(c, T, itr, isz) = similar(c, T)
@@ -217,6 +218,8 @@ Return an array of type `Array{element_type,1}` of all items in a collection.
217218
"""
218219
collect{T}(::Type{T}, itr) = collect(Generator(T, itr))
219220

221+
_collect{T}(::Type{T}, itr, ::IsScalar) = (a = Array{T}(); a[] = itr; a)
222+
220223
"""
221224
collect(collection)
222225
@@ -226,6 +229,12 @@ collect(itr) = _collect(1:1 #= Array =#, itr, iteratoreltype(itr), iteratorsize(
226229

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

232+
function _collect(cont, itr, ::IteratorEltype, isz::IsScalar)
233+
a = _similar_for(cont, typeof(itr), itr, isz)
234+
a[start(eachindex(a))] = itr
235+
return a
236+
end
237+
229238
_collect(cont, itr, ::HasEltype, isz::Union{HasLength,HasShape}) =
230239
copy!(_similar_for(cont, eltype(itr), itr, isz), itr)
231240

base/dict.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ _tt1{A,B}(::Type{Pair{A,B}}) = A
186186
_tt2{A,B}(::Type{Pair{A,B}}) = B
187187
eltype{D}(::Type{KeyIterator{D}}) = _tt1(eltype(D))
188188
eltype{D}(::Type{ValueIterator{D}}) = _tt2(eltype(D))
189+
iteratorsize{T<:Union{KeyIterator,ValueIterator}}(::Type{T}) = HasLength()
189190

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

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

276278
function isequal(l::Associative, r::Associative)
277279
l === r && return true

base/essentials.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ done(v::SimpleVector,i) = (i > v.length)
173173
isempty(v::SimpleVector) = (v.length == 0)
174174
indices(v::SimpleVector, d) = d == 1 ? (1:length(v)) : (1:1)
175175
linearindices(v::SimpleVector) = indices(v, 1)
176+
iteratorsize(::Type{SimpleVector}) = HasLength()
176177

177178
function ==(v1::SimpleVector, v2::SimpleVector)
178179
length(v1)==length(v2) || return false

base/generator.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,19 @@ end
2929

3030
abstract IteratorSize
3131
immutable SizeUnknown <: IteratorSize end
32+
immutable IsScalar <: IteratorSize end
3233
immutable HasLength <: IteratorSize end
3334
immutable HasShape <: IteratorSize end
3435
immutable IsInfinite <: IteratorSize end
3536

3637
iteratorsize(x) = iteratorsize(typeof(x))
37-
iteratorsize(::Type) = HasLength() # HasLength is the default
38+
iteratorsize(::Type) = IsScalar() # IsScalar is the default
3839

3940
and_iteratorsize{T}(isz::T, ::T) = isz
4041
and_iteratorsize(::HasLength, ::HasShape) = HasLength()
4142
and_iteratorsize(::HasShape, ::HasLength) = HasLength()
43+
and_iteratorsize(::IsScalar, ::Union{HasLength,HasShape}) = IsScalar()
44+
and_iteratorsize(::Union{HasLength,HasShape}, ::IsScalar) = IsScalar()
4245
and_iteratorsize(a, b) = SizeUnknown()
4346

4447
abstract IteratorEltype

base/iterator.jl

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ iteratoreltype{I}(::Type{Enumerate{I}}) = iteratoreltype(I)
3838
abstract AbstractZipIterator
3939

4040
zip_iteratorsize(a, b) = and_iteratorsize(a,b) # as `and_iteratorsize` but inherit `Union{HasLength,IsInfinite}` of the shorter iterator
41+
zip_iteratorsize(::IsScalar, ::IsInfinite) = HasLength()
4142
zip_iteratorsize(::HasLength, ::IsInfinite) = HasLength()
4243
zip_iteratorsize(::HasShape, ::IsInfinite) = HasLength()
4344
zip_iteratorsize(a::IsInfinite, b) = zip_iteratorsize(b,a)
@@ -308,20 +309,16 @@ iteratoreltype{O}(::Type{Repeated{O}}) = HasEltype()
308309
abstract AbstractProdIterator
309310

310311
length(p::AbstractProdIterator) = prod(size(p))
311-
size(p::AbstractProdIterator) = _prod_size(p.a, p.b, iteratorsize(p.a), iteratorsize(p.b))
312+
size(p::AbstractProdIterator) = _prod_size(p.a, p.b)
312313
ndims(p::AbstractProdIterator) = length(size(p))
313314

314315
# generic methods to handle size of Prod* types
316+
_prod_size(a, ::IsScalar) = (1,)
315317
_prod_size(a, ::HasShape) = size(a)
316318
_prod_size(a, ::HasLength) = (length(a), )
317-
_prod_size(a, A) =
319+
_prod_size(a, ::IteratorSize) =
318320
throw(ArgumentError("Cannot compute size for object of type $(typeof(a))"))
319-
_prod_size(a, b, ::HasLength, ::HasLength) = (length(a), length(b))
320-
_prod_size(a, b, ::HasLength, ::HasShape) = (length(a), size(b)...)
321-
_prod_size(a, b, ::HasShape, ::HasLength) = (size(a)..., length(b))
322-
_prod_size(a, b, ::HasShape, ::HasShape) = (size(a)..., size(b)...)
323-
_prod_size(a, b, A, B) =
324-
throw(ArgumentError("Cannot construct size for objects of types $(typeof(a)) and $(typeof(b))"))
321+
_prod_size(a, b) = (_prod_size(a, iteratorsize(a))..., _prod_size(b, iteratorsize(b))...)
325322

326323
# one iterator
327324
immutable Prod1{I} <: AbstractProdIterator
@@ -413,6 +410,9 @@ iteratorsize{I1,I2}(::Type{Prod{I1,I2}}) = prod_iteratorsize(iteratorsize(I1),it
413410
((x[1][1],x[1][2]...), x[2])
414411
end
415412

413+
prod_iteratorsize(::IsScalar, ::IsScalar) = IsScalar()
414+
prod_iteratorsize(::IsScalar, isz::Union{HasLength,HasShape}) = isz
415+
prod_iteratorsize(isz::Union{HasLength,HasShape}, ::IsScalar) = isz
416416
prod_iteratorsize(::Union{HasLength,HasShape}, ::Union{HasLength,HasShape}) = HasShape()
417417
# products can have an infinite iterator
418418
prod_iteratorsize(::IsInfinite, ::IsInfinite) = IsInfinite()
@@ -534,6 +534,7 @@ type PartitionIterator{T}
534534
end
535535

536536
eltype{T}(::Type{PartitionIterator{T}}) = Vector{eltype(T)}
537+
iteratorsize{T<:PartitionIterator}(::Type{T}) = HasLength()
537538

538539
function length(itr::PartitionIterator)
539540
l = length(itr.c)

base/reflection.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ isempty(m::MethodList) = isempty(m.ms)
231231
start(m::MethodList) = start(m.ms)
232232
done(m::MethodList, s) = done(m.ms, s)
233233
next(m::MethodList, s) = next(m.ms, s)
234+
iteratorsize(::Type{MethodList}) = HasLength()
234235

235236
function MethodList(mt::MethodTable)
236237
ms = Method[]

base/strings/basic.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## core string functions ##
44

5+
iteratorsize{T<:AbstractString}(::Type{T}) = HasLength()
6+
57
endof(s::AbstractString) = error("you must implement endof(", typeof(s), ")")
68
next(s::AbstractString, i::Int) = error("you must implement next(", typeof(s), ",Int)")
79
next(s::DirectIndexString, i::Int) = (s[i],i+1)

base/strings/utf8proc.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Various Unicode functionality from the utf8proc library
44
module UTF8proc
55

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

88
export isgraphemebreak
99

@@ -190,6 +190,7 @@ end
190190
graphemes(s::AbstractString) = GraphemeIterator{typeof(s)}(s)
191191

192192
eltype{S}(::Type{GraphemeIterator{S}}) = SubString{S}
193+
iteratorsize{T<:GraphemeIterator}(::Type{T}) = Base.HasLength()
193194

194195
function length(g::GraphemeIterator)
195196
c0 = Char(0x00ad) # soft hyphen (grapheme break always allowed after this)

base/tuple.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ getindex(t::Tuple, b::AbstractArray{Bool}) = getindex(t,find(b))
1212

1313
## iterating ##
1414

15+
<<<<<<< HEAD
16+
iteratorsize{T<:Tuple}(::Type{T}) = HasLength()
17+
=======
18+
iteratorsize(::Tuple) = HasLength()
19+
>>>>>>> d7ef4cc... Add default IsScalar trait
20+
1521
start(t::Tuple) = 1
1622
done(t::Tuple, i::Int) = (length(t) < i)
1723
next(t::Tuple, i::Int) = (t[i], i+1)

0 commit comments

Comments
 (0)