Skip to content

Commit

Permalink
AxisArrays features: support eltype, convert, minimum, maximum, etc
Browse files Browse the repository at this point in the history
  • Loading branch information
timholy committed Sep 11, 2016
1 parent 60b0ce1 commit 024f3f5
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 8 deletions.
16 changes: 14 additions & 2 deletions src/IntervalSets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,24 @@ module IntervalSets

# package code goes here

import Base: show, in, length, isempty, isequal, issubset, ==, union, intersect
using Base: @pure
import Base: eltype, convert, show, in, length, isempty, isequal, issubset, ==, hash, union, intersect, minimum, maximum

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

abstract AbstractInterval{T}

include("closed.jl")

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

convert{I<:AbstractInterval}(::Type{I}, i::I) = i
function convert{I<:AbstractInterval}(::Type{I}, i::AbstractInterval)
T = eltype(I)
I(convert(T, i.left), convert(T, i.right))
end

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

Expand Down
15 changes: 13 additions & 2 deletions src/closed.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""
A `ClosedInterval(left, right)` is an interval set that includes both its upper and lower bounds. In
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}
immutable ClosedInterval{T} <: AbstractInterval{T}
left::T
right::T

Expand All @@ -20,6 +20,9 @@ function ClosedInterval(left, right)
ClosedInterval{T}(checked_conversion(T, left, right)...)
end

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

..(x, y) = ClosedInterval(x, y)

±(x, y) = ClosedInterval(x - y, x + y)
Expand All @@ -28,13 +31,21 @@ end
show(io::IO, I::ClosedInterval) = print(io, I.left, "..", I.right)

in(v, I::ClosedInterval) = I.left <= v <= I.right
in(a::ClosedInterval, b::ClosedInterval) = (b.left <= a.left) & (a.right <= b.right)

isempty(A::ClosedInterval) = A.left > A.right

isequal(A::ClosedInterval, B::ClosedInterval) = (isequal(A.left, B.left) & isequal(A.right, B.right)) | (isempty(A) & isempty(B))

==(A::ClosedInterval, B::ClosedInterval) = (A.left == B.left && A.right == B.right) || (isempty(A) && isempty(B))

const _closed_interval_hash = UInt == UInt64 ? 0x1588c274e0a33ad4 : 0x1e3f7252

hash(I::ClosedInterval, h::UInt) = hash(I.left, hash(I.right, hash(_closed_interval_hash, h)))

minimum(I::ClosedInterval) = I.left
maximum(I::ClosedInterval) = I.right

function intersect(A::ClosedInterval, B::ClosedInterval)
left = max(A.left, B.left)
right = min(A.right, B.right)
Expand Down
21 changes: 17 additions & 4 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,25 @@ using Base.Test
@test_throws ArgumentError :a .. "b"
I = 0..3
print(io, I)
@test String(io) == "0..3"
@test takebuf_string(io) == "0..3"
J = 3..2
K = 5..4
L = 3 ± 2
M = ClosedInterval(2, 5.0)
takebuf_array(io)
print(io, M)
@test String(io) == "2.0..5.0"
@test takebuf_string(io) == "2.0..5.0"
N = ClosedInterval(UInt8(255), 300)
O = CartesianIndex(1, 2, 3, 4) ± 2
@test O == (-1..3, 0..4, 1..5, 2..6)

@test eltype(I) == Int
@test eltype(M) == Float64
@test convert(ClosedInterval{Float64}, I) === 0.0..3.0
@test !(convert(ClosedInterval{Float64}, I) === 0..3)
@test ClosedInterval{Float64}(1,3) === 1.0..3.0
@test ClosedInterval(0.5..2.5) === 0.5..2.5
@test ClosedInterval{Int}(1.0..3.0) === 1..3

@test !isempty(I)
@test isempty(J)
@test J == K
Expand All @@ -34,9 +41,13 @@ using Base.Test
@test isequal(J, K)

@test typeof(M.left) == typeof(M.right) && typeof(M.left) == Float64
@test typeof(N.left) == typeof(N.right) && typeof(N.left) == Int
@test typeof(N.left) == typeof(N.right) && typeof(N.left) == Int

@test maximum(I) === 3
@test minimum(I) === 0

@test 2 in I
@test 1..2 in 0.5..2.5

@test I L == ClosedInterval(0, 5)
@test I L == ClosedInterval(1, 3)
Expand All @@ -60,5 +71,7 @@ using Base.Test
@test (ClosedInterval(7, 9) I) == false
@test I I
@test I ClosedInterval(1, 2)

@test hash(1..3) == hash(1.0..3.0)
end
end

0 comments on commit 024f3f5

Please sign in to comment.