Skip to content

Commit f3bef32

Browse files
author
Pietro Vertechi
authored
apply index_type on value (#204)
1 parent 49611ce commit f3bef32

File tree

2 files changed

+23
-27
lines changed

2 files changed

+23
-27
lines changed

src/structarray.jl

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,28 +21,23 @@ struct StructArray{T, N, C<:Tup, I} <: AbstractArray{T, N}
2121
axes(c[i]) == ax || error("all field arrays must have same shape")
2222
end
2323
end
24-
new{T, N, C, index_type(C)}(c)
24+
new{T, N, C, index_type(c)}(c)
2525
end
2626
end
2727

28-
# compute optimal type to use for indexing as a function of component types
29-
index_type(::Type{NamedTuple{names, types}}) where {names, types} = index_type(types)
30-
index_type(::Type{Tuple{}}) = Int
31-
function index_type(::Type{T}) where {T<:Tuple}
32-
S, U = tuple_type_head(T), tuple_type_tail(T)
33-
return _index_type(S, U)
28+
# compute optimal type to use for indexing as a function of components
29+
index_type(components::NamedTuple) = index_type(values(components))
30+
index_type(::Tuple{}) = Int
31+
function index_type(components::Tuple)
32+
f, ls = first(components), tail(components)
33+
return IndexStyle(f) isa IndexCartesian ? CartesianIndex{ndims(f)} : index_type(ls)
3434
end
35-
# Julia v1.7.0-beta3 doesn't seem to specialize `index_type` as defined above
36-
# for tuple types with "many" elements (three or four, depending on the concrete
37-
# types). However, we can help the compiler for homogeneous types by defining
38-
# the specialization below.
39-
index_type(::Type{NTuple{N, S}}) where {N, S} = _index_type(S)
35+
# Only check first component if the all the component types match
36+
index_type(components::NTuple) = invoke(index_type, Tuple{Tuple}, (first(components),))
37+
# Return the index type parameter as a function of the StructArray type or instance
38+
index_type(s::StructArray) = index_type(typeof(s))
4039
index_type(::Type{StructArray{T, N, C, I}}) where {T, N, C, I} = I
4140

42-
function _index_type(::Type{S}, ::Type{U}=Tuple{}) where {S, U}
43-
return IndexStyle(S) isa IndexCartesian ? CartesianIndex{ndims(S)} : index_type(U)
44-
end
45-
4641
array_types(::Type{StructArray{T, N, C, I}}) where {T, N, C, I} = array_types(C)
4742
array_types(::Type{NamedTuple{names, types}}) where {names, types} = types
4843
array_types(::Type{TT}) where {TT<:Tuple} = TT
@@ -168,7 +163,6 @@ function buildfromslices(::Type{T}, unwrap::F, slices) where {T,F}
168163
end
169164
end
170165

171-
172166
function Base.IndexStyle(::Type{S}) where {S<:StructArray}
173167
index_type(S) === Int ? IndexLinear() : IndexCartesian()
174168
end

test/runtests.jl

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,10 @@ end
5050
end
5151

5252
@testset "indexstyle" begin
53-
@inferred IndexStyle(StructArray(a=rand(10,10), b=view(rand(100,100), 1:10, 1:10)))
5453
s = StructArray(a=rand(10,10), b=view(rand(100,100), 1:10, 1:10))
5554
T = typeof(s)
5655
@test IndexStyle(T) === IndexCartesian()
57-
@test StructArrays.index_type(T) == CartesianIndex{2}
56+
@test StructArrays.index_type(s) == CartesianIndex{2}
5857
@test s[100] == s[10, 10] == (a=s.a[10,10], b=s.b[10,10])
5958
s[100] = (a=1, b=1)
6059
@test s[100] == s[10, 10] == (a=1, b=1)
@@ -63,22 +62,25 @@ end
6362
@inferred IndexStyle(StructArray(a=rand(10,10), b=rand(10,10)))
6463
s = StructArray(a=rand(10,10), b=rand(10,10))
6564
T = typeof(s)
66-
@test IndexStyle(T) === IndexLinear()
67-
@test StructArrays.index_type(T) == Int
65+
@test StructArrays.index_type(s) == Int
66+
@inferred IndexStyle(s)
6867
@test s[100] == s[10, 10] == (a=s.a[10,10], b=s.b[10,10])
6968
s[100] = (a=1, b=1)
7069
@test s[100] == s[10, 10] == (a=1, b=1)
7170
s[10, 10] = (a=0, b=0)
7271
@test s[100] == s[10, 10] == (a=0, b=0)
7372

7473
# inference for "many" types, both for linear ad Cartesian indexing
75-
@inferred StructArrays.index_type(NTuple{2, Vector{Float64}})
76-
@inferred StructArrays.index_type(NTuple{3, Matrix{Float64}})
77-
@inferred StructArrays.index_type(NTuple{4, Array{Float64, 3}})
74+
@inferred StructArrays.index_type(ntuple(_ -> rand(5), 2))
75+
@inferred StructArrays.index_type(ntuple(_ -> rand(5, 5), 3))
76+
@inferred StructArrays.index_type(ntuple(_ -> rand(5, 5, 5), 4))
77+
78+
@inferred StructArrays.index_type(ntuple(_ -> view(rand(5), 1:3), 2))
79+
@inferred StructArrays.index_type(ntuple(_ -> view(rand(5, 5), 1:3, 1:2), 3))
80+
@inferred StructArrays.index_type(ntuple(_ -> view(rand(5, 5, 5), 1:3, 1:2, 1:4), 4))
7881

79-
@inferred StructArrays.index_type(NTuple{2, SubArray{Float64, 1, Array{Float64, 2}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}})
80-
@inferred StructArrays.index_type(NTuple{3, SubArray{Float64, 1, Array{Float64, 2}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}})
81-
@inferred StructArrays.index_type(NTuple{4, SubArray{Float64, 1, Array{Float64, 2}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}})
82+
@inferred StructArrays.index_type(ntuple(n -> n == 1 ? rand(5, 5) : view(rand(5, 5), 1:2, 1:3), 5))
83+
@inferred IndexStyle(StructArray(a=rand(10,10), b=view(rand(100,100), 1:10, 1:10)))
8284
end
8385

8486
@testset "replace_storage" begin

0 commit comments

Comments
 (0)