diff --git a/src/binary_ops.jl b/src/binary_ops.jl index 4c84c87..7677b7c 100644 --- a/src/binary_ops.jl +++ b/src/binary_ops.jl @@ -28,20 +28,22 @@ end for OP in (:(<), :(<=), :(>=), :(>), :(!=), :(==), :isless, :isequal) + for SI in (SafeSigned, SafeUnsigned, SafeInteger) + @eval begin + @inline function $OP(x::T, y::T) where T<: $SI + ix = baseint(x) + iy = baseint(y) + result = $OP(ix, iy) + return safeint(result) + end + + @inline function $OP(x::T1, y::T2) where {T1<:$SI, T2<: $SI} + xx, yy = promote(x, y) + return $OP(xx, yy) + end + end + end @eval begin - - @inline function $OP(x::T, y::T) where T<:SafeInteger - ix = baseint(x) - iy = baseint(y) - result = $OP(ix, iy) - return safeint(result) - end - - @inline function $OP(x::T1, y::T2) where {T1<:SafeInteger, T2<:SafeInteger} - xx, yy = promote(x, y) - return $OP(xx, yy) - end - @inline function $OP(x::T1, y::T2) where {T1<:SafeSigned, T2<:Signed} xx, yy = promote(x, y) return $OP(xx, yy) @@ -75,7 +77,11 @@ for OP in (:(<), :(<=), :(>=), :(>), :(!=), :(==), :isless, :isequal) xx, yy = promote(x, y) return $OP(xx, yy) end - end + @inline function $OP(x::T1, y::T2) where {T1<:SafeInteger, T2<:Integer} + xx, yy = promote(x, y) + return $OP(xx, yy) + end + end end diff --git a/src/int_ops.jl b/src/int_ops.jl index 8a2cb0e..2fc987f 100644 --- a/src/int_ops.jl +++ b/src/int_ops.jl @@ -55,6 +55,10 @@ end return safeint(baseint( signbit(y) ? -abs(x) : abs(x) )) end @inline copysign(x::T, y::T) where T<:SafeUnsigned = x +@inline copysign(x::SafeSigned, y::Float16) = safeint( copysign(baseint(x), y) ) +@inline copysign(x::SafeSigned, y::Float32) = safeint( copysign(baseint(x), y) ) +@inline copysign(x::SafeSigned, y::Float64) = safeint( copysign(baseint(x), y) ) +@inline copysign(x::SafeSigned, y::Signed) = safeint( copysign(baseint(x), y) ) @inline function flipsign(x::T, y::T) where T<:SafeSigned return safeint(baseint( signbit(y) ? -(x) : x )) diff --git a/src/promote.jl b/src/promote.jl index 2477cf6..6b90f1d 100644 --- a/src/promote.jl +++ b/src/promote.jl @@ -5,10 +5,14 @@ promote_rule(::Type{S}, ::Type{T}) where S<:SafeSigned where T<:SafeUnsigned = promote_rule(::Type{S}, ::Type{T}) where S<:SafeUnsigned where T<:SafeUnsigned = safeint(promote_type(baseint(S), baseint(T))) -promote_rule(::Type{S}, ::Type{T}) where S<:SafeSigned where T<:Signed = S -promote_rule(::Type{S}, ::Type{T}) where S<:SafeSigned where T<:Unsigned = S -promote_rule(::Type{S}, ::Type{T}) where S<:SafeUnsigned where T<:Signed = S -promote_rule(::Type{S}, ::Type{T}) where S<:SafeUnsigned where T<:Unsigned = S +promote_rule(::Type{S}, ::Type{T}) where S<:SafeSigned where T<:Signed = + T <: SafeInteger ? Base.Bottom : S +promote_rule(::Type{S}, ::Type{T}) where S<:SafeSigned where T<:Unsigned = + T <: SafeInteger ? Base.Bottom : S +promote_rule(::Type{S}, ::Type{T}) where S<:SafeUnsigned where T<:Signed = + T <: SafeInteger ? Base.Bottom : S +promote_rule(::Type{S}, ::Type{T}) where S<:SafeUnsigned where T<:Unsigned = + T <: SafeInteger ? Base.Bottom : S promote_rule(::Type{S}, ::Type{T}) where S<:SafeSigned where T<:Base.IEEEFloat = T promote_rule(::Type{S}, ::Type{T}) where S<:SafeUnsigned where T<:Base.IEEEFloat = T diff --git a/src/type.jl b/src/type.jl index 1bf350f..3a00056 100644 --- a/src/type.jl +++ b/src/type.jl @@ -1,6 +1,6 @@ -abstract type SafeInteger <: Integer end -abstract type SafeUnsigned <: SafeInteger end -abstract type SafeSigned <: SafeInteger end +abstract type SafeUnsigned <: Unsigned end +abstract type SafeSigned <: Signed end +const SafeInteger = Union{SafeUnsigned, SafeSigned} primitive type SafeInt8 <: SafeSigned 8 end primitive type SafeInt16 <: SafeSigned 16 end