Skip to content
This repository has been archived by the owner on May 4, 2019. It is now read-only.

Commit

Permalink
Support Nullable{Union{}} with operators
Browse files Browse the repository at this point in the history
Nullable{Union{}} is always null so we can return null immediately
if one of the arguments is of that type. For unary operators, return
Nullabl(). For binary operators, return Nullable{S}() with S the element
type of the other argument, which carries more information.
  • Loading branch information
nalimilan committed Jul 3, 2016
1 parent d16fa1f commit 92e3b27
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ for op in (:+, :-, :!, :~, :abs, :abs2, :sqrt, :cbrt)
Nullable{R}($op(x.value))
end
end
$op(x::Nullable{Union{}}) = Nullable()
end
end

Expand Down Expand Up @@ -122,5 +123,8 @@ for op in (:+, :-, :*, :/, :%, :÷, :&, :|, :^, :<<, :>>, :(>>>),
Nullable{R}($op(x.value, y.value))
end
end
$op(x::Nullable{Union{}}, y::Nullable{Union{}}) = Nullable()
$op{S}(x::Nullable{Union{}}, y::Nullable{S}) = Nullable{S}()
$op{S}(x::Nullable{S}, y::Nullable{Union{}}) = Nullable{S}()
end
end
29 changes: 28 additions & 1 deletion test/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ module TestOperators
v1 = one(T)
v2 = T <: Union{BigInt, BigFloat} ? T(rand(Int128)) : rand(T)

v2 > 5 && (v2 = T(5)) # Work around issue #16989
abs(v2) > 5 && (v2 = T(5)) # Work around JuliaLang/julia#16989

# safe unary operators
for op in (+, -, ~, abs, abs2, cbrt)
Expand All @@ -99,6 +99,9 @@ module TestOperators
@test isa(x, Nullable{R}) && isnull(x)
x = op(Nullable{R}())
@test isa(x, Nullable{R}) && isnull(x)

x = op(Nullable())
@test isa(x, Nullable{Union{}}) && isnull(x)
end

# unsafe unary operators
Expand All @@ -120,6 +123,9 @@ module TestOperators
x = sqrt(Nullable{R}())
@test isa(x, Nullable{R}) && isnull(x)

x = sqrt(Nullable())
@test isa(x, Nullable{Union{}}) && isnull(x)

for u in (u0, u1, u2), v in (v0, v1, v2)
# safe binary operators
for op in (+, -, *, /, &, |, >>, <<, >>>,
Expand All @@ -143,6 +149,13 @@ module TestOperators
@test isa(x, Nullable{R}) && isnull(x)
x = op(Nullable(u, true), Nullable(v))
@test isa(x, Nullable{R}) && isnull(x)

x = op(Nullable(u, true), Nullable())
@test isa(x, Nullable{S}) && isnull(x)
x = op(Nullable(), Nullable(u, true))
@test isa(x, Nullable{S}) && isnull(x)
x = op(Nullable(), Nullable())
@test isa(x, Nullable{Union{}}) && isnull(x)
end

# unsafe binary operators
Expand All @@ -159,6 +172,13 @@ module TestOperators
x = Nullable(u, true)^Nullable(-abs(v), false)
@test isnull(x) && eltype(x) === R

x = Nullable(u, true)^Nullable()
@test isa(x, Nullable{S}) && isnull(x)
x = Nullable()^Nullable(u, true)
@test isa(x, Nullable{S}) && isnull(x)
x = Nullable()^Nullable()
@test isa(x, Nullable{Union{}}) && isnull(x)

# ÷ and %
for op in (÷, %)
if S <: Integer && T <: Integer && v == 0
Expand All @@ -173,6 +193,13 @@ module TestOperators
@test isnull(x) && eltype(x) === R
x = op(Nullable(u, true), Nullable(v, false))
@test isnull(x) && eltype(x) === R

x = op(Nullable(u, true), Nullable())
@test isa(x, Nullable{S}) && isnull(x)
x = op(Nullable(), Nullable(u, true))
@test isa(x, Nullable{S}) && isnull(x)
x = op(Nullable(), Nullable())
@test isa(x, Nullable{Union{}}) && isnull(x)
end
end
end
Expand Down

0 comments on commit 92e3b27

Please sign in to comment.