Skip to content

Commit a1e5daf

Browse files
committed
indices extensions for iterators & collect
1 parent 043eb26 commit a1e5daf

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

base/array.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ The result has the same shape and number of dimensions as `collection`.
211211
collect{T}(::Type{T}, itr) = _collect(T, itr, iteratorsize(itr))
212212

213213
_collect{T}(::Type{T}, itr, isz::HasLength) = copy!(Array{T,1}(Int(length(itr)::Integer)), itr)
214-
_collect{T}(::Type{T}, itr, isz::HasShape) = copy!(Array{T}(convert(Dims,size(itr))), itr)
214+
_collect{T}(::Type{T}, itr, isz::HasShape) = copy!(similar(Array{T}, indices(itr)), itr)
215215
function _collect{T}(::Type{T}, itr, isz::SizeUnknown)
216216
a = Array{T,1}(0)
217217
for x in itr
@@ -259,7 +259,7 @@ end
259259
_default_eltype{I,T}(::Type{Generator{I,Type{T}}}) = T
260260

261261
_array_for(T, itr, ::HasLength) = Array{T,1}(Int(length(itr)::Integer))
262-
_array_for(T, itr, ::HasShape) = Array{T}(convert(Dims,size(itr)))
262+
_array_for(T, itr, ::HasShape) = similar(Array{T}, indices(itr))
263263

264264
function collect(itr::Generator)
265265
isz = iteratorsize(itr.iter)

base/iterator.jl

+18-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ end
4949
zip(a) = Zip1(a)
5050
length(z::Zip1) = length(z.a)
5151
size(z::Zip1) = size(z.a)
52+
indices(z::Zip1) = indices(z.a)
5253
eltype{I}(::Type{Zip1{I}}) = Tuple{eltype(I)}
5354
@inline start(z::Zip1) = start(z.a)
5455
@inline function next(z::Zip1, st)
@@ -67,6 +68,7 @@ end
6768
zip(a, b) = Zip2(a, b)
6869
length(z::Zip2) = _min_length(z.a, z.b, iteratorsize(z.a), iteratorsize(z.b))
6970
size(z::Zip2) = promote_shape(size(z.a), size(z.b))
71+
indices(z::Zip2) = promote_shape(indices(z.a), indices(z.b))
7072
eltype{I1,I2}(::Type{Zip2{I1,I2}}) = Tuple{eltype(I1), eltype(I2)}
7173
@inline start(z::Zip2) = (start(z.a), start(z.b))
7274
@inline function next(z::Zip2, st)
@@ -86,6 +88,7 @@ end
8688
zip(a, b, c...) = Zip(a, zip(b, c...))
8789
length(z::Zip) = _min_length(z.a, z.z, iteratorsize(z.a), iteratorsize(z.z))
8890
size(z::Zip) = promote_shape(size(z.a), size(z.z))
91+
indices(z::Zip) = promote_shape(indices(z.a), indices(z.z))
8992
tuple_type_cons{S}(::Type{S}, ::Type{Union{}}) = Union{}
9093
function tuple_type_cons{S,T<:Tuple}(::Type{S}, ::Type{T})
9194
@_pure_meta
@@ -308,8 +311,10 @@ iteratoreltype{O}(::Type{Repeated{O}}) = HasEltype()
308311
abstract AbstractProdIterator
309312

310313
length(p::AbstractProdIterator) = prod(size(p))
314+
_length(p::AbstractProdIterator) = prod(map(unsafe_length, indices(p)))
311315
size(p::AbstractProdIterator) = _prod_size(p.a, p.b, iteratorsize(p.a), iteratorsize(p.b))
312-
ndims(p::AbstractProdIterator) = length(size(p))
316+
indices(p::AbstractProdIterator) = _prod_indices(p.a, p.b, iteratorsize(p.a), iteratorsize(p.b))
317+
ndims(p::AbstractProdIterator) = length(indices(p))
313318

314319
# generic methods to handle size of Prod* types
315320
_prod_size(a, ::HasShape) = size(a)
@@ -323,6 +328,17 @@ _prod_size(a, b, ::HasShape, ::HasShape) = (size(a)..., size(b)...)
323328
_prod_size(a, b, A, B) =
324329
throw(ArgumentError("Cannot construct size for objects of types $(typeof(a)) and $(typeof(b))"))
325330

331+
_prod_indices(a, ::HasShape) = indices(a)
332+
_prod_indices(a, ::HasLength) = (OneTo(length(a)), )
333+
_prod_indices(a, A) =
334+
throw(ArgumentError("Cannot compute indices for object of type $(typeof(a))"))
335+
_prod_indices(a, b, ::HasLength, ::HasLength) = (OneTo(length(a)), OneTo(length(b)))
336+
_prod_indices(a, b, ::HasLength, ::HasShape) = (OneTo(length(a)), indices(b)...)
337+
_prod_indices(a, b, ::HasShape, ::HasLength) = (indices(a)..., OneTo(length(b)))
338+
_prod_indices(a, b, ::HasShape, ::HasShape) = (indices(a)..., indices(b)...)
339+
_prod_indices(a, b, A, B) =
340+
throw(ArgumentError("Cannot construct indices for objects of types $(typeof(a)) and $(typeof(b))"))
341+
326342
# one iterator
327343
immutable Prod1{I} <: AbstractProdIterator
328344
a::I
@@ -331,6 +347,7 @@ product(a) = Prod1(a)
331347

332348
eltype{I}(::Type{Prod1{I}}) = Tuple{eltype(I)}
333349
size(p::Prod1) = _prod_size(p.a, iteratorsize(p.a))
350+
indices(p::Prod1) = _prod_indices(p.a, iteratorsize(p.a))
334351

335352
@inline start(p::Prod1) = start(p.a)
336353
@inline function next(p::Prod1, st)

0 commit comments

Comments
 (0)