Skip to content

Commit bf78898

Browse files
committed
Inline support for isbits union array element types
1 parent 442b02d commit bf78898

File tree

9 files changed

+302
-108
lines changed

9 files changed

+302
-108
lines changed

base/array.jl

+31-3
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...)
@@ -154,7 +182,7 @@ copy!(dest::Array{T}, src::Array{T}) where {T} = copy!(dest, 1, src, 1, length(s
154182
copy(a::T) where {T<:Array} = ccall(:jl_array_copy, Ref{T}, (Any,), a)
155183

156184
function reinterpret(::Type{T}, a::Array{S,1}) where T where S
157-
nel = Int(div(length(a)*sizeof(S),sizeof(T)))
185+
nel = Int(div(length(a) * sizeof(S), sizeof(T)))
158186
# TODO: maybe check that remainder is zero?
159187
return reinterpret(T, a, (nel,))
160188
end
@@ -173,7 +201,7 @@ function reinterpret(::Type{T}, a::Array{S}, dims::NTuple{N,Int}) where T where
173201
end
174202
isbits(T) || throwbits(S, T, T)
175203
isbits(S) || throwbits(S, T, S)
176-
nel = div(length(a)*sizeof(S),sizeof(T))
204+
nel = div(length(a) * sizeof(S), sizeof(T))
177205
if prod(dims) != nel
178206
_throw_dmrsa(dims, nel)
179207
end

0 commit comments

Comments
 (0)