Skip to content

Commit

Permalink
Add tests for isbits union optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
quinnj committed Aug 15, 2017
1 parent 90b95c2 commit f9766a6
Showing 1 changed file with 220 additions and 0 deletions.
220 changes: 220 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5180,3 +5180,223 @@ let idx = (7,5,9)
(v,) = (idx...,)
@test v == 7
end

module UnionOptimizations

using Base.Test

const boxedunions = [Union{}, Union{String, Void}]
const unboxedunions = [Union{Int8, Void}, Union{Int8, Float16, Void},
# Union{Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128}, # issue #22688
Union{Char, Date, Int}]

initvalue(::Type{Void}) = nothing
initvalue(::Type{Char}) = '\0'
initvalue(::Type{Date}) = Date(0, 12, 31)
initvalue(::Type{T}) where {T <: Number} = T(0)

initvalue2(::Type{Void}) = nothing
initvalue2(::Type{Char}) = Char(0x01)
initvalue2(::Type{Date}) = Date(1)
initvalue2(::Type{T}) where {T <: Number} = T(1)

U = unboxedunions[1]

mutable struct UnionField
u::U
end

x = UnionField(initvalue(Base.uniontypes(U)[1]))
@test x.u === initvalue(Base.uniontypes(U)[1])
x.u = initvalue2(Base.uniontypes(U)[1])
@test x.u === initvalue2(Base.uniontypes(U)[1])
x.u = initvalue(Base.uniontypes(U)[2])
@test x.u === initvalue(Base.uniontypes(U)[2])

for U in boxedunions
for N in (1, 2, 3, 4)
A = Array{U}(ntuple(x->0, N)...)
@test isempty(A)
@test Core.sizeof(A) == 0

A = Array{U}(ntuple(x->10, N)...)
@test length(A) == 10^N
@test Core.sizeof(A) == sizeof(Int) * (10^N)
@test !isassigned(A, 1)
end
end

# unsafe_wrap
A4 = [1, 2, 3]
@test_throws ArgumentError unsafe_wrap(Array, convert(Ptr{Union{Int, Void}}, pointer(A4)), 3)
A5 = [1 2 3; 4 5 6]
@test_throws ArgumentError unsafe_wrap(Array, convert(Ptr{Union{Int, Void}}, pointer(A5)), 6)

for U in unboxedunions
for N in (1, 2, 3, 4)
A = Array{U}(ntuple(x->0, N)...)
@test isempty(A)
@test Core.sizeof(A) == 0

len = ntuple(x->10, N)
mxsz = maximum(sizeof, Base.uniontypes(U))
A = Array{U}(len)
@test length(A) == prod(len)
@test Core.sizeof(A) == prod(len) * mxsz
@test isassigned(A, 1)
@test isassigned(A, length(A))

# arrayref / arrayset
F = Base.uniontypes(U)[1]
@test A[1] === initvalue(F)
A[1] = initvalue2(F)
@test A[1] === initvalue2(F)

F2 = Base.uniontypes(U)[2]
A[2] = initvalue(F2)
@test A[2] === initvalue(F2)

for (i, U2) in enumerate(Base.uniontypes(U))
A[i] = initvalue2(U2)
@test A[i] === initvalue2(U2)
end

# serialize / deserialize
io = IOBuffer()
serialize(io, A)
seekstart(io)
A2 = deserialize(io)
@test A == A2

# reshape
A3 = reshape(A, (div(prod(len), 2), 2))
@test Core.sizeof(A) == prod(len) * mxsz
@test isassigned(A, 1)
@test A[1] === initvalue2(F)

# copy
A4 = copy(A)
@test A == A4

if N == 1
## Dequeue functions
# pop!
F2 = Base.uniontypes(U)[2]
len = len[1]
A = U[initvalue2(F2) for i = 1:len]
for i = 1:len
@test A[end] === initvalue2(F2)
v = pop!(A)
@test v === initvalue2(F2)
end
@test isempty(A)

# shift!
A = U[initvalue2(F2) for i = 1:len]
for i = 1:len
@test A[1] === initvalue2(F2)
shift!(A)
end
@test isempty(A)

# empty!
A = U[initvalue2(F2) for i = 1:len]
empty!(A)
@test isempty(A)

# resize!
A = U[initvalue2(F2) for i = 1:len]
resize!(A, 1)
@test length(A) === 1
@test A[1] === initvalue2(F2)
resize!(A, len)
@test length(A) === len
@test A[1] === initvalue2(F2)
@test typeof(A[end]) === F

# deleteat!
F = Base.uniontypes(U)[2]
A = U[rand(F(1):F(len)) for i = 1:len]
deleteat!(A, map(Int, sort!(unique(A[1:4]))))
A = U[initvalue2(F2) for i = 1:len]
deleteat!(A, 1:2)
@test length(A) == len - 2
@test all(A .== initvalue2(F2))
deleteat!(A, 1:2)
@test length(A) == len - 4
@test all(A .== initvalue2(F2))
A = U[initvalue2(F2) for i = 1:len]
deleteat!(A, length(A)-1:length(A))
@test length(A) == len - 2
@test all(A .== initvalue2(F2))
deleteat!(A, length(A)-1:length(A))
@test length(A) == len - 4
@test all(A .== initvalue2(F2))
A = U[initvalue2(F2) for i = 1:len]
deleteat!(A, 2:3)
@test length(A) == len - 2
@test all(A .== initvalue2(F2))
A = U[initvalue2(F2) for i = 1:len]
deleteat!(A, length(A)-2:length(A)-1)
@test length(A) == len - 2
@test all(A .== initvalue2(F2))

# unshift!
A = U[initvalue2(F2) for i = 1:len]
for i = 1:5
unshift!(A, initvalue2(F))
unshift!(A, initvalue(F2))
@test A[1] === initvalue(F2)
@test A[2] === initvalue2(F)
end

# push! / append! / prepend!
A = U[initvalue2(F2) for i = 1:len]
push!(A, initvalue2(F))
@test A[end] === initvalue2(F)
push!(A, initvalue2(F2))
@test A[end] === initvalue2(F2)
append!(A, [initvalue(F), initvalue2(F)])
@test A[end] === initvalue2(F)
@test A[end-1] === initvalue(F)
prepend!(A, [initvalue(F), initvalue2(F)])
@test A[2] === initvalue2(F)
@test A[1] === initvalue(F)

# insert!
A = U[initvalue2(F2) for i = 1:len]
insert!(A, 2, initvalue2(F))
@test A[2] === initvalue2(F)
@test A[1] === initvalue2(F2)
@test A[3] === initvalue2(F2)
@test A[end] === initvalue2(F2)
A = U[initvalue2(F2) for i = 1:len]
insert!(A, 8, initvalue2(F))
@test A[8] === initvalue2(F)
@test A[7] === initvalue2(F2)
@test A[9] === initvalue2(F2)
@test A[end] === initvalue2(F2)

# splice!
A = U[initvalue2(F2) for i = 1:len]
V = splice!(A, 1:2)
@test length(A) == len - 2
@test length(V) == 2
@test V[1] == initvalue2(F2)
@test V[2] == initvalue2(F2)
@test A[1] == initvalue2(F2)
@test A[end] == initvalue2(F2)

A = U[initvalue2(F2) for i = 1:len]
V = splice!(A, 4:5)
@test length(A) == len - 2
@test length(V) == 2
@test V[1] == initvalue2(F2)
@test V[2] == initvalue2(F2)
@test A[1] == initvalue2(F2)
@test A[end] == initvalue2(F2)
end
end
end

end # module UnionOptimizations

0 comments on commit f9766a6

Please sign in to comment.