Skip to content

Commit 93b7ea6

Browse files
committed
Generalize indexing and reduce its ambiguity footprint
This should support non-scalar static indexing for any dimensionality (not just dimensions 1-4). By having fewer `getindex` and `setindex!` methods it should also substantially reduce the likelihood of ambiguities with other packages.
1 parent da4a1ed commit 93b7ea6

File tree

1 file changed

+23
-92
lines changed

1 file changed

+23
-92
lines changed

src/indexing.jl

Lines changed: 23 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ setindex!(a::StaticArray, value, i::Int) = error("setindex!(::$(typeof(a)), valu
88

99
# Note: all indexing behavior defaults to dense, linear indexing
1010

11-
@propagate_inbounds function getindex(a::StaticArray, inds::Int...)
12-
@boundscheck checkbounds(a, inds...)
11+
@propagate_inbounds function getindex(a::StaticArray{<:Tuple,<:Any,N}, inds::Vararg{Int,N}) where N
12+
@boundscheck checkbounds(a, inds...)
1313
_getindex_scalar(Size(a), a, inds...)
1414
end
1515

@@ -30,8 +30,8 @@ end
3030
end
3131
end
3232

33-
@propagate_inbounds function setindex!(a::StaticArray, value, inds::Int...)
34-
@boundscheck checkbounds(a, inds...)
33+
@propagate_inbounds function setindex!(a::StaticArray{<:Tuple,<:Any,N}, value, inds::Vararg{Int,N}) where N
34+
@boundscheck checkbounds(a, inds...)
3535
_setindex!_scalar(Size(a), a, value, inds...)
3636
end
3737

@@ -182,46 +182,32 @@ end
182182
## Multidimensional non-scalar indexing ##
183183
###########################################
184184

185-
# getindex
186-
187-
@propagate_inbounds function getindex(a::StaticArray, inds::Union{Int, StaticArray{<:Any, Int}, Colon}...)
188-
_getindex(a, index_sizes(Size(a), inds...), inds)
189-
end
185+
# To intercept `A[i1, ...]` where all `i` indexes have static sizes,
186+
# create a wrapper used to mark non-scalar indexing operations.
187+
# We insert this at a point in the dispatch hierarchy where we can intercept any
188+
# `typeof(A)` (specifically, including dynamic arrays) without triggering ambiguities.
190189

191-
# Hard to describe "Union{Int, StaticArray{<:Any, Int}} with at least one StaticArray{<:Any, Int}"
192-
# Here we require the first StaticArray{<:Any, Int} to be within the first four dimensions
193-
@propagate_inbounds function getindex(a::AbstractArray, i1::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
194-
_getindex(a, index_sizes(i1, inds...), (i1, inds...))
190+
struct StaticIndexing{I}
191+
ind::I
195192
end
193+
unwrap(i::StaticIndexing) = i.ind
196194

197-
@propagate_inbounds function getindex(a::AbstractArray, i1::Int, i2::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
198-
_getindex(a, index_sizes(i1, i2, inds...), (i1, i2, inds...))
195+
function Base.to_indices(A, I::Tuple{Vararg{Union{Integer, CartesianIndex, StaticArray{<:Tuple,Int}}}})
196+
inds = to_indices(A, axes(A), I)
197+
return map(StaticIndexing, inds)
199198
end
200199

201-
@propagate_inbounds function getindex(a::AbstractArray, i1::Int, i2::Int, i3::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
202-
_getindex(a, index_sizes(i1, i2, i3, inds...), (i1, i2, i3, inds...))
203-
end
204-
205-
@propagate_inbounds function getindex(a::AbstractArray, i1::Int, i2::Int, i3::Int, i4::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
206-
_getindex(a, index_sizes(i1, i2, i3, i4, inds...), (i1, i2, i3, i4, inds...))
207-
end
208-
209-
# Disambuguity methods for the above
210-
@propagate_inbounds function getindex(a::StaticArray, i1::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
211-
_getindex(a, index_sizes(i1, inds...), (i1, inds...))
212-
end
200+
# getindex
213201

214-
@propagate_inbounds function getindex(a::StaticArray, i1::Int, i2::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
215-
_getindex(a, index_sizes(i1, i2, inds...), (i1, i2, inds...))
202+
@propagate_inbounds function getindex(a::StaticArray, inds::Union{Int, StaticArray{<:Any, Int}, Colon}...)
203+
_getindex(a, index_sizes(Size(a), inds...), inds)
216204
end
217205

218-
@propagate_inbounds function getindex(a::StaticArray, i1::Int, i2::Int, i3::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
219-
_getindex(a, index_sizes(i1, i2, i3, inds...), (i1, i2, i3, inds...))
206+
function Base._getindex(::IndexStyle, A::AbstractArray, i1::StaticIndexing, I::StaticIndexing...)
207+
inds = (unwrap(i1), map(unwrap, I)...)
208+
return StaticArrays._getindex(A, index_sizes(inds...), inds)
220209
end
221210

222-
@propagate_inbounds function getindex(a::StaticArray, i1::Int, i2::Int, i3::Int, i4::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
223-
_getindex(a, index_sizes(i1, i2, i3, i4, inds...), (i1, i2, i3, i4, inds...))
224-
end
225211

226212
@generated function _getindex(a::AbstractArray, ind_sizes::Tuple{Vararg{Size}}, inds)
227213
newsize = out_index_size(ind_sizes.parameters...)
@@ -265,64 +251,9 @@ end
265251
_setindex!(a, value, index_sizes(Size(a), inds...), inds)
266252
end
267253

268-
# Hard to describe "Union{Int, StaticArray{<:Any, Int}} with at least one StaticArray{<:Any, Int}"
269-
# Here we require the first StaticArray{<:Any, Int} to be within the first four dimensions
270-
@propagate_inbounds function setindex!(a::AbstractArray, value, i1::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
271-
_setindex!(a, value, index_sizes(i1, inds...), (i1, inds...))
272-
end
273-
274-
@propagate_inbounds function setindex!(a::AbstractArray, value, i1::Int, i2::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
275-
_setindex!(a, value, index_sizes(i1, i2, inds...), (i1, i2, inds...))
276-
end
277-
278-
@propagate_inbounds function setindex!(a::AbstractArray, value, i1::Int, i2::Int, i3::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
279-
_setindex!(a, value, index_sizes(i1, i2, i3, inds...), (i1, i2, i3, inds...))
280-
end
281-
282-
@propagate_inbounds function setindex!(a::AbstractArray, value, i1::Int, i2::Int, i3::Int, i4::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
283-
_setindex!(a, value, index_sizes(i1, i2, i3, i4, inds...), (i1, i2, i3, i4, inds...))
284-
end
285-
286-
# Disambiguity methods for the above
287-
@propagate_inbounds function setindex!(a::StaticArray, value, i1::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
288-
_setindex!(a, value, index_sizes(i1, inds...), (i1, inds...))
289-
end
290-
291-
@propagate_inbounds function setindex!(a::StaticArray, value, i1::Int, i2::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
292-
_setindex!(a, value, index_sizes(i1, i2, inds...), (i1, i2, inds...))
293-
end
294-
295-
@propagate_inbounds function setindex!(a::StaticArray, value, i1::Int, i2::Int, i3::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
296-
_setindex!(a, value, index_sizes(i1, i2, i3, inds...), (i1, i2, i3, inds...))
297-
end
298-
299-
@propagate_inbounds function setindex!(a::StaticArray, value, i1::Int, i2::Int, i3::Int, i4::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
300-
_setindex!(a, value, index_sizes(i1, i2, i3, i4, inds...), (i1, i2, i3, i4, inds...))
301-
end
302-
303-
# disambiguities from Base
304-
@propagate_inbounds function setindex!(a::Array, value, i1::StaticVector{<:Any, Int})
305-
_setindex!(a, value, index_sizes(i1), (i1,))
306-
end
307-
308-
@propagate_inbounds function setindex!(a::Array, value::AbstractArray, i1::StaticVector{<:Any, Int})
309-
_setindex!(a, value, index_sizes(i1), (i1,))
310-
end
311-
312-
@propagate_inbounds function setindex!(a::Array, value::AbstractArray, i1::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
313-
_setindex!(a, value, index_sizes(i1, inds...), (i1, inds...))
314-
end
315-
316-
@propagate_inbounds function setindex!(a::Array, value::AbstractArray, i1::Int, i2::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
317-
_setindex!(a, value, index_sizes(i1, i2, inds...), (i1, i2, inds...))
318-
end
319-
320-
@propagate_inbounds function setindex!(a::Array, value::AbstractArray, i1::Int, i2::Int, i3::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
321-
_setindex!(a, value, index_sizes(i1, i2, i3, inds...), (i1, i2, i3, inds...))
322-
end
323-
324-
@propagate_inbounds function setindex!(a::Array, value::AbstractArray, i1::Int, i2::Int, i3::Int, i4::StaticArray{<:Any, Int}, inds::Union{Int, StaticArray{<:Any, Int}}...)
325-
_setindex!(a, value, index_sizes(i1, i2, i3, i4, inds...), (i1, i2, i3, i4, inds...))
254+
function Base._setindex!(::IndexStyle, a::AbstractArray, value, i1::StaticIndexing, I::StaticIndexing...)
255+
inds = (unwrap(i1), map(unwrap, I)...)
256+
return StaticArrays._setindex!(a, value, index_sizes(inds...), inds)
326257
end
327258

328259
# setindex! from a scalar

0 commit comments

Comments
 (0)