Access a tuple of structs using the values of an integer array

And here’s a simpler solution based on @Tortar’s idea:

struct Foo{T}
    a :: T
    b :: T
end
foos = (Foo(1,2), Foo(3.0,4.0))
I = zeros(Int, (100,200,300));
@. I[1:50,:,:] = 1;
@. I[51:100,:,:] = 2;
case_expr(idx, n) = idx == n ?
    :(foos[$idx]) :
    :(i == $idx ? foos[$idx] : $(case_expr(idx+1, n)))
@generated getfoo(foos, i) = case_expr(1, fieldcount(foos))

function bar(foos, I)
    s = 0.0
    @inbounds for i in eachindex(I)
        s += getfoo(foos, I[i]).a
    end
    return s
end

julia> @btime bar($foos, $I)
  5.696 ms (0 allocations: 0 bytes)

(I’m wary about generated functions due to the possible undefined behavior but it seems safe here.)

3 Likes