Skip to content

Commit 9c7cc1c

Browse files
authored
Replace in with issubset and fix #61 (#62)
1 parent d7e4642 commit 9c7cc1c

File tree

2 files changed

+104
-48
lines changed

2 files changed

+104
-48
lines changed

src/IntervalSets.jl

+62-15
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,6 @@ end
9999

100100
mean(d::AbstractInterval) = (leftendpoint(d) + rightendpoint(d))/2
101101

102-
issubset(A::AbstractInterval, B::AbstractInterval) = ((leftendpoint(A) in B) && (rightendpoint(A) in B)) || isempty(A)
103-
(A::AbstractInterval, B::AbstractInterval) = issubset(B, A)
104-
if VERSION < v"1.1.0-DEV.123"
105-
issubset(x, B::AbstractInterval) = issubset(convert(AbstractInterval, x), B)
106-
end
107-
108102
"""
109103
w = width(iv)
110104
@@ -143,22 +137,49 @@ in(::Missing, I::TypedEndpointsInterval{:open,:open}) = !isempty(I) && missing
143137
in(::Missing, I::TypedEndpointsInterval{:closed,:open}) = !isempty(I) && missing
144138
in(::Missing, I::TypedEndpointsInterval{:open,:closed}) = !isempty(I) && missing
145139

146-
in(a::AbstractInterval, b::TypedEndpointsInterval{:closed,:closed}) =
140+
# The code below can be defined as
141+
# ```
142+
# function in(a::AbstractInterval, b::AbstractInterval)
143+
# Base.depwarn("`in(a::AbstractInterval, b::AbstractInterval)` (equivalently, `a ∈ b`) is deprecated in favor of `issubset(a, b)` (equivalently, `a ⊆ b`). Note that the behavior for empty intervals is also changing.", :in)
144+
# return in_deprecation(a, b)
145+
# end
146+
# ```
147+
# but that makes ambiguity definition.
148+
function in(a::AbstractInterval, b::TypedEndpointsInterval{:closed,:closed})
149+
Base.depwarn("`in(a::AbstractInterval, b::AbstractInterval)` (equivalently, `a ∈ b`) is deprecated in favor of `issubset(a, b)` (equivalently, `a ⊆ b`). Note that the behavior for empty intervals is also changing.", :in)
150+
return in_deprecation(a, b)
151+
end
152+
function in(a::AbstractInterval, b::TypedEndpointsInterval{:open,:open})
153+
Base.depwarn("`in(a::AbstractInterval, b::AbstractInterval)` (equivalently, `a ∈ b`) is deprecated in favor of `issubset(a, b)` (equivalently, `a ⊆ b`). Note that the behavior for empty intervals is also changing.", :in)
154+
return in_deprecation(a, b)
155+
end
156+
function in(a::AbstractInterval, b::TypedEndpointsInterval{:closed,:open})
157+
Base.depwarn("`in(a::AbstractInterval, b::AbstractInterval)` (equivalently, `a ∈ b`) is deprecated in favor of `issubset(a, b)` (equivalently, `a ⊆ b`). Note that the behavior for empty intervals is also changing.", :in)
158+
return in_deprecation(a, b)
159+
end
160+
function in(a::AbstractInterval, b::TypedEndpointsInterval{:open,:closed})
161+
Base.depwarn("`in(a::AbstractInterval, b::AbstractInterval)` (equivalently, `a ∈ b`) is deprecated in favor of `issubset(a, b)` (equivalently, `a ⊆ b`). Note that the behavior for empty intervals is also changing.", :in)
162+
return in_deprecation(a, b)
163+
end
164+
165+
in_deprecation(a::AbstractInterval, b::TypedEndpointsInterval{:closed,:closed}) =
147166
(leftendpoint(a) leftendpoint(b)) & (rightendpoint(a) rightendpoint(b))
148-
in(a::TypedEndpointsInterval{:open,:open}, b::TypedEndpointsInterval{:open,:open}) =
167+
in_deprecation(a::TypedEndpointsInterval{:open,:open}, b::TypedEndpointsInterval{:open,:open} ) =
149168
(leftendpoint(a) leftendpoint(b)) & (rightendpoint(a) rightendpoint(b))
150-
in(a::TypedEndpointsInterval{:closed,:open}, b::TypedEndpointsInterval{:open,:open}) =
169+
in_deprecation(a::TypedEndpointsInterval{:closed,:open}, b::TypedEndpointsInterval{:open,:open} ) =
151170
(leftendpoint(a) > leftendpoint(b)) & (rightendpoint(a) rightendpoint(b))
152-
in(a::TypedEndpointsInterval{:open,:closed}, b::TypedEndpointsInterval{:open,:open}) =
171+
in_deprecation(a::TypedEndpointsInterval{:open,:closed}, b::TypedEndpointsInterval{:open,:open} ) =
153172
(leftendpoint(a) leftendpoint(b)) & (rightendpoint(a) < rightendpoint(b))
154-
in(a::TypedEndpointsInterval{:closed,:closed}, b::TypedEndpointsInterval{:open,:open}) =
173+
in_deprecation(a::TypedEndpointsInterval{:closed,:closed}, b::TypedEndpointsInterval{:open,:open} ) =
155174
(leftendpoint(a) > leftendpoint(b)) & (rightendpoint(a) < rightendpoint(b))
156-
in(a::TypedEndpointsInterval{:closed}, b::TypedEndpointsInterval{:open,:closed}) =
175+
in_deprecation(a::TypedEndpointsInterval{:closed}, b::TypedEndpointsInterval{:open,:closed} ) =
157176
(leftendpoint(a) > leftendpoint(b)) & (rightendpoint(a) rightendpoint(b))
158-
in(a::TypedEndpointsInterval{:open}, b::TypedEndpointsInterval{:open,:closed}) =
177+
in_deprecation(a::TypedEndpointsInterval{:open}, b::TypedEndpointsInterval{:open,:closed} ) =
178+
(leftendpoint(a) leftendpoint(b)) & (rightendpoint(a) rightendpoint(b))
179+
in_deprecation(a::TypedEndpointsInterval{L,:closed}, b::TypedEndpointsInterval{:closed,:open}) where L =
180+
(leftendpoint(a) leftendpoint(b)) & (rightendpoint(a) < rightendpoint(b))
181+
in_deprecation(a::TypedEndpointsInterval{L,:open}, b::TypedEndpointsInterval{:closed,:open}) where L =
159182
(leftendpoint(a) leftendpoint(b)) & (rightendpoint(a) rightendpoint(b))
160-
in(a::TypedEndpointsInterval{L,:closed}, b::TypedEndpointsInterval{:closed,:open}) where L = (leftendpoint(a) leftendpoint(b)) & (rightendpoint(a) < rightendpoint(b))
161-
in(a::TypedEndpointsInterval{L,:open}, b::TypedEndpointsInterval{:closed,:open}) where L = (leftendpoint(a) leftendpoint(b)) & (rightendpoint(a) rightendpoint(b))
162183

163184
isempty(A::TypedEndpointsInterval{:closed,:closed}) = leftendpoint(A) > rightendpoint(A)
164185
isempty(A::TypedEndpointsInterval) = leftendpoint(A) rightendpoint(A)
@@ -169,6 +190,32 @@ isequal(A::TypedEndpointsInterval, B::TypedEndpointsInterval) = isempty(A) & ise
169190
==(A::TypedEndpointsInterval{L,R}, B::TypedEndpointsInterval{L,R}) where {L,R} = (leftendpoint(A) == leftendpoint(B) && rightendpoint(A) == rightendpoint(B)) || (isempty(A) && isempty(B))
170191
==(A::TypedEndpointsInterval, B::TypedEndpointsInterval) = isempty(A) && isempty(B)
171192

193+
function issubset(A::TypedEndpointsInterval, B::TypedEndpointsInterval)
194+
Al, Ar = endpoints(A)
195+
Bl, Br = endpoints(B)
196+
return isempty(A) | ( (Bl Al) & (Ar Br) )
197+
end
198+
function issubset(A::TypedEndpointsInterval{:closed,R1} where R1, B::TypedEndpointsInterval{:open,R2} where R2)
199+
Al, Ar = endpoints(A)
200+
Bl, Br = endpoints(B)
201+
return isempty(A) | ( (Bl < Al) & (Ar Br) )
202+
end
203+
function issubset(A::TypedEndpointsInterval{L1,:closed} where L1, B::TypedEndpointsInterval{L2,:open} where L2)
204+
Al, Ar = endpoints(A)
205+
Bl, Br = endpoints(B)
206+
return isempty(A) | ( (Bl Al) & (Ar < Br) )
207+
end
208+
function issubset(A::TypedEndpointsInterval{:closed,:closed}, B::TypedEndpointsInterval{:open,:open})
209+
Al, Ar = endpoints(A)
210+
Bl, Br = endpoints(B)
211+
return isempty(A) | ( (Bl < Al) & (Ar < Br) )
212+
end
213+
214+
(A::AbstractInterval, B::AbstractInterval) = issubset(B, A)
215+
if VERSION < v"1.1.0-DEV.123"
216+
issubset(x, B::AbstractInterval) = issubset(convert(AbstractInterval, x), B)
217+
end
218+
172219
const _interval_hash = UInt == UInt64 ? 0x1588c274e0a33ad4 : 0x1e3f7252
173220

174221
hash(I::TypedEndpointsInterval, h::UInt) = hash(leftendpoint(I), hash(rightendpoint(I), hash(_interval_hash, h)))

test/runtests.jl

+42-33
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ struct IncompleteInterval <: AbstractInterval{Int} end
7575
@test extrema(I) === (0, 3)
7676

7777
@test 2 in I
78-
@test 1..2 in 0.5..2.5
78+
@test issubset(1..2, 0.5..2.5)
7979

8080
@test @inferred(I L) == ClosedInterval(0, 5)
8181
@test @inferred(I L) == ClosedInterval(1, 3)
@@ -343,36 +343,36 @@ struct IncompleteInterval <: AbstractInterval{Int} end
343343
end
344344
end
345345

346-
@testset "In" begin
346+
@testset "Issubset" begin
347347
I = 0..3
348348
J = 1..2
349-
@test J I
350-
@test I J
351-
@test OpenInterval(J) I
352-
@test OpenInterval(I) J
353-
@test J OpenInterval(I)
354-
@test I OpenInterval(J)
355-
@test OpenInterval(J) OpenInterval(I)
356-
@test OpenInterval(I) OpenInterval(J)
357-
@test Interval{:closed,:open}(J) OpenInterval(I)
358-
@test Interval{:open,:closed}(J) OpenInterval(I)
359-
@test Interval{:open,:closed}(J) Interval{:open,:closed}(I)
360-
@test OpenInterval(I) OpenInterval(J)
361-
362-
@test Interval{:closed,:open}(J) I
363-
@test I Interval{:closed,:open}(J)
364-
365-
366-
@test I I
367-
@test OpenInterval(I) I
368-
@test Interval{:open,:closed}(I) I
369-
@test Interval{:closed,:open}(I) I
370-
@test I OpenInterval(I)
371-
@test I Interval{:open,:closed}(I)
372-
@test I Interval{:closed,:open}(I)
373-
374-
@test Interval{:closed,:open}(I) Interval{:closed,:open}(I)
375-
@test Interval{:open,:closed}(I) Interval{:closed,:open}(I)
349+
@test J I
350+
@test I J
351+
@test OpenInterval(J) I
352+
@test OpenInterval(I) J
353+
@test J OpenInterval(I)
354+
@test I OpenInterval(J)
355+
@test OpenInterval(J) OpenInterval(I)
356+
@test OpenInterval(I) OpenInterval(J)
357+
@test Interval{:closed,:open}(J) OpenInterval(I)
358+
@test Interval{:open,:closed}(J) OpenInterval(I)
359+
@test Interval{:open,:closed}(J) Interval{:open,:closed}(I)
360+
@test OpenInterval(I) OpenInterval(J)
361+
362+
@test Interval{:closed,:open}(J) I
363+
@test I Interval{:closed,:open}(J)
364+
365+
366+
@test I I
367+
@test OpenInterval(I) I
368+
@test Interval{:open,:closed}(I) I
369+
@test Interval{:closed,:open}(I) I
370+
@test I OpenInterval(I)
371+
@test I Interval{:open,:closed}(I)
372+
@test I Interval{:closed,:open}(I)
373+
374+
@test Interval{:closed,:open}(I) Interval{:closed,:open}(I)
375+
@test Interval{:open,:closed}(I) Interval{:closed,:open}(I)
376376

377377
@test !isequal(I, OpenInterval(I))
378378
@test !(I == OpenInterval(I))
@@ -637,11 +637,20 @@ struct IncompleteInterval <: AbstractInterval{Int} end
637637
@test_broken ismissing(2 in missing..1) # would be fixed by julialang#31171
638638
end
639639

640+
@testset "in" begin
641+
@test in(0.1, 0.0..1.0) == true
642+
@test in(0.0, 0.0..1.0) == true
643+
@test in(1.1, 0.0..1.0) == false
644+
@test in(0.0, nextfloat(0.0)..1.0) == false
645+
end
646+
640647
@testset "issubset" begin
641-
@test issubset(0.1, 0.0..1.0) == true
642-
@test issubset(0.0, 0.0..1.0) == true
643-
@test issubset(1.1, 0.0..1.0) == false
644-
@test issubset(0.0, nextfloat(0.0)..1.0) == false
648+
@test issubset(Interval{:closed,:closed}(1,2), Interval{:closed,:closed}(1,2)) == true
649+
@test issubset(Interval{:closed,:closed}(1,2), Interval{:open ,:open }(1,2)) == false
650+
@test issubset(Interval{:closed,:open }(1,2), Interval{:open ,:open }(1,2)) == false
651+
@test issubset(Interval{:open ,:closed}(1,2), Interval{:open ,:open }(1,2)) == false
652+
@test issubset(Interval{:closed,:closed}(1,2), Interval{:closed,:closed}(1,prevfloat(2.0))) == false
653+
@test issubset(Interval{:closed,:open }(1,2), Interval{:open ,:open }(prevfloat(1.0),2)) == true
645654
end
646655

647656
@testset "missing in" begin

0 commit comments

Comments
 (0)