@@ -98,8 +98,36 @@ size(a::Array{<:Any,N}) where {N} = (@_inline_meta; ntuple(M -> size(a, M), Val(
98
98
99
99
asize_from (a:: Array , n) = n > ndims (a) ? () : (arraysize (a,n), asize_from (a, n+ 1 )... )
100
100
101
+ """
102
+ Base.isbitsunion(::Type{T})
103
+
104
+ Return whether a type is an "is-bits" Union type, meaning each type included in a Union is `isbits`.
105
+ """
106
+ function isbitsunion end
107
+
108
+ function isbitsunion (U:: Union )
109
+ for u in Base. uniontypes (U)
110
+ isbits (u) || return false
111
+ end
112
+ return true
113
+ end
114
+ isbitsunion (T) = false
115
+
116
+ """
117
+ Base.bitsunionsize(U::Union)
118
+
119
+ For a Union of `isbits` types, return the size of the largest type.
120
+ """
121
+ function bitsunionsize (U:: Union )
122
+ sz = 0
123
+ for u in Base. uniontypes (U)
124
+ sz = max (sz, sizeof (u))
125
+ end
126
+ return sz
127
+ end
128
+
101
129
length (a:: Array ) = arraylen (a)
102
- elsize (a:: Array{T} ) where {T} = isbits (T) ? sizeof (T) : sizeof (Ptr)
130
+ elsize (a:: Array{T} ) where {T} = isbits (T) ? sizeof (T) : ( isbitsunion (T) ? bitsunionsize (T) : sizeof (Ptr) )
103
131
sizeof (a:: Array ) = Core. sizeof (a)
104
132
105
133
function isassigned (a:: Array , i:: Int... )
@@ -109,6 +137,19 @@ function isassigned(a::Array, i::Int...)
109
137
ccall (:jl_array_isassigned , Cint, (Any, UInt), a, ii) == 1
110
138
end
111
139
140
+ """
141
+ Base.selectorbytes(A::Array{T, N}) -> Array{UInt8, N}
142
+
143
+ For an Array with `isbits` Union elements, return the "selector bytes" that indicate the index
144
+ of the type for each array element, i.e. the type of `A[1]` is `Base.uniontypes(eltype(A))[Base.selectorbytes(A)[1] + 1]`.
145
+ **NOTE**: The actual array selector bytes are returned, meaning if individual elements are modified, the original array will reflect those changes.
146
+ Setting selector bytes to invalid or out-of-bounds type indexes may corrupt the original array.
147
+ """
148
+ function selectorbytes (a:: Array{T, N} ) where {T, N}
149
+ isbitsunion (T) || return UInt8[]
150
+ return unsafe_wrap (Array{UInt8, N}, convert (Ptr{UInt8}, pointer (a)) + length (a) * elsize (a), size (a))
151
+ end
152
+
112
153
# # copy ##
113
154
114
155
function unsafe_copy! (dest:: Ptr{T} , src:: Ptr{T} , n) where T
@@ -143,7 +184,7 @@ copy!(dest::Array{T}, src::Array{T}) where {T} = copy!(dest, 1, src, 1, length(s
143
184
copy (a:: T ) where {T<: Array } = ccall (:jl_array_copy , Ref{T}, (Any,), a)
144
185
145
186
function reinterpret (:: Type{T} , a:: Array{S,1} ) where T where S
146
- nel = Int (div (length (a)* sizeof (S),sizeof (T)))
187
+ nel = Int (div (length (a) * sizeof (S), sizeof (T)))
147
188
# TODO : maybe check that remainder is zero?
148
189
return reinterpret (T, a, (nel,))
149
190
end
@@ -162,7 +203,7 @@ function reinterpret(::Type{T}, a::Array{S}, dims::NTuple{N,Int}) where T where
162
203
end
163
204
isbits (T) || throwbits (S, T, T)
164
205
isbits (S) || throwbits (S, T, S)
165
- nel = div (length (a)* sizeof (S),sizeof (T))
206
+ nel = div (length (a) * sizeof (S), sizeof (T))
166
207
if prod (dims) != nel
167
208
_throw_dmrsa (dims, nel)
168
209
end
0 commit comments