Skip to content

Commit 0884cc5

Browse files
committed
Support views on empty UnsafeArrays
1 parent 2dd8dbc commit 0884cc5

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

src/unsafe_array.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,20 @@ Base.@propagate_inbounds _unsafe_view_impl(IFwd::NTuple{M,Base.ViewIndex}, A::Un
8787
_unsafe_view_impl((IFwd..., i), A, I...)
8888

8989
@inline function _unsafe_view_impl(IFwd::NTuple{M,Base.Slice}, A::UnsafeArray{T,N}, i::DenseIdx, I::Integer...) where {T,M,N}
90+
ax_A = axes(A)
9091
@assert IFwd == ntuple(i -> axes(A)[i], Val{M}())
9192
I_all = (IFwd..., i, I...)
9293
@boundscheck checkbounds(A, I_all...)
9394
startidxs = map(first, (IFwd..., i, I...))
95+
firstidxs = map(first, ax_A)
9496
sub_s = _sub_size(I_all...)
95-
p = pointer(A, LinearIndices(size(A))[startidxs...])
97+
A_isempty = length(A) == 0
98+
view_isempty = prod(sub_s) == 0
99+
# getindex on LinearIndices fails with startidxs if A is empty, so use pseudo-size in that case:
100+
sz = size(A)
101+
pseudo_sz = ntuple(_ -> 1, Val(N))
102+
mod_size, mod_startidxs = ifelse(A_isempty && view_isempty, (pseudo_sz, firstidxs), (sz, startidxs))
103+
p = pointer(A, LinearIndices(mod_size)[mod_startidxs...])
96104
UnsafeArray(p, sub_s)
97105
end
98106

test/unsafe_array.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ using Random
3434
end
3535

3636

37+
function test_empty_A_UA(test_code::Function, ::Type{T}, Val_N::Val{N}) where {T, N}
38+
A = rand(T, 0, fill(4, N-1)...)
39+
UA = UnsafeArray(pointer(A), size(A))
40+
UnsafeArrays.@gc_preserve A test_code(A, UA)
41+
end
42+
43+
3744
@testset "ctors" begin
3845
test_A(Float64, Val(0)) do A
3946
ptr = pointer(A)
@@ -146,6 +153,11 @@ using Random
146153
@test isbits(view(UA, :, :, :)) == true
147154
@test isbits(view(UA, :, 3, :)) == true
148155
end
156+
157+
test_empty_A_UA(Float32, Val(2)) do A, UA
158+
@test @inferred(view(UA, :, 2:3)) isa UnsafeArray
159+
@test size(@inferred(view(UA, :, 2:3))) == (0, 2)
160+
end
149161
end
150162

151163

0 commit comments

Comments
 (0)