Skip to content

Commit fcbfc5f

Browse files
committed
Add static comparison operators + "test/static.jl" file
1 parent 1d8fe52 commit fcbfc5f

File tree

3 files changed

+215
-120
lines changed

3 files changed

+215
-120
lines changed

src/static.jl

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,19 @@ function Base.UnitRange(start::StaticInt, stop::StaticInt)
147147
return UnitRange(Int(start), Int(stop))
148148
end
149149

150-
struct True <: Integer end
151-
struct False <: Integer end
152-
153150
"""
154-
StaticBool(bool::Bool) -> StaticBool{bool}()
151+
StaticBool(x::Bool) -> True/False
155152
153+
A statically typed `Bool`.
156154
"""
157-
const StaticBool = Union{True,False}
155+
abstract type StaticBool <: Integer end
156+
158157
StaticBool(x::StaticBool) = x
158+
159+
struct True <: StaticBool end
160+
161+
struct False <: StaticBool end
162+
159163
function StaticBool(x::Bool)
160164
if x
161165
return True()
@@ -290,6 +294,74 @@ end
290294
Expr(:block, Expr(:meta, :inline), t)
291295
end
292296

297+
"""
298+
eq(x::StaticInt, y::StaticInt) -> StaticBool
299+
300+
Equivalent to `==` or `isequal` but returns a `StaticBool`.
301+
"""
302+
eq(::StaticInt{X}, ::StaticInt{X}) where {X} = True()
303+
eq(::StaticInt{X}, ::StaticInt{Y}) where {X,Y} = False()
304+
305+
"""
306+
ne(x::StaticInt, y::StaticInt) -> StaticBool
307+
308+
Equivalent to `!=` but returns a `StaticBool`.
309+
"""
310+
ne(::StaticInt{X}, ::StaticInt{X}) where {X} = False()
311+
ne(::StaticInt{X}, ::StaticInt{Y}) where {X,Y} = True()
312+
313+
"""
314+
gt(x::StaticInt, y::StaticInt) -> StaticBool
315+
316+
Equivalent to `>` but returns a `StaticBool`.
317+
"""
318+
function gt(::StaticInt{X}, ::StaticInt{Y}) where {X,Y}
319+
if X > Y
320+
return True()
321+
else
322+
return False()
323+
end
324+
end
325+
326+
"""
327+
ge(x::StaticInt, y::StaticInt) -> StaticBool
328+
329+
Equivalent to `>=` but returns a `StaticBool`.
330+
"""
331+
function ge(::StaticInt{X}, ::StaticInt{Y}) where {X,Y}
332+
if X >= Y
333+
return True()
334+
else
335+
return False()
336+
end
337+
end
338+
339+
"""
340+
le(x::StaticInt, y::StaticInt) -> StaticBool
341+
342+
Equivalent to `<=` but returns a `StaticBool`.
343+
"""
344+
function le(::StaticInt{X}, ::StaticInt{Y}) where {X,Y}
345+
if X <= Y
346+
return True()
347+
else
348+
return False()
349+
end
350+
end
351+
352+
"""
353+
lt(x::StaticInt, y::StaticInt) -> StaticBool
354+
355+
Equivalent to `<` but returns a `StaticBool`.
356+
"""
357+
function lt(::StaticInt{X}, ::StaticInt{Y}) where {X,Y}
358+
if X < Y
359+
return True()
360+
else
361+
return False()
362+
end
363+
end
364+
293365
"""
294366
static(x)
295367

test/runtests.jl

Lines changed: 1 addition & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -611,120 +611,7 @@ end
611611
@test Base.axes1(Base.Slice(StaticInt(2):4)) === Base.IdentityUnitRange(StaticInt(2):4)
612612
end
613613

614-
@testset "StaticInt" begin
615-
@test iszero(StaticInt(0))
616-
@test !iszero(StaticInt(1))
617-
@test !isone(StaticInt(0))
618-
@test isone(StaticInt(1))
619-
@test @inferred(one(StaticInt(1))) === StaticInt(1)
620-
@test @inferred(zero(StaticInt(1))) === StaticInt(0)
621-
@test @inferred(one(StaticInt)) === StaticInt(1)
622-
@test @inferred(zero(StaticInt)) === StaticInt(0) === StaticInt(StaticInt(Val(0)))
623-
@test eltype(one(StaticInt)) <: Int
624-
625-
x = StaticInt(1)
626-
@test @inferred(Bool(x)) isa Bool
627-
@test @inferred(BigInt(x)) isa BigInt
628-
@test @inferred(Integer(x)) === x
629-
# test for ambiguities and correctness
630-
for i Any[StaticInt(0), StaticInt(1), StaticInt(2), 3]
631-
for j Any[StaticInt(0), StaticInt(1), StaticInt(2), 3]
632-
i === j === 3 && continue
633-
for f [+, -, *, ÷, %, <<, >>, >>>, &, |, , ==, , ]
634-
(iszero(j) && ((f === ÷) || (f === %))) && continue # integer division error
635-
@test convert(Int, @inferred(f(i,j))) == f(convert(Int, i), convert(Int, j))
636-
end
637-
end
638-
i == 3 && break
639-
for f [+, -, *, /, ÷, %, ==, , ]
640-
w = f(convert(Int, i), 1.4)
641-
x = f(1.4, convert(Int, i))
642-
@test convert(typeof(w), @inferred(f(i, 1.4))) === w
643-
@test convert(typeof(x), @inferred(f(1.4, i))) === x # if f is division and i === StaticInt(0), returns `NaN`; hence use of ==== in check.
644-
(((f === ÷) || (f === %)) && (i === StaticInt(0))) && continue
645-
y = f(convert(Int, i), 2 // 7)
646-
z = f(2 // 7, convert(Int, i))
647-
@test convert(typeof(y), @inferred(f(i, 2 // 7))) === y
648-
@test convert(typeof(z), @inferred(f(2 // 7, i))) === z
649-
end
650-
end
651-
652-
@test UnitRange{Int16}(StaticInt(-9), 17) === Int16(-9):Int16(17)
653-
@test UnitRange{Int16}(-7, StaticInt(19)) === Int16(-7):Int16(19)
654-
@test UnitRange(-11, StaticInt(15)) === -11:15
655-
@test UnitRange(StaticInt(-11), 15) === -11:15
656-
@test UnitRange(StaticInt(-11), StaticInt(15)) === -11:15
657-
@test float(StaticInt(8)) === 8.0
658-
end
659-
660-
@testset "StaticBool" begin
661-
t = True()
662-
f = False()
663-
664-
@test @inferred(StaticInt(t)) === StaticInt(1)
665-
@test @inferred(StaticInt(f)) === StaticInt(0)
666-
667-
@test @inferred(~t) === f
668-
@test @inferred(~f) === t
669-
@test @inferred(!t) === f
670-
@test @inferred(!f) === t
671-
@test @inferred(+t) === StaticInt(1)
672-
@test @inferred(+f) === StaticInt(0)
673-
@test @inferred(-t) === StaticInt(-1)
674-
@test @inferred(-f) === StaticInt(0)
675-
676-
@test @inferred(|(true, f))
677-
@test @inferred(|(f, true))
678-
@test @inferred(|(f, f)) === f
679-
@test @inferred(|(f, t)) === t
680-
@test @inferred(|(t, f)) === t
681-
@test @inferred(|(t, t)) === t
682-
683-
@test !@inferred(Base.:(&)(true, f))
684-
@test !@inferred(Base.:(&)(f, true))
685-
@test @inferred(Base.:(&)(f, f)) === f
686-
@test @inferred(Base.:(&)(f, t)) === f
687-
@test @inferred(Base.:(&)(t, f)) === f
688-
@test @inferred(Base.:(&)(t, t)) === t
689-
690-
@test @inferred(<(f, f)) === f
691-
@test @inferred(<(f, t)) === t
692-
@test @inferred(<(t, f)) === f
693-
@test @inferred(<(t, t)) === f
694-
695-
@test @inferred(<=(f, f)) === t
696-
@test @inferred(<=(f, t)) === t
697-
@test @inferred(<=(t, f)) === f
698-
@test @inferred(<=(t, t)) === t
699-
700-
@test @inferred(*(f, t)) === t & f
701-
@test @inferred(-(f, t)) === StaticInt(f) - StaticInt(t)
702-
@test @inferred(+(f, t)) === StaticInt(f) + StaticInt(t)
703-
704-
@test @inferred(^(t, f)) == ^(true, false)
705-
@test @inferred(^(t, t)) == ^(true, true)
706-
707-
@test @inferred(^(2, f)) == 1
708-
@test @inferred(^(2, t)) == 2
709-
710-
@test @inferred(^(BigInt(2), f)) == 1
711-
@test @inferred(^(BigInt(2), t)) == 2
712-
713-
@test div(t, t) === t
714-
@test_throws DivideError div(t, f)
715-
716-
@test rem(t, t) === f
717-
@test_throws DivideError rem(t, f)
718-
@test mod(t, t) === f
719-
720-
@test all((t, t, t))
721-
@test !all((t, f, t))
722-
@test !all((f, f, f))
723-
724-
@test any((t, t, t))
725-
@test any((t, f, t))
726-
@test !any((f, f, f))
727-
end
614+
include("static.jl")
728615

729616
@testset "insert/deleteat" begin
730617
@test @inferred(ArrayInterface.insert([1,2,3], 2, -2)) == [1, -2, 2, 3]
@@ -734,7 +621,6 @@ end
734621
@test @inferred(ArrayInterface.deleteat([1, 2, 3], [1, 3])) == [2]
735622
@test @inferred(ArrayInterface.deleteat([1, 2, 3], [2, 3])) == [1]
736623

737-
738624
@test @inferred(ArrayInterface.insert((2,3,4), 1, -2)) == (-2, 2, 3, 4)
739625
@test @inferred(ArrayInterface.insert((2,3,4), 2, -2)) == (2, -2, 3, 4)
740626
@test @inferred(ArrayInterface.insert((2,3,4), 3, -2)) == (2, 3, -2, 4)

test/static.jl

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
2+
@testset "StaticInt" begin
3+
@test iszero(StaticInt(0))
4+
@test !iszero(StaticInt(1))
5+
@test !isone(StaticInt(0))
6+
@test isone(StaticInt(1))
7+
@test @inferred(one(StaticInt(1))) === StaticInt(1)
8+
@test @inferred(zero(StaticInt(1))) === StaticInt(0)
9+
@test @inferred(one(StaticInt)) === StaticInt(1)
10+
@test @inferred(zero(StaticInt)) === StaticInt(0) === StaticInt(StaticInt(Val(0)))
11+
@test eltype(one(StaticInt)) <: Int
12+
13+
x = StaticInt(1)
14+
@test @inferred(Bool(x)) isa Bool
15+
@test @inferred(BigInt(x)) isa BigInt
16+
@test @inferred(Integer(x)) === x
17+
# test for ambiguities and correctness
18+
for i Any[StaticInt(0), StaticInt(1), StaticInt(2), 3]
19+
for j Any[StaticInt(0), StaticInt(1), StaticInt(2), 3]
20+
i === j === 3 && continue
21+
for f [+, -, *, ÷, %, <<, >>, >>>, &, |, , ==, , ]
22+
(iszero(j) && ((f === ÷) || (f === %))) && continue # integer division error
23+
@test convert(Int, @inferred(f(i,j))) == f(convert(Int, i), convert(Int, j))
24+
end
25+
end
26+
i == 3 && break
27+
for f [+, -, *, /, ÷, %, ==, , ]
28+
w = f(convert(Int, i), 1.4)
29+
x = f(1.4, convert(Int, i))
30+
@test convert(typeof(w), @inferred(f(i, 1.4))) === w
31+
@test convert(typeof(x), @inferred(f(1.4, i))) === x # if f is division and i === StaticInt(0), returns `NaN`; hence use of ==== in check.
32+
(((f === ÷) || (f === %)) && (i === StaticInt(0))) && continue
33+
y = f(convert(Int, i), 2 // 7)
34+
z = f(2 // 7, convert(Int, i))
35+
@test convert(typeof(y), @inferred(f(i, 2 // 7))) === y
36+
@test convert(typeof(z), @inferred(f(2 // 7, i))) === z
37+
end
38+
end
39+
40+
@test UnitRange{Int16}(StaticInt(-9), 17) === Int16(-9):Int16(17)
41+
@test UnitRange{Int16}(-7, StaticInt(19)) === Int16(-7):Int16(19)
42+
@test UnitRange(-11, StaticInt(15)) === -11:15
43+
@test UnitRange(StaticInt(-11), 15) === -11:15
44+
@test UnitRange(StaticInt(-11), StaticInt(15)) === -11:15
45+
@test float(StaticInt(8)) === 8.0
46+
end
47+
48+
@testset "StaticBool" begin
49+
t = True()
50+
f = False()
51+
52+
@test @inferred(StaticInt(t)) === StaticInt(1)
53+
@test @inferred(StaticInt(f)) === StaticInt(0)
54+
55+
@test @inferred(~t) === f
56+
@test @inferred(~f) === t
57+
@test @inferred(!t) === f
58+
@test @inferred(!f) === t
59+
@test @inferred(+t) === StaticInt(1)
60+
@test @inferred(+f) === StaticInt(0)
61+
@test @inferred(-t) === StaticInt(-1)
62+
@test @inferred(-f) === StaticInt(0)
63+
64+
@test @inferred(|(true, f))
65+
@test @inferred(|(f, true))
66+
@test @inferred(|(f, f)) === f
67+
@test @inferred(|(f, t)) === t
68+
@test @inferred(|(t, f)) === t
69+
@test @inferred(|(t, t)) === t
70+
71+
@test !@inferred(Base.:(&)(true, f))
72+
@test !@inferred(Base.:(&)(f, true))
73+
@test @inferred(Base.:(&)(f, f)) === f
74+
@test @inferred(Base.:(&)(f, t)) === f
75+
@test @inferred(Base.:(&)(t, f)) === f
76+
@test @inferred(Base.:(&)(t, t)) === t
77+
78+
@test @inferred(<(f, f)) === f
79+
@test @inferred(<(f, t)) === t
80+
@test @inferred(<(t, f)) === f
81+
@test @inferred(<(t, t)) === f
82+
83+
@test @inferred(<=(f, f)) === t
84+
@test @inferred(<=(f, t)) === t
85+
@test @inferred(<=(t, f)) === f
86+
@test @inferred(<=(t, t)) === t
87+
88+
@test @inferred(*(f, t)) === t & f
89+
@test @inferred(-(f, t)) === StaticInt(f) - StaticInt(t)
90+
@test @inferred(+(f, t)) === StaticInt(f) + StaticInt(t)
91+
92+
@test @inferred(^(t, f)) == ^(true, false)
93+
@test @inferred(^(t, t)) == ^(true, true)
94+
95+
@test @inferred(^(2, f)) == 1
96+
@test @inferred(^(2, t)) == 2
97+
98+
@test @inferred(^(BigInt(2), f)) == 1
99+
@test @inferred(^(BigInt(2), t)) == 2
100+
101+
@test @inferred(div(t, t)) === t
102+
@test_throws DivideError div(t, f)
103+
104+
@test @inferred(rem(t, t)) === f
105+
@test_throws DivideError rem(t, f)
106+
@test @inferred(mod(t, t)) === f
107+
108+
@test @inferred(all((t, t, t)))
109+
@test !@inferred(all((t, f, t)))
110+
@test !@inferred(all((f, f, f)))
111+
112+
@test @inferred(any((t, t, t)))
113+
@test @inferred(any((t, f, t)))
114+
@test !@inferred(any((f, f, f)))
115+
116+
x = StaticInt(1)
117+
y = StaticInt(0)
118+
z = StaticInt(-1)
119+
@test @inferred(ArrayInterface.eq(x, y)) === f
120+
@test @inferred(ArrayInterface.eq(x, x)) === t
121+
122+
@test @inferred(ArrayInterface.ne(x, y)) === t
123+
@test @inferred(ArrayInterface.ne(x, x)) === f
124+
125+
@test @inferred(ArrayInterface.gt(x, y)) === t
126+
@test @inferred(ArrayInterface.gt(y, x)) === f
127+
128+
@test @inferred(ArrayInterface.ge(x, y)) === t
129+
@test @inferred(ArrayInterface.ge(y, x)) === f
130+
131+
@test @inferred(ArrayInterface.lt(y, x)) === t
132+
@test @inferred(ArrayInterface.lt(x, y)) === f
133+
134+
@test @inferred(ArrayInterface.le(y, x)) === t
135+
@test @inferred(ArrayInterface.le(x, y)) === f
136+
end
137+

0 commit comments

Comments
 (0)