Skip to content

Commit 85223f9

Browse files
committed
Support Arrays of Union isbits types
1 parent 31c2469 commit 85223f9

File tree

12 files changed

+596
-157
lines changed

12 files changed

+596
-157
lines changed

base/array.jl

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

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

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

119147
function isassigned(a::Array, i::Int...)
@@ -123,6 +151,19 @@ function isassigned(a::Array, i::Int...)
123151
ccall(:jl_array_isassigned, Cint, (Any, UInt), a, ii) == 1
124152
end
125153

154+
"""
155+
Base.selectorbytes(A::Array{T, N}) -> Array{UInt8, N}
156+
157+
For an Array with `isbits` Union elements, return the "selector bytes" that indicate the index
158+
of the type for each array element, i.e. the type of `A[1]` is `Base.uniontypes(eltype(A))[Base.selectorbytes(A)[1] + 1]`.
159+
**NOTE**: The actual array selector bytes are returned, meaning if individual elements are modified, the original array will reflect those changes.
160+
Setting selector bytes to invalid or out-of-bounds type indexes may corrupt the original array.
161+
"""
162+
function selectorbytes(a::Array{T, N}) where {T, N}
163+
isbitsunion(T) || return UInt8[]
164+
return unsafe_wrap(Array{UInt8, N}, convert(Ptr{UInt8}, pointer(a)) + length(a) * elsize(a), size(a))
165+
end
166+
126167
## copy ##
127168

128169
function unsafe_copy!(dest::Ptr{T}, src::Ptr{T}, n) where T
@@ -157,7 +198,7 @@ copy!(dest::Array{T}, src::Array{T}) where {T} = copy!(dest, 1, src, 1, length(s
157198
copy(a::T) where {T<:Array} = ccall(:jl_array_copy, Ref{T}, (Any,), a)
158199

159200
function reinterpret(::Type{T}, a::Array{S,1}) where T where S
160-
nel = Int(div(length(a)*sizeof(S),sizeof(T)))
201+
nel = Int(div(length(a) * sizeof(S), sizeof(T)))
161202
# TODO: maybe check that remainder is zero?
162203
return reinterpret(T, a, (nel,))
163204
end
@@ -176,7 +217,7 @@ function reinterpret(::Type{T}, a::Array{S}, dims::NTuple{N,Int}) where T where
176217
end
177218
isbits(T) || throwbits(S, T, T)
178219
isbits(S) || throwbits(S, T, S)
179-
nel = div(length(a)*sizeof(S),sizeof(T))
220+
nel = div(length(a) * sizeof(S), sizeof(T))
180221
if prod(dims) != nel
181222
_throw_dmrsa(dims, nel)
182223
end

src/.vscode/launch.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "(lldb) Launch",
6+
"type": "cppdbg",
7+
"request": "launch",
8+
"program": "/Users/jacobquinn/julia/usr/bin/julia-debug",
9+
"args": ["/Users/jacobquinn/arnoldi.jl"],
10+
"stopAtEntry": false,
11+
"cwd": "${workspaceRoot}",
12+
"environment": [],
13+
"externalConsole": true,
14+
"MIMode": "lldb"
15+
}
16+
]
17+
}

src/.vscode/settings.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"files.associations": {
3+
"array.c": "cpp",
4+
"gc.c": "cpp",
5+
"jlapi.c": "cpp",
6+
"jltypes.c": "cpp",
7+
"gf.c": "cpp"
8+
}
9+
}

0 commit comments

Comments
 (0)