Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/offsetintegers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,18 @@ for op in (:(+), :(-), :(*), :(/), :div)
end
end

for op in (:(==), :(>=), :(<=), :(<), :(>), :sub_with_overflow)
# No mixed OffsetInteger/Integer methods for the comparison operators: they
# go through Base's promotion machinery (promote_rule + convert above) with
# identical semantics, just like mixed +/-/* already do. Defining e.g.
# `==(::Integer, ::OffsetInteger)` invalidates compiled comparison code in
# unrelated packages whenever GeometryBasics loads (~1.8k method instances,
# measured via SnoopCompile in a Makie session).
for op in (:(==), :(>=), :(<=), :(<), :(>))
@eval begin
function Base.$op(x::OffsetInteger{O}, y::OffsetInteger{O}) where {O}
return $op(x.i, y.i)
end
Base.$op(x::OffsetInteger, y::OffsetInteger) = $op(value(x), value(y))
Base.$op(x::OffsetInteger, y::Integer) = $op(value(x), y)
Base.$op(x::Integer, y::OffsetInteger) = $op(x, value(y))
end
end

Expand Down
39 changes: 39 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,45 @@ end
@test <(x, x1)
end
end

# With a nonzero offset `raw != value`, so this exercises the arithmetic
# and the same-offset comparison method `op(x.i, y.i)` for an offset != 0.
let O = 3
a = OffsetInteger{O}(2)
b = OffsetInteger{O}(4)
@test GeometryBasics.value(a) == 2
@test GeometryBasics.raw(a) == 2 + O
@test Base.to_index(a) == 2
@test -(a) == OffsetInteger{O}(-2)
@test abs(OffsetInteger{O}(-2)) == OffsetInteger{O}(2)
@test +(a, b) == OffsetInteger{O}(6)
@test -(b, a) == OffsetInteger{O}(2)
@test *(a, b) == OffsetInteger{O}(8)
@test div(b, a) == OffsetInteger{O}(2)
@test a == OffsetInteger{O}(2)
@test a != b
@test a < b
@test a <= b
@test b > a
@test b >= a
end

# Comparing OffsetIntegers with *different* offsets goes through the
# value-based fallback method `op(value(x), value(y))`.
let
a = OffsetInteger{0}(5) # value 5
b = OffsetInteger{3}(5) # value 5
c = OffsetInteger{3}(7) # value 7
@test a == b
@test a <= b
@test a >= b
@test !(a < b)
@test a < c
@test a <= c
@test c > a
@test c >= a
@test a != c
end
end

@testset "Tests from GeometryTypes" begin
Expand Down
Loading