Skip to content

Commit ecb8f8f

Browse files
Preserve blocking of indices when slicing a unit range with a blocked unit range (#465)
Fixes #367. --------- Co-authored-by: Sheehan Olver <[email protected]>
1 parent b717822 commit ecb8f8f

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

src/blockaxis.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ function Base.AbstractUnitRange{T}(r::BlockedUnitRange) where {T}
105105
return _BlockedUnitRange(convert(T,first(r)), convert.(T,blocklasts(r)))
106106
end
107107

108+
# See: https://github.com/JuliaLang/julia/blob/b06d26075bf7b3f4e7f1b64b120f5665d8ed76f9/base/range.jl#L991-L1004
109+
function Base.getindex(r::AbstractUnitRange, s::AbstractBlockedUnitRange{T}) where {T<:Integer}
110+
@boundscheck checkbounds(r, s)
111+
112+
f = first(r)
113+
start = oftype(f, f + first(s) - firstindex(r))
114+
lens = map(Base.Fix1(oftype, f), blocklengths(s))
115+
return blockedrange(start, lens)
116+
end
117+
108118
"""
109119
BlockedOneTo{T, <:Union{AbstractVector{T}, NTuple{<:Any,T}}} where {T}
110120
@@ -164,6 +174,16 @@ function Base.AbstractUnitRange{T}(r::BlockedOneTo) where {T}
164174
return BlockedOneTo(convert.(T,blocklasts(r)))
165175
end
166176

177+
# See: https://github.com/JuliaLang/julia/blob/b06d26075bf7b3f4e7f1b64b120f5665d8ed76f9/base/range.jl#L1006-L1010
178+
function getindex(r::Base.OneTo{T}, s::BlockedOneTo) where T
179+
@inline
180+
@boundscheck checkbounds(r, s)
181+
return BlockedOneTo(convert(AbstractVector{T}, blocklasts(s)))
182+
end
183+
function getindex(r::BlockedOneTo{T}, s::BlockedOneTo) where T
184+
return Base.oneto(r)[s]
185+
end
186+
167187
"""
168188
blockedrange(blocklengths::Union{Tuple, AbstractVector})
169189
blockedrange(first::Integer, blocklengths::Union{Tuple, AbstractVector})

test/test_blockindices.jl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,40 @@ end
330330
end
331331
end
332332

333+
@testset "BlockedUnitRange indexing" begin
334+
a = 2:10
335+
b = blockedrange(2, [1,2,3])
336+
@test a[b] == blockedrange(3, [1,2,3])
337+
@test a[b] isa BlockedUnitRange
338+
@test first(a[b]) == 3
339+
@test blocklengths(a[b]) == [1,2,3]
340+
@test_throws BoundsError a[blockedrange(5, [1,2,3])]
341+
342+
a = blockedrange(2, [4,5])
343+
b = blockedrange(2, [1,2,3])
344+
@test a[b] == blockedrange(3, [1,2,3])
345+
@test a[b] isa BlockedUnitRange
346+
@test first(a[b]) == 3
347+
@test blocklengths(a[b]) == [1,2,3]
348+
@test_throws BoundsError a[blockedrange(5, [1,2,3])]
349+
350+
a = Base.OneTo(9)
351+
b = blockedrange([1,2,3])
352+
@test a[b] == blockedrange([1,2,3])
353+
@test a[b] isa BlockedOneTo
354+
@test first(a[b]) == 1
355+
@test blocklengths(a[b]) == [1,2,3]
356+
@test_throws BoundsError a[blockedrange([1,2,3,4])]
357+
358+
a = blockedrange([4,5])
359+
b = blockedrange([1,2,3])
360+
@test a[b] == blockedrange([1,2,3])
361+
@test a[b] isa BlockedOneTo
362+
@test first(a[b]) == 1
363+
@test blocklengths(a[b]) == [1,2,3]
364+
@test_throws BoundsError a[blockedrange([1,2,3,4])]
365+
end
366+
333367
@testset "misc" begin
334368
b = blockedrange(1, [1,2,3])
335369
@test axes(b) == Base.unsafe_indices(b) == (b,)

0 commit comments

Comments
 (0)