Skip to content

Commit

Permalink
Merge pull request #12090 from JuliaLang/jb/cartesiantuple
Browse files Browse the repository at this point in the history
use NTuple as the representation of a CartesianIndex
  • Loading branch information
JeffBezanson committed Jul 10, 2015
2 parents eca6d16 + 77181ac commit 9ba9130
Showing 1 changed file with 6 additions and 27 deletions.
33 changes: 6 additions & 27 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ export CartesianIndex, CartesianRange
linearindexing{A<:BitArray}(::Type{A}) = LinearFast()

# CartesianIndex
abstract CartesianIndex{N}

@generated function Base.call{N}(::Type{CartesianIndex},index::NTuple{N,Integer})
indextype = gen_cartesian(N)
return Expr(:call,indextype,[:(to_index(index[$i])) for i=1:N]...)
immutable CartesianIndex{N}
I::NTuple{N,Int}
CartesianIndex(index::NTuple{N,Integer}) = new(index)
end

CartesianIndex{N}(index::NTuple{N,Integer}) = CartesianIndex{N}(index)
@generated function Base.call{N}(::Type{CartesianIndex{N}},index::Integer...)
length(index) == N && return :(CartesianIndex(index))
length(index) > N && throw(DimensionMismatch("Cannot create CartesianIndex{$N} from $(length(index)) indexes"))
Expand All @@ -27,33 +27,12 @@ end
end
Base.call{M,N}(::Type{CartesianIndex{N}},index::NTuple{M,Integer}) = CartesianIndex{N}(index...)

let implemented = IntSet()
global gen_cartesian
function gen_cartesian(N::Int)
# Create the types
indextype = symbol("CartesianIndex_$N")
if !in(N,implemented)
fnames = [symbol("I_$i") for i = 1:N]
fields = [Expr(:(::), fnames[i], :Int) for i = 1:N]
extype = Expr(:type, false, Expr(:(<:), indextype, Expr(:curly, :CartesianIndex, N)), Expr(:block, fields...))
eval(extype)
argsleft = [Expr(:(::), fnames[i], :Integer) for i = 1:N]
argsright = [Expr(:call,:to_index,fnames[i]) for i=1:N]
exconstructor = Expr(:(=),Expr(:call,:(Base.call),:(::Type{CartesianIndex{$N}}),argsleft...),Expr(:call,indextype,argsright...))
eval(exconstructor)
push!(implemented,N)
end
return indextype
end
end

# length
length{N}(::CartesianIndex{N})=N
length{N}(::Type{CartesianIndex{N}})=N
length{I<:CartesianIndex}(::Type{I})=length(super(I))

# indexing
getindex(index::CartesianIndex, i::Integer) = getfield(index, i)::Int
getindex(index::CartesianIndex, i::Integer) = index.I[i]

# arithmetic, min/max
for op in (:+, :-, :min, :max)
Expand Down

0 comments on commit 9ba9130

Please sign in to comment.