|
| 1 | +module CheckedArithmeticCore |
| 2 | + |
| 3 | +export safearg_type, safearg, safeconvert, accumulatortype, acc |
| 4 | + |
| 5 | +""" |
| 6 | + newT = CheckedArithmeticCore.safearg_type(::Type{T}) |
| 7 | +
|
| 8 | +Return a "reasonably safe" type `newT` for computation with numbers of type `T`. |
| 9 | +For example, for `UInt8` one might return `UInt128`, because one is much less likely |
| 10 | +to overflow with `UInt128`. |
| 11 | +""" |
| 12 | +function safearg_type end |
| 13 | + |
| 14 | + |
| 15 | +""" |
| 16 | + xsafe = CheckedArithmeticCore.safearg(x) |
| 17 | +
|
| 18 | +Return a variant `xsafe` of `x` that is "reasonably safe" for non-overflowing computation. |
| 19 | +For numbers, this uses [`CheckedArithmetic.safearg_type`](@ref). |
| 20 | +For containers and other non-number types, specialize `safearg` directly. |
| 21 | +""" |
| 22 | +safearg(x::T) where T = convert(safearg_type(T), x) |
| 23 | + |
| 24 | + |
| 25 | +""" |
| 26 | + xc = safeconvert(T, x) |
| 27 | +
|
| 28 | +Convert `x` to type `T`, "safely." This is designed for comparison to results computed by |
| 29 | +[`CheckedArithmetic.@check`](@ref), i.e., for arguments converted by |
| 30 | +[`CheckedArithmeticCore.safearg`](@ref). |
| 31 | +""" |
| 32 | +safeconvert(::Type{T}, x) where T = convert(T, x) |
| 33 | + |
| 34 | + |
| 35 | +""" |
| 36 | + Tnew = accumulatortype(op, T1, T2, ...) |
| 37 | + Tnew = accumulatortype(T1, T2, ...) |
| 38 | +
|
| 39 | +Return a type `Tnew` suitable for accumulation (reduction) of elements of type `T` under |
| 40 | +operation `op`. |
| 41 | +
|
| 42 | +# Examples |
| 43 | +
|
| 44 | +```jldoctest; setup = :(using CheckedArithmetic) |
| 45 | +julia> accumulatortype(+, UInt8) |
| 46 | +$UInt |
| 47 | +``` |
| 48 | +""" |
| 49 | +Base.@pure accumulatortype(op::Function, T1::Type, T2::Type, T3::Type...) = |
| 50 | + accumulatortype(op, promote_type(T1, T2, T3...)) |
| 51 | +Base.@pure accumulatortype(T1::Type, T2::Type, T3::Type...) = |
| 52 | + accumulatortype(*, T1, T2, T3...) |
| 53 | +accumulatortype(::Type{T}) where T = accumulatortype(*, T) |
| 54 | + |
| 55 | + |
| 56 | +""" |
| 57 | + xacc = acc(x) |
| 58 | +
|
| 59 | +Convert `x` to type [`accumulatortype`](@ref)`(typeof(x))`. |
| 60 | +""" |
| 61 | +acc(x) = convert(accumulatortype(typeof(x)), x) |
| 62 | +acc(f::F, x) where F<:Function = convert(accumulatortype(f, typeof(x)), x) |
| 63 | + |
| 64 | + |
| 65 | +end # module |
0 commit comments