The basic technique Keno was referencing is something that’s generally quite feasible, and I think there is a package somewhere that does it (but I cannot find it at the moment).
julia> struct End end
julia> Base.to_indices(A, inds, I::Tuple{End, Vararg}) = (inds[1][end], to_indices(A, Base.tail(inds), Base.tail(I))...)
With just those two definitions, we can now use End()
in many places that didn’t use to be possible:
julia> A = rand(3,5)
3×5 Array{Float64,2}:
0.0496429 0.1541 0.178673 0.987561 0.100913
0.273997 0.984579 0.255768 0.862814 0.200435
0.317385 0.445612 0.106676 0.00631464 0.934804
julia> A[End(), 2]
0.4456115553735922
julia> view(A, End(), 2:3)
2-element view(::Array{Float64,2}, 3, 2:3) with eltype Float64:
0.4456115553735922
0.10667647668776192
Now, the trouble you’ll rapidly run into is that you cannot do computation on this End()
thing.
julia> A[End() - 1, :]
ERROR: MethodError: no method matching -(::End, ::Int64)
So you can manually add in “deferred” computations, essentially allowing it to build up a thunk that it can evaluate once it knows the size of the array. This is the huge advantage to the end
keyword — it is just syntax for the appropriate lastindex
function call, which returns a real integer on which you can do real computation.
Now this finally brings us to your actual question, which is can you use this thing with a CartesianIndex
? The answer there is a flat no. CartesianIndex
is hardcoded to only handle Int
s. But the game isn’t over — you can of course construct your own type that will work just like CartesianIndex but allow for more things to be stored in it. It’s just a bit more complicated, but that to_indices
is the only API that you need to extend.