Skip to content

Commit d126c66

Browse files
authored
Merge pull request #22441 from JuliaLang/jq/array-union-bits
Support isbits Union array elements and struct fields
2 parents a945af3 + 88341b9 commit d126c66

13 files changed

+702
-137
lines changed

base/array.jl

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,36 @@ size(a::Array{<:Any,N}) where {N} = (@_inline_meta; ntuple(M -> size(a, M), Val(
109109

110110
asize_from(a::Array, n) = n > ndims(a) ? () : (arraysize(a,n), asize_from(a, n+1)...)
111111

112+
"""
113+
Base.isbitsunion(::Type{T})
114+
115+
Return whether a type is an "is-bits" Union type, meaning each type included in a Union is `isbits`.
116+
"""
117+
function isbitsunion end
118+
119+
function isbitsunion(U::Union)
120+
for u in Base.uniontypes(U)
121+
isbits(u) || return false
122+
end
123+
return true
124+
end
125+
isbitsunion(T) = false
126+
127+
"""
128+
Base.bitsunionsize(U::Union)
129+
130+
For a Union of `isbits` types, return the size of the largest type.
131+
"""
132+
function bitsunionsize(U::Union)
133+
sz = 0
134+
for u in Base.uniontypes(U)
135+
sz = max(sz, sizeof(u))
136+
end
137+
return sz
138+
end
139+
112140
length(a::Array) = arraylen(a)
113-
elsize(a::Array{T}) where {T} = isbits(T) ? sizeof(T) : sizeof(Ptr)
141+
elsize(a::Array{T}) where {T} = isbits(T) ? sizeof(T) : (isbitsunion(T) ? bitsunionsize(T) : sizeof(Ptr))
114142
sizeof(a::Array) = Core.sizeof(a)
115143

116144
function isassigned(a::Array, i::Int...)
@@ -187,7 +215,7 @@ original.
187215
copy(a::T) where {T<:Array} = ccall(:jl_array_copy, Ref{T}, (Any,), a)
188216

189217
function reinterpret(::Type{T}, a::Array{S,1}) where T where S
190-
nel = Int(div(length(a)*sizeof(S),sizeof(T)))
218+
nel = Int(div(length(a) * sizeof(S), sizeof(T)))
191219
# TODO: maybe check that remainder is zero?
192220
return reinterpret(T, a, (nel,))
193221
end
@@ -206,7 +234,7 @@ function reinterpret(::Type{T}, a::Array{S}, dims::NTuple{N,Int}) where T where
206234
end
207235
isbits(T) || throwbits(S, T, T)
208236
isbits(S) || throwbits(S, T, S)
209-
nel = div(length(a)*sizeof(S),sizeof(T))
237+
nel = div(length(a) * sizeof(S), sizeof(T))
210238
if prod(dims) != nel
211239
_throw_dmrsa(dims, nel)
212240
end

0 commit comments

Comments
 (0)