Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ CartesianIndex{N}(index::NTuple{N,Integer}) = CartesianIndex{N}(index)
(::Type{CartesianIndex{N}}){N}(index::Integer...) = CartesianIndex{N}(index)
(::Type{CartesianIndex{N}}){N}() = CartesianIndex{N}(())
# Un-nest passed CartesianIndexes
CartesianIndex(index::Union{Integer, CartesianIndex}...) = CartesianIndex(_flatten((), index...))
_flatten(out) = out
@inline _flatten(out, i::Integer, I...) = _flatten((out..., i), I...)
@inline _flatten(out, i::CartesianIndex, I...) = _flatten((out..., i.I...), I...)
CartesianIndex(index::Union{Integer, CartesianIndex}...) = CartesianIndex(flatten(index))
Base.@pure flatten(I) = (_flatten(I...)...,)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this different than the flatten in iterators.jl ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It produces the same outcome, but it's non-lazy. Note that I'm not importing Base.flatten, so this doesn't "globally" extend flatten.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw, I think a pure function should usually not be extended, but I'm not certain.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean, there should be only one method?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps. although more importantly, external code need to be careful about how they overload it (e.g. don't write code that could trigger a #265-style error)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For sure. Come to think of it, I don't need the @pure annotation on _flatten, just on flatten. (right?)

The only reason it was marked pure is because of #17126, but this flatten has since been redesigned several times, and in testing with this version I'm getting equal performance with @inline. So I'll change it.

Base.@pure _flatten() = ()
Base.@pure _flatten(i, I...) = (i, _flatten(I...)...)
Base.@pure _flatten(i::CartesianIndex, I...) = (i.I..., _flatten(I...)...)
CartesianIndex(index::Tuple{Vararg{Union{Integer, CartesianIndex}}}) = CartesianIndex(index...)

# length
Expand Down Expand Up @@ -374,10 +375,10 @@ end
end

@propagate_inbounds function _getindex{T,N}(l::LinearIndexing, A::AbstractArray{T,N}, I::Union{Real,AbstractArray,Colon,CartesianIndex}...)
getindex(A, IteratorsMD._flatten((), I...)...)
getindex(A, IteratorsMD.flatten(I)...)
end
@propagate_inbounds function _setindex!{T,N}(l::LinearIndexing, A::AbstractArray{T,N}, v, I::Union{Real,AbstractArray,Colon,CartesianIndex}...)
setindex!(A, v, IteratorsMD._flatten((), I...)...)
setindex!(A, v, IteratorsMD.flatten(I)...)
end

##
Expand Down
3 changes: 3 additions & 0 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,9 @@ a[1,CartesianIndex{2}(3,4)] = -2
@test a[CartesianIndex{1}(2),3,CartesianIndex{1}(4)] == 44
a[CartesianIndex{1}(2),3,CartesianIndex{1}(3)] = -3
@test a[CartesianIndex{1}(2),3,CartesianIndex{1}(3)] == -3
@test a[:, :, CartesianIndex((1,))] == a[:,:,1]
@test a[CartesianIndex((1,)), [1,2], :] == a[1,[1,2],:]
@test a[CartesianIndex((2,)), 3:4, :] == a[2,3:4,:]

a = view(zeros(3, 4, 5), :, :, :)
a[CartesianIndex{3}(2,3,3)] = -1
Expand Down