Skip to content

Commit 57d443e

Browse files
authored
Merge pull request #40 from invenia/cv/refactor
Refactoring of #34 and #37
2 parents 8a7016a + 52a1179 commit 57d443e

File tree

3 files changed

+46
-73
lines changed

3 files changed

+46
-73
lines changed

CODEOWNERS

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# Default owners for everything in the repo.
2-
* @omus @spurll
2+
* @omus

src/interval.jl

+40-43
Original file line numberDiff line numberDiff line change
@@ -87,36 +87,6 @@ end
8787

8888
Base.copy(x::Interval{T}) where T = Interval{T}(x.first, x.last, x.inclusivity)
8989

90-
function Base.merge(a::AbstractInterval{T}, b::AbstractInterval{T}) where T
91-
!overlapscontiguous(a,b) && throw(ArgumentError("$a and $b are not touching."))
92-
93-
left = min(LeftEndpoint(a), LeftEndpoint(b))
94-
right = max(RightEndpoint(a), RightEndpoint(b))
95-
return Interval(
96-
left.endpoint,
97-
right.endpoint,
98-
Inclusivity(left.included, right.included)
99-
)
100-
end
101-
102-
function overlapscontiguous(a::AbstractInterval, b::AbstractInterval)
103-
return overlaps(a,b) || contiguous(a,b)
104-
end
105-
106-
function overlaps(a::AbstractInterval, b::AbstractInterval)
107-
left = max(LeftEndpoint(a), LeftEndpoint(b))
108-
right = min(RightEndpoint(a), RightEndpoint(b))
109-
110-
return left <= right
111-
end
112-
113-
function contiguous(a::AbstractInterval, b::AbstractInterval)
114-
left = max(LeftEndpoint(a), LeftEndpoint(b))
115-
right = min(RightEndpoint(a), RightEndpoint(b))
116-
117-
return right.endpoint == left.endpoint && left.included != right.included
118-
end
119-
12090
##### ACCESSORS #####
12191

12292
Base.first(interval::Interval) = interval.first
@@ -175,8 +145,7 @@ Base.:+(a::T, b) where {T <: Interval} = T(first(a) + b, last(a) + b, inclusivit
175145

176146
Base.:+(a, b::Interval) = b + a
177147
Base.:-(a::Interval, b) = a + -b
178-
179-
Base.:-(a::T, b::Interval{T}) where T = a + -b
148+
Base.:-(a, b::Interval) = a + -b
180149

181150
function Base.:-(a::Interval{T}) where T
182151
inc = inclusivity(a)
@@ -185,23 +154,23 @@ end
185154

186155
##### EQUALITY #####
187156

188-
function Base.:(==)(a::AbstractInterval{T}, b::AbstractInterval{T}) where T
157+
function Base.:(==)(a::AbstractInterval, b::AbstractInterval)
189158
return LeftEndpoint(a) == LeftEndpoint(b) && RightEndpoint(a) == RightEndpoint(b)
190159
end
191160

192161
# While it might be convincingly argued that this should define < instead of isless (see
193162
# https://github.com/invenia/Intervals.jl/issues/14), this breaks sort.
194-
Base.isless(a::AbstractInterval{T}, b::T) where T = LeftEndpoint(a) < b
195-
Base.isless(a::T, b::AbstractInterval{T}) where T = a < LeftEndpoint(b)
163+
Base.isless(a::AbstractInterval, b) = LeftEndpoint(a) < b
164+
Base.isless(a, b::AbstractInterval) = a < LeftEndpoint(b)
196165

197-
less_than_disjoint(a::AbstractInterval{T}, b::T) where T = RightEndpoint(a) < b
198-
less_than_disjoint(a::T, b::AbstractInterval{T}) where T = a < LeftEndpoint(b)
166+
less_than_disjoint(a::AbstractInterval, b) = RightEndpoint(a) < b
167+
less_than_disjoint(a, b::AbstractInterval) = a < LeftEndpoint(b)
199168

200-
function Base.:isless(a::AbstractInterval{T}, b::AbstractInterval{T}) where T
169+
function Base.:isless(a::AbstractInterval, b::AbstractInterval)
201170
return LeftEndpoint(a) < LeftEndpoint(b)
202171
end
203172

204-
function less_than_disjoint(a::AbstractInterval{T}, b::AbstractInterval{T}) where T
173+
function less_than_disjoint(a::AbstractInterval, b::AbstractInterval)
205174
return RightEndpoint(a) < LeftEndpoint(b)
206175
end
207176

@@ -248,12 +217,26 @@ true
248217
Base.isempty(i::AbstractInterval) = LeftEndpoint(i) > RightEndpoint(i)
249218
Base.in(a::T, b::AbstractInterval{T}) where T = !(a b || a b)
250219

251-
function Base.issubset(a::AbstractInterval{T}, b::AbstractInterval{T}) where T
220+
function Base.issubset(a::AbstractInterval, b::AbstractInterval)
252221
return LeftEndpoint(a) LeftEndpoint(b) && RightEndpoint(a) RightEndpoint(b)
253222
end
254223

255-
Base.:(a::AbstractInterval{T}, b::AbstractInterval{T}) where T = !issubset(a, b)
256-
Base.:(a::AbstractInterval{T}, b::AbstractInterval{T}) where T = !issubset(b, a)
224+
Base.:(a::AbstractInterval, b::AbstractInterval) = !issubset(a, b)
225+
Base.:(a::AbstractInterval, b::AbstractInterval) = !issubset(b, a)
226+
227+
function overlaps(a::AbstractInterval, b::AbstractInterval)
228+
left = max(LeftEndpoint(a), LeftEndpoint(b))
229+
right = min(RightEndpoint(a), RightEndpoint(b))
230+
231+
return left <= right
232+
end
233+
234+
function contiguous(a::AbstractInterval, b::AbstractInterval)
235+
left = max(LeftEndpoint(a), LeftEndpoint(b))
236+
right = min(RightEndpoint(a), RightEndpoint(b))
237+
238+
return right.endpoint == left.endpoint && left.included != right.included
239+
end
257240

258241
function Base.intersect(a::AbstractInterval{T}, b::AbstractInterval{T}) where T
259242
!overlaps(a,b) && return Interval{T}()
@@ -290,7 +273,7 @@ function Base.union!(intervals::Union{AbstractVector{<:Interval}, AbstractVector
290273
curr = intervals[i]
291274

292275
# If the current and previous intervals don't meet then move along
293-
if !overlapscontiguous(prev, curr)
276+
if !overlaps(prev, curr) && !contiguous(prev, curr)
294277
i = i + 1
295278

296279
# If the two intervals meet then we absorb the current interval into
@@ -305,6 +288,20 @@ function Base.union!(intervals::Union{AbstractVector{<:Interval}, AbstractVector
305288
return intervals
306289
end
307290

291+
function Base.merge(a::AbstractInterval, b::AbstractInterval)
292+
if !overlaps(a, b) && !contiguous(a, b)
293+
throw(ArgumentError("$a and $b are neither overlapping or contiguous."))
294+
end
295+
296+
left = min(LeftEndpoint(a), LeftEndpoint(b))
297+
right = max(RightEndpoint(a), RightEndpoint(b))
298+
return Interval(
299+
left.endpoint,
300+
right.endpoint,
301+
Inclusivity(left.included, right.included)
302+
)
303+
end
304+
308305
##### TIME ZONES #####
309306

310307
function astimezone(i::Interval{ZonedDateTime}, tz::TimeZone)

test/interval.jl

+5-29
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@
284284
@test_throws MethodError unit - interval
285285
end
286286
end
287+
288+
@test_throws MethodError Interval(a, b) + Interval(a, b)
289+
@test_throws MethodError Interval(a, b) - Interval(a, b)
287290
end
288291

289292
# DST transition
@@ -358,6 +361,8 @@
358361
@test !in(b, interval)
359362
@test in(b - unit, interval)
360363
@test !in(b + unit, interval)
364+
365+
@test_throws MethodError (in(Interval(a, b), Interval(a, b)))
361366
end
362367
end
363368

@@ -471,35 +476,6 @@
471476
end
472477
end
473478

474-
@testset "overlapscontiguous" begin
475-
a = Interval(-100, -1)
476-
b = Interval(-5, 10)
477-
478-
@test Intervals.overlapscontiguous(a,a)
479-
@test Intervals.overlapscontiguous(a,b)
480-
@test Intervals.overlapscontiguous(b,a)
481-
482-
b = Interval(5, 10)
483-
@test !Intervals.overlapscontiguous(a,b)
484-
@test !Intervals.overlapscontiguous(b,a)
485-
486-
a = Interval(10, 20, Inclusivity(true, false))
487-
b = Interval(-5, 10, Inclusivity(false, true))
488-
@test Intervals.overlapscontiguous(a,b)
489-
490-
a = Interval(10, 20, Inclusivity(false, false))
491-
b = Interval(-5, 10, Inclusivity(false, true))
492-
@test Intervals.overlapscontiguous(a,b)
493-
494-
a = Interval(10, 20, Inclusivity(true, false))
495-
b = Interval(-5, 10, Inclusivity(false, false))
496-
@test Intervals.overlapscontiguous(a,b)
497-
498-
a = Interval(10, 20, Inclusivity(false, false))
499-
b = Interval(-5, 10, Inclusivity(false, false))
500-
@test !Intervals.overlapscontiguous(a,b)
501-
end
502-
503479
@testset "merge" begin
504480
a = Interval(-100, -1)
505481
b = Interval(-3, 10)

0 commit comments

Comments
 (0)