Skip to content

Commit 6f5b07a

Browse files
authored
Merge pull request #51 from invenia/cv/non-ordered
Fixes for non-ordered intervals
2 parents 74c9ff0 + b436ac7 commit 6f5b07a

File tree

4 files changed

+38
-3
lines changed

4 files changed

+38
-3
lines changed

src/anchoredinterval.jl

+16-2
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,18 @@ end
121121

122122
##### ACCESSORS #####
123123

124-
Base.first(interval::AnchoredInterval{P}) where P = min(interval.anchor, interval.anchor+P)
125-
Base.last(interval::AnchoredInterval{P}) where P = max(interval.anchor, interval.anchor+P)
124+
# We would typically compute `first` and `last` using `min` and `max` respectively, but we
125+
# can get unexpected behaviour if adding the span to the anchor endpoint produces a value
126+
# that is no longer comparable (e.g., `NaN`).
127+
128+
function Base.first(interval::AnchoredInterval{P}) where P
129+
P < zero(P) ? (interval.anchor + P) : (interval.anchor)
130+
end
131+
132+
function Base.last(interval::AnchoredInterval{P}) where P
133+
P < zero(P) ? (interval.anchor) : (interval.anchor + P)
134+
end
135+
126136
anchor(interval::AnchoredInterval) = interval.anchor
127137
span(interval::AnchoredInterval{P}) where P = abs(P)
128138

@@ -209,6 +219,10 @@ end
209219

210220
##### EQUALITY #####
211221

222+
function Base.:(==)(a::AnchoredInterval{P, T}, b::AnchoredInterval{P, T}) where {P, T}
223+
return anchor(a) == anchor(b) && inclusivity(a) == inclusivity(b)
224+
end
225+
212226
# Required for min/max of AnchoredInterval{LaxZonedDateTime} when the anchor is AMB or DNE
213227
function Base.isless(a::AnchoredInterval{P, T}, b::AnchoredInterval{P, T}) where {P, T}
214228
return (

src/interval.jl

+3-1
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,10 @@ struct Interval{T} <: AbstractInterval{T}
6363
# Ensure that `first` preceeds `last`.
6464
f, l, inc = if f l
6565
f, l, inc
66-
else
66+
elseif l f
6767
l, f, Inclusivity(last(inc), first(inc))
68+
else
69+
throw(ArgumentError("Unable to determine an ordering between: $f and $l"))
6870
end
6971

7072
return new(f, l, inc)

test/anchoredinterval.jl

+14
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,20 @@ using Intervals: canonicalize
3636
@test AnchoredInterval{25}('a') isa AnchoredInterval
3737
end
3838

39+
@testset "non-ordered" begin
40+
ending = AnchoredInterval{-Inf}(Inf)
41+
@test isequal(first(ending), NaN)
42+
@test isequal(last(ending), Inf)
43+
@test ending == ending
44+
@test isequal(ending, ending)
45+
46+
beginning = AnchoredInterval{Inf}(-Inf)
47+
@test isequal(first(beginning), -Inf)
48+
@test isequal(last(beginning), NaN)
49+
@test beginning == beginning
50+
@test isequal(beginning, beginning)
51+
end
52+
3953
@testset "hash" begin
4054
# Need a complicated enough element type for this test to ever fail
4155
zdt = now(tz"Europe/London")

test/interval.jl

+5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@
3737
@test_throws MethodError Interval(1, 2, 3)
3838
end
3939

40+
@testset "non-ordered" begin
41+
@test_throws ArgumentError Interval(NaN, Inf)
42+
@test_throws ArgumentError Interval(NaN, NaN)
43+
end
44+
4045
@testset "hash" begin
4146
# Need a complicated enough element type for this test to ever fail
4247
zdt = now(tz"Europe/London")

0 commit comments

Comments
 (0)