Skip to content

Commit f50ebe9

Browse files
authored
Idempotent indexing using offset ranges (#156)
* preserve axes while indexing with IdOffsetRange * Idempotent indexing for IdentityUnitRange
1 parent dc867d5 commit f50ebe9

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

src/OffsetArrays.jl

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -305,22 +305,29 @@ const IIUR = IdentityUnitRange{S} where S<:AbstractUnitRange{T} where T<:Integer
305305

306306
Base.step(a::OffsetRange) = step(parent(a))
307307

308-
Base.getindex(a::OffsetRange, r::OffsetRange) = OffsetArray(a[parent(r)], r.offsets)
309-
Base.getindex(a::OffsetRange, r::AbstractRange) = a.parent[r .- a.offsets[1]]
310-
Base.getindex(a::AbstractRange, r::OffsetRange) = OffsetArray(a[parent(r)], r.offsets)
308+
@propagate_inbounds Base.getindex(a::OffsetRange, r::OffsetRange) = OffsetArray(a[parent(r)], r.offsets)
309+
@propagate_inbounds function Base.getindex(a::OffsetRange, r::IdOffsetRange)
310+
OffsetArray(a.parent[r.parent .+ (r.offset - a.offsets[1])], r.offset)
311+
end
312+
@propagate_inbounds Base.getindex(r::OffsetRange, s::IIUR) =
313+
OffsetArray(r[s.indices], s)
314+
@propagate_inbounds Base.getindex(a::OffsetRange, r::AbstractRange) = a.parent[r .- a.offsets[1]]
315+
@propagate_inbounds Base.getindex(a::AbstractRange, r::OffsetRange) = OffsetArray(a[parent(r)], r.offsets)
311316

312317
@propagate_inbounds Base.getindex(r::UnitRange, s::IIUR) =
313318
OffsetArray(r[s.indices], s)
314319

315320
@propagate_inbounds Base.getindex(r::StepRange, s::IIUR) =
316321
OffsetArray(r[s.indices], s)
317322

318-
@inline @propagate_inbounds Base.getindex(r::StepRangeLen{T,<:Base.TwicePrecision,<:Base.TwicePrecision}, s::IIUR) where T =
323+
# this method is needed for ambiguity resolution
324+
@propagate_inbounds Base.getindex(r::StepRangeLen{T,<:Base.TwicePrecision,<:Base.TwicePrecision}, s::IIUR) where T =
319325
OffsetArray(r[s.indices], s)
320-
@inline @propagate_inbounds Base.getindex(r::StepRangeLen{T}, s::IIUR) where {T} =
326+
327+
@propagate_inbounds Base.getindex(r::StepRangeLen{T}, s::IIUR) where {T} =
321328
OffsetArray(r[s.indices], s)
322329

323-
@inline @propagate_inbounds Base.getindex(r::LinRange, s::IIUR) =
330+
@propagate_inbounds Base.getindex(r::LinRange, s::IIUR) =
324331
OffsetArray(r[s.indices], s)
325332

326333
function Base.show(io::IO, r::OffsetRange)

test/runtests.jl

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,15 @@ end
231231
r = -2:5
232232
y = OffsetArray(r, r)
233233
@test axes(y) == (r,)
234+
@test step(y) == step(r)
234235
y = OffsetArray(r, (r,))
235236
@test axes(y) == (r,)
237+
238+
s = -2:2:4
239+
r = 5:8
240+
y = OffsetArray(s, r)
241+
@test axes(y) == (r,)
242+
@test step(y) == step(s)
236243
end
237244

238245
@testset "OffsetArray of OffsetArray construction" begin
@@ -351,6 +358,19 @@ end
351358
r1 = OffsetArray(8:10, -1:1)[OffsetArray(0:1, -5:-4)]
352359
@test axes(r1) == (IdentityUnitRange(-5:-4),)
353360
@test parent(r1) === 9:10
361+
362+
a = OffsetVector(3:4, 10:11)
363+
ax = OffsetArrays.IdOffsetRange(5:6, 5)
364+
@test axes(a[ax]) == axes(ax)
365+
for i in axes(ax,1)
366+
@test a[ax[i]] == a[ax][i]
367+
end
368+
369+
ax = IdentityUnitRange(10:11)
370+
@test axes(a[ax]) == axes(ax)
371+
for i in axes(ax,1)
372+
@test a[ax[i]] == a[ax][i]
373+
end
354374
end
355375

356376
@testset "CartesianIndexing" begin
@@ -651,7 +671,7 @@ end
651671
v = view(A0, 1:1, i1)
652672
@test axes(v) == (Base.OneTo(1), IdentityUnitRange(-4:-3))
653673

654-
for r in (1:10, 1:1:10, StepRangeLen(1, 1, 10), LinRange(1, 10, 10))
674+
for r in (1:10, 1:1:10, StepRangeLen(1, 1, 10), LinRange(1, 10, 10), 0.1:0.2:0.9)
655675
for s in (IdentityUnitRange(2:3), OffsetArray(2:3, 2:3))
656676
@test axes(r[s]) == axes(s)
657677
end

0 commit comments

Comments
 (0)