From 58bdac3aa431eb67b8809bdad8f56c32c115de06 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Mon, 29 Feb 2016 19:58:20 +0100 Subject: [PATCH] Implement checked operations on Bool Bool behaves almost like unsigned integers, but with special cases for checked_add() and checked_sub() which require adding methods and testing separately. --- base/checked.jl | 6 +++++- test/checked.jl | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/base/checked.jl b/base/checked.jl index a5fef27089e44..217f800e06b84 100644 --- a/base/checked.jl +++ b/base/checked.jl @@ -38,7 +38,7 @@ checked_mod{T<:Integer}(x::T, y::T) = no_op_err("checked_mod", T) checked_cld{T<:Integer}(x::T, y::T) = no_op_err("checked_cld", T) typealias SignedInt Union{Int8,Int16,Int32,Int64,Int128} -typealias UnsignedInt Union{UInt8,UInt16,UInt32,UInt64,UInt128} +typealias UnsignedInt Union{UInt8,UInt16,UInt32,UInt64,UInt128,Bool} # LLVM has several code generation bugs for checked integer arithmetic (see e.g. # #4905). We thus distinguish between operations that can be implemented via @@ -166,6 +166,8 @@ function checked_add{T<:BrokenUnsignedInt}(x::T, y::T) x + y end end +checked_add(x::Bool, y::Bool) = x + y +checked_add(x::Bool) = +x # Handle multiple arguments checked_add(x) = x @@ -212,6 +214,8 @@ function checked_sub{T<:BrokenUnsignedInt}(x::T, y::T) x - y end end +checked_sub(x::Bool, y::Bool) = x - y +checked_sub(x::Bool) = -x """ Base.checked_mul(x, y) diff --git a/test/checked.jl b/test/checked.jl index f685c5c724376..9d8cfa87d1c85 100644 --- a/test/checked.jl +++ b/test/checked.jl @@ -196,6 +196,50 @@ for T in (UInt8, UInt16, UInt32, UInt64, UInt128) @test_throws DivideError checked_cld(typemax(T), T(0)) end +# Boolean +@test checked_add(false) === 0 +@test checked_add(true) === 1 +@test checked_sub(false) === 0 +@test checked_sub(true) === -1 +@test checked_neg(false) === 0 +@test checked_neg(true) === -1 +@test checked_abs(true) === true +@test checked_abs(false) === false +@test checked_mul(false) === false +@test checked_mul(true) === true + +@test checked_add(true, true) === 2 +@test checked_add(true, false) === 1 +@test checked_add(false, false) === 0 +@test checked_add(false, true) === 1 + +@test checked_sub(true, true) === 0 +@test checked_sub(true, false) === 1 +@test checked_sub(false, false) === 0 +@test checked_sub(false, true) === -1 + +@test checked_mul(true, false) === false +@test checked_mul(false, false) === false +@test checked_mul(true, true) === true +@test checked_mul(false, true) === false + +@test checked_div(true, true) === true +@test checked_div(false, true) === false +@test_throws DivideError checked_div(true, false) +@test checked_rem(true, true) === false +@test checked_rem(false, true) === false +@test_throws DivideError checked_rem(true, false) +@test checked_fld(true, true) === true +@test checked_fld(false, true) === false +@test_throws DivideError checked_fld(true, false) +@test checked_mod(true, true) === false +@test checked_mod(false, true) === false +@test_throws DivideError checked_mod(true, false) +@test checked_cld(true, true) === true +@test checked_cld(false, true) === false +@test_throws DivideError checked_cld(true, false) + +# BigInt @test checked_abs(BigInt(-1)) == BigInt(1) @test checked_abs(BigInt(1)) == BigInt(1) @test checked_neg(BigInt(-1)) == BigInt(1)