Skip to content

Commit

Permalink
Updates for Julia 0.6 and 0.7 (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
ararslan authored Mar 15, 2018
1 parent d13b0fa commit e214e32
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 38 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ os:
- linux
- osx
julia:
- 0.5
- 0.6
- nightly
notifications:
Expand Down
4 changes: 2 additions & 2 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
julia 0.5
Compat 0.17
julia 0.6
Compat 0.49
2 changes: 0 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
environment:
matrix:
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.5/julia-0.5-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
Expand Down
29 changes: 13 additions & 16 deletions src/IntervalSets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,38 @@ __precompile__()

module IntervalSets

# package code goes here

using Base: @pure
import Base: eltype, convert, show, in, length, isempty, isequal, issubset, ==, hash, union, intersect, minimum, maximum, extrema, range
if isdefined(Main, :)
import Base:
end
import Base: eltype, convert, show, in, length, isempty, isequal, issubset, ==, hash,
union, intersect, minimum, maximum, extrema, range,

using Compat
using Compat.Dates

export AbstractInterval, ClosedInterval, , .., ±, ordered, width

@compat abstract type AbstractInterval{T} end
abstract type AbstractInterval{T} end

include("closed.jl")

eltype{T}(::Type{AbstractInterval{T}}) = T
@pure eltype{I<:AbstractInterval}(::Type{I}) = eltype(supertype(I))
eltype(::Type{AbstractInterval{T}}) where {T} = T
@pure eltype(::Type{I}) where {I<:AbstractInterval} = eltype(supertype(I))

convert{I<:AbstractInterval}(::Type{I}, i::I) = i
function convert{I<:AbstractInterval}(::Type{I}, i::AbstractInterval)
convert(::Type{I}, i::I) where {I<:AbstractInterval} = i
function convert(::Type{I}, i::AbstractInterval) where I<:AbstractInterval
T = eltype(I)
I(convert(T, i.left), convert(T, i.right))
end
function convert{I<:AbstractInterval}(::Type{I}, r::Range)
function convert(::Type{I}, r::AbstractRange) where I<:AbstractInterval
T = eltype(I)
I(convert(T, minimum(r)), convert(T, maximum(r)))
end

ordered{T}(a::T, b::T) = ifelse(a < b, (a, b), (b, a))
ordered(a::T, b::T) where {T} = ifelse(a < b, (a, b), (b, a))
ordered(a, b) = ordered(promote(a, b)...)

checked_conversion{T}(::Type{T}, a, b) = _checked_conversion(T, convert(T, a), convert(T, b))
_checked_conversion{T}(::Type{T}, a::T, b::T) = a, b
checked_conversion(::Type{T}, a, b) where {T} = _checked_conversion(T, convert(T, a), convert(T, b))
_checked_conversion(::Type{T}, a::T, b::T) where {T} = a, b
_checked_conversion(::Type{Any}, a, b) = throw(ArgumentError("$a and $b promoted to type Any"))
_checked_conversion{T}(::Type{T}, a, b) = throw(ArgumentError("$a and $b are not both of type $T"))
_checked_conversion(::Type{T}, a, b) where {T} = throw(ArgumentError("$a and $b are not both of type $T"))

end # module
25 changes: 11 additions & 14 deletions src/closed.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@
A `ClosedInterval(left, right)` is an interval set that includes both its upper and lower bounds. In
mathematical notation, the constructed range is `[left, right]`.
"""
immutable ClosedInterval{T} <: AbstractInterval{T}
struct ClosedInterval{T} <: AbstractInterval{T}
left::T
right::T

(::Type{ClosedInterval{T}}){T}(l::T, r::T) = new{T}(l, r)
ClosedInterval{T}(l::T, r::T) where {T} = new{T}(l, r)
ClosedInterval{T}(l, r) where {T} = ((a, b) = checked_conversion(T, l, r); new{T}(a, b))
ClosedInterval{T}(i::AbstractInterval) where {T} = convert(ClosedInterval{T}, i)
end

ClosedInterval{T}(left::T, right::T) = ClosedInterval{T}(left, right)
(::Type{ClosedInterval{T}}){T}(left, right) =
ClosedInterval{T}(checked_conversion(T, left, right)...)

function ClosedInterval(left, right)
# Defining this as ClosedInterval(promote(left, right)...) has one problem:
# if left and right do not promote to a common type, it triggers a StackOverflow.
Expand All @@ -21,7 +19,6 @@ function ClosedInterval(left, right)
end

ClosedInterval(i::AbstractInterval) = convert(ClosedInterval{eltype(i)}, i)
(::Type{ClosedInterval{T}}){T}(i::AbstractInterval) = convert(ClosedInterval{T}, i)

"""
iv = l..r
Expand All @@ -37,7 +34,7 @@ Construct a ClosedInterval `iv` spanning the region from
`center - halfwidth` to `center + halfwidth`.
"""
±(x, y) = ClosedInterval(x - y, x + y)
±(x::CartesianIndex, y) = map(ClosedInterval, (x - y).I, (x + y).I)
±(x::CartesianIndex, y) = (xy = y * one(x); map(ClosedInterval, (x - xy).I, (x + xy).I))

show(io::IO, I::ClosedInterval) = print(io, I.left, "..", I.right)

Expand All @@ -64,7 +61,7 @@ function intersect(A::ClosedInterval, B::ClosedInterval)
ClosedInterval(left, right)
end

function union{T<:AbstractFloat}(A::ClosedInterval{T}, B::ClosedInterval{T})
function union(A::ClosedInterval{T}, B::ClosedInterval{T}) where T<:AbstractFloat
max(A.left, B.left) <= nextfloat(min(A.right, B.right)) || throw(ArgumentError("Cannot construct union of disjoint sets."))
_union(A, B)
end
Expand All @@ -90,19 +87,19 @@ issubset(A::ClosedInterval, B::ClosedInterval) = ((A.left in B) && (A.right in B
Calculate the width (max-min) of interval `iv`. Note that for integers
`l` and `r`, `width(l..r) = length(l:r) - 1`.
"""
function width{T}(A::ClosedInterval{T})
function width(A::ClosedInterval{T}) where T
_width = A.right - A.left
max(zero(_width), _width) # this works when T is a Date
end

length{T <: Integer}(A::ClosedInterval{T}) = max(0, Int(A.right - A.left) + 1)
length(A::ClosedInterval{T}) where {T<:Integer} = max(0, Int(A.right - A.left) + 1)

length(A::ClosedInterval{Date}) = max(0, Dates.days(A.right - A.left) + 1)

function convert{R<:AbstractUnitRange,I<:Integer}(::Type{R}, i::ClosedInterval{I})
function convert(::Type{R}, i::ClosedInterval{I}) where {R<:AbstractUnitRange,I<:Integer}
R(minimum(i), maximum(i))
end

range{I<:Integer}(i::ClosedInterval{I}) = convert(UnitRange{I}, i)
range(i::ClosedInterval{I}) where {I<:Integer} = convert(UnitRange{I}, i)

Base.promote_rule{T1,T2}(::Type{ClosedInterval{T1}}, ::Type{ClosedInterval{T2}}) = ClosedInterval{promote_type(T1, T2)}
Base.promote_rule(::Type{ClosedInterval{T1}}, ::Type{ClosedInterval{T2}}) where {T1,T2} = ClosedInterval{promote_type(T1, T2)}
8 changes: 5 additions & 3 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using IntervalSets
using Base.Test
using Compat
using Compat.Test
using Compat.Dates

@testset "IntervalSets" begin
@test ordered(2, 1) == (1, 2)
Expand Down Expand Up @@ -77,8 +79,8 @@ using Base.Test
@test hash(1..3) == hash(1.0..3.0)

let A = Date(1990, 1, 1), B = Date(1990, 3, 1)
@test width(ClosedInterval(A, B)) == Base.Dates.Day(59)
@test width(ClosedInterval(B, A)) == Base.Dates.Day(0)
@test width(ClosedInterval(A, B)) == Dates.Day(59)
@test width(ClosedInterval(B, A)) == Dates.Day(0)
@test isempty(ClosedInterval(B, A))
@test length(ClosedInterval(A, B)) 60
@test length(ClosedInterval(B, A)) 0
Expand Down

0 comments on commit e214e32

Please sign in to comment.