Skip to content

Commit d7f9183

Browse files
authored
Move the API definitions to a new package, CheckedArithmeticCore (#8)
This also add support for `div` and `%` in `@checked`. This switches the CI from Travis to GitHub Actions, and adds Julia v1 and 32-bit x86 to the test target.
1 parent 50243f0 commit d7f9183

File tree

10 files changed

+242
-96
lines changed

10 files changed

+242
-96
lines changed

.github/workflows/UnitTest.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Unit test
2+
3+
on:
4+
push:
5+
pull_request:
6+
defaults:
7+
run:
8+
shell: bash
9+
jobs:
10+
test:
11+
runs-on: ${{ matrix.os }}
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
julia-version: ['1.0', '1', 'nightly']
16+
os: [ubuntu-latest, windows-latest, macOS-latest]
17+
julia-arch: [x64]
18+
include:
19+
- os: ubuntu-latest
20+
julia-version: '1'
21+
julia-arch: x86
22+
steps:
23+
- uses: actions/checkout@v2
24+
25+
- name: "Set up Julia"
26+
uses: julia-actions/setup-julia@v1
27+
with:
28+
version: ${{ matrix.julia-version }}
29+
arch: ${{ matrix.julia-arch }}
30+
- run: julia --project -e 'using Pkg; Pkg.develop([PackageSpec(path="CheckedArithmeticCore")])'
31+
32+
- name: Cache artifacts
33+
uses: actions/cache@v1
34+
env:
35+
cache-name: cache-artifacts
36+
with:
37+
path: ~/.julia/artifacts
38+
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
39+
restore-keys: |
40+
${{ runner.os }}-test-${{ env.cache-name }}-
41+
${{ runner.os }}-test-
42+
${{ runner.os }}-
43+
44+
- name: "Unit Test"
45+
uses: julia-actions/julia-runtest@master
46+
- uses: julia-actions/julia-processcoverage@v1
47+
- uses: codecov/codecov-action@v1
48+
with:
49+
file: lcov.info

.travis.yml

Lines changed: 0 additions & 15 deletions
This file was deleted.

CheckedArithmeticCore/LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2019 Tim Holy <[email protected]>
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

CheckedArithmeticCore/Project.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name = "CheckedArithmeticCore"
2+
uuid = "740b204e-26e5-40b1-866a-9c367e60c4b6"
3+
authors = ["Tim Holy <[email protected]>"]
4+
version = "0.1.0"
5+
6+
[compat]
7+
julia = "1"
8+
9+
[extras]
10+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
11+
12+
[targets]
13+
test = ["Test"]

CheckedArithmeticCore/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# CheckedArithmeticCore
2+
3+
CheckedArithmeticCore is a component of
4+
[CheckedArithmetic](https://github.com/JuliaMath/CheckedArithmetic.jl).
5+
6+
This package provides a set of low-level APIs for the packages which provide
7+
numeric types and their arithmetic.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using CheckedArithmeticCore
2+
using Test
3+
4+
struct MyType end
5+
struct MySafeType end
6+
Base.convert(::Type{MySafeType}, ::MyType) = MySafeType()
7+
CheckedArithmeticCore.safearg_type(::Type{MyType}) = MySafeType
8+
CheckedArithmeticCore.accumulatortype(::typeof(+), ::Type{MyType}) = MyType
9+
CheckedArithmeticCore.accumulatortype(::typeof(+), ::Type{MySafeType}) = MySafeType
10+
CheckedArithmeticCore.accumulatortype(::typeof(*), ::Type{MyType}) = MySafeType
11+
CheckedArithmeticCore.accumulatortype(::typeof(*), ::Type{MySafeType}) = MySafeType
12+
Base.promote_rule(::Type{MyType}, ::Type{MySafeType}) = MySafeType
13+
14+
# fallback
15+
@test safearg(MyType()) === MySafeType()
16+
17+
# fallback
18+
@test safeconvert(UInt16, 0x12) === 0x0012
19+
20+
# fallback
21+
@test accumulatortype(MyType) === MySafeType
22+
@test accumulatortype(MyType, MyType) === MySafeType
23+
@test accumulatortype(+, MyType) === MyType
24+
@test accumulatortype(*, MyType) === MySafeType
25+
@test accumulatortype(+, MyType, MySafeType) === MySafeType
26+
@test accumulatortype(*, MySafeType, MyType) === MySafeType
27+
28+
# acc
29+
@test acc(MyType()) === MySafeType()
30+
@test acc(+, MyType()) === MyType()

Project.toml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
name = "CheckedArithmetic"
22
uuid = "2c4a1fb8-30c1-4c71-8b84-dff8d59868ee"
33
authors = ["Tim Holy <[email protected]>"]
4-
version = "0.1.0"
4+
version = "0.2.0"
55

66
[deps]
7+
CheckedArithmeticCore = "740b204e-26e5-40b1-866a-9c367e60c4b6"
78
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
89
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
910
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
10-
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1111

1212
[compat]
13+
CheckedArithmeticCore = "0.1"
1314
julia = "1"
15+
16+
[extras]
17+
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
18+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
19+
20+
[targets]
21+
test = ["Pkg", "Test"]

0 commit comments

Comments
 (0)