Skip to content

Commit

Permalink
Use types for bounds
Browse files Browse the repository at this point in the history
  • Loading branch information
omus committed Jun 10, 2020
1 parent 797c523 commit 91939f4
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 64 deletions.
42 changes: 21 additions & 21 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,23 @@ This package defines:

```jldoctest
julia> a = 1..10
Interval{Int64,:closed,:closed}(1, 10)
Interval{Int64,Closed,Closed}(1, 10)
julia> b = 5..15
Interval{Int64,:closed,:closed}(5, 15)
Interval{Int64,Closed,Closed}(5, 15)
julia> intersect(a, b)
Interval{Int64,:closed,:closed}(5, 10)
Interval{Int64,Closed,Closed}(5, 10)
```

### Bounds

```jldoctest
julia> a = Interval{:closed,:closed}(1, 10)
Interval{Int64,:closed,:closed}(1, 10)
julia> a = Interval{Closed,Closed}(1, 10)
Interval{Int64,Closed,Closed}(1, 10)
julia> b = Interval{:open,:open}(5, 15)
Interval{Int64,:open,:open}(5, 15)
julia> b = Interval{Open,Open}(5, 15)
Interval{Int64,Open,Open}(5, 15)
julia> 5 in a
true
Expand All @@ -55,10 +55,10 @@ julia> 5 in b
false
julia> intersect(a, b)
Interval{Int64,:open,:closed}(5, 10)
Interval{Int64,Open,Closed}(5, 10)
julia> c = Interval(15, 20)
Interval{Int64,:closed,:closed}(15, 20)
Interval{Int64,Closed,Closed}(15, 20)
julia> isempty(intersect(b, c))
true
Expand All @@ -68,21 +68,21 @@ true

```jldoctest
julia> a = Interval('a', 'z')
Interval{Char,:closed,:closed}('a', 'z')
Interval{Char,Closed,Closed}('a', 'z')
julia> string(a)
"[a .. z]"
julia> using Dates
julia> b = Interval{:closed,:open}(Date(2013), Date(2016))
Interval{Date,:closed,:open}(2013-01-01, 2016-01-01)
julia> b = Interval{Closed,Open}(Date(2013), Date(2016))
Interval{Date,Closed,Open}(2013-01-01, 2016-01-01)
julia> string(b)
"[2013-01-01 .. 2016-01-01)"
julia> c = HourEnding(DateTime(2016, 8, 11))
AnchoredInterval{-1 hour,DateTime,:open,:closed}(2016-08-11T00:00:00)
AnchoredInterval{-1 hour,DateTime,Open,Closed}(2016-08-11T00:00:00)
julia> string(c)
"(2016-08-10 HE24]"
Expand All @@ -94,13 +94,13 @@ julia> string(c)
julia> using TimeZones, Dates
julia> unrounded = HourEnding(ZonedDateTime(2013, 2, 13, 0, 30, tz"America/Winnipeg"))
AnchoredInterval{-1 hour,ZonedDateTime,:open,:closed}(ZonedDateTime(2013, 2, 13, 0, 30, tz"America/Winnipeg"))
AnchoredInterval{-1 hour,ZonedDateTime,Open,Closed}(ZonedDateTime(2013, 2, 13, 0, 30, tz"America/Winnipeg"))
julia> he = HE(ZonedDateTime(2013, 2, 13, 0, 30, tz"America/Winnipeg"))
AnchoredInterval{-1 hour,ZonedDateTime,:open,:closed}(ZonedDateTime(2013, 2, 13, 1, tz"America/Winnipeg"))
AnchoredInterval{-1 hour,ZonedDateTime,Open,Closed}(ZonedDateTime(2013, 2, 13, 1, tz"America/Winnipeg"))
julia> he + Hour(1)
AnchoredInterval{-1 hour,ZonedDateTime,:open,:closed}(ZonedDateTime(2013, 2, 13, 2, tz"America/Winnipeg"))
AnchoredInterval{-1 hour,ZonedDateTime,Open,Closed}(ZonedDateTime(2013, 2, 13, 2, tz"America/Winnipeg"))
julia> foreach(println, he:he + Day(1))
(2013-02-13 HE01-06:00]
Expand Down Expand Up @@ -166,14 +166,14 @@ Two `AbstractInterval`s are considered equal if they have identical left and rig
endpoints (taking bounds into account):

```jldoctest
julia> a = Interval{:closed,:open}(DateTime(2013, 2, 13), DateTime(2013, 2, 13, 1))
Interval{DateTime,:closed,:open}(2013-02-13T00:00:00, 2013-02-13T01:00:00)
julia> a = Interval{Closed,Open}(DateTime(2013, 2, 13), DateTime(2013, 2, 13, 1))
Interval{DateTime,Closed,Open}(2013-02-13T00:00:00, 2013-02-13T01:00:00)
julia> b = Interval{:open,:closed}(DateTime(2013, 2, 13), DateTime(2013, 2, 13, 1))
Interval{DateTime,:open,:closed}(2013-02-13T00:00:00, 2013-02-13T01:00:00)
julia> b = Interval{Open,Closed}(DateTime(2013, 2, 13), DateTime(2013, 2, 13, 1))
Interval{DateTime,Open,Closed}(2013-02-13T00:00:00, 2013-02-13T01:00:00)
julia> c = HourEnding(DateTime(2013, 2, 13, 1))
AnchoredInterval{-1 hour,DateTime,:open,:closed}(2013-02-13T01:00:00)
AnchoredInterval{-1 hour,DateTime,Open,Closed}(2013-02-13T01:00:00)
julia> a == b
false
Expand Down
15 changes: 11 additions & 4 deletions src/Intervals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@ using Dates: AbstractDateTime, value, coarserperiod

import Base: , , , , union, union!, merge

abstract type AbstractInterval{T,L,R} end
abstract type Bound end
struct Closed <: Bound end
struct Open <: Bound end

bound(x::Bool) = x ? Closed : Open

abstract type AbstractInterval{T, L <: Bound, R <: Bound} end

Base.eltype(::AbstractInterval{T}) where {T} = T
Base.broadcastable(x::AbstractInterval) = Ref(x)

bound(x::Bool) = x ? :closed : :open

include("inclusivity.jl")
include("endpoint.jl")
include("interval.jl")
Expand All @@ -24,7 +28,10 @@ include("description.jl")
include("plotting.jl")
include("deprecated.jl")

export AbstractInterval,
export Bound,
Closed,
Open,
AbstractInterval,
Interval,
AnchoredInterval,
HourEnding,
Expand Down
6 changes: 3 additions & 3 deletions src/anchoredinterval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ AnchoredInterval{5 minutes, DateTime}(2016-08-11T12:30:00, Inclusivity(true, tru
See also: [`Interval`](@ref), [`HE`](@ref), [`HB`](@ref)
"""
struct AnchoredInterval{P,T,L,R} <: AbstractInterval{T,L,R}
struct AnchoredInterval{P, T, L <: Bound, R <: Bound} <: AbstractInterval{T,L,R}
anchor::T
end

Expand All @@ -83,7 +83,7 @@ AnchoredInterval{P}(anchor::T) where {P,T} = AnchoredInterval{P,T}(anchor)
A type alias for `AnchoredInterval{Hour(-1), T}` which is used to denote a 1-hour period of
time which ends at a time instant (of type `T`).
"""
const HourEnding{T,L,R} = AnchoredInterval{Hour(-1), T, L, R} where {T,L,R}
const HourEnding{T,L,R} = AnchoredInterval{Hour(-1), T, L, R} where {T, L <: Bound, R <: Bound}
HourEnding(anchor::T) where T = HourEnding{T}(anchor)

# Note: Ideally we would define the restriction `T <: TimeType` but doing so interferes with
Expand All @@ -94,7 +94,7 @@ HourEnding(anchor::T) where T = HourEnding{T}(anchor)
A type alias for `AnchoredInterval{Hour(1), T}` which is used to denote a 1-hour period of
time which begins at a time instant (of type `T`).
"""
const HourBeginning{T,L,R} = AnchoredInterval{Hour(1), T, L, R} where {T,L,R}
const HourBeginning{T,L,R} = AnchoredInterval{Hour(1), T, L, R} where {T, L <: Bound, R <: Bound}
HourBeginning(anchor::T) where T = HourBeginning{T}(anchor)

"""
Expand Down
4 changes: 2 additions & 2 deletions src/endpoint.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const Right = Direction{:Right}()
const Beginning = Left
const Ending = Right

struct Endpoint{T,D,B}
struct Endpoint{T, D, B <: Bound}
endpoint::T

function Endpoint{T,D,B}(ep::T) where {T,D,B}
Expand All @@ -25,7 +25,7 @@ LeftEndpoint(i::AbstractInterval{T,L,R}) where {T,L,R} = LeftEndpoint{T,L}(first
RightEndpoint(i::AbstractInterval{T,L,R}) where {T,L,R} = RightEndpoint{T,R}(last(i))

bound(x::Endpoint{T,D,B}) where {T,D,B} = B
isclosed(x::Endpoint) = bound(x) === :closed
isclosed(x::Endpoint) = bound(x) === Closed

function Base.hash(x::Endpoint{T,D,B}, h::UInt) where {T,D,B}
# Note: we shouldn't need to hash `T` as this is covered by the endpoint field.
Expand Down
6 changes: 3 additions & 3 deletions src/interval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Note that the `Inclusivity` value is also reversed in this case.
See also: [`AnchoredInterval`](@ref)
"""
struct Interval{T,L,R} <: AbstractInterval{T,L,R}
struct Interval{T, L <: Bound, R <: Bound} <: AbstractInterval{T,L,R}
first::T
last::T

Expand All @@ -75,7 +75,7 @@ Interval{T,L,R}(f, l) where {T,L,R} = Interval{T,L,R}(convert(T, f), convert(T,
Interval{L,R}(f::T, l::T) where {T,L,R} = Interval{T,L,R}(f, l)
Interval{L,R}(f, l) where {L,R} = Interval{promote_type(typeof(f), typeof(l)), L, R}(f, l)

Interval{T}(f, l) where {T,L,R} = Interval{T, :closed, :closed}(f, l)
Interval{T}(f, l) where {T,L,R} = Interval{T, Closed, Closed}(f, l)

Interval(f::T, l::T) where T = Interval{T}(f, l)
Interval(f, l) = Interval(promote(f, l)...)
Expand Down Expand Up @@ -120,7 +120,7 @@ end
Base.first(interval::Interval) = interval.first
Base.last(interval::Interval) = interval.last
span(interval::Interval) = interval.last - interval.first
inclusivity(interval::AbstractInterval{T,L,R}) where {T,L,R} = Inclusivity(L === :closed, R === :closed)
inclusivity(interval::AbstractInterval{T,L,R}) where {T,L,R} = Inclusivity(L === Closed, R === Closed)
isclosed(interval::AbstractInterval) = isclosed(inclusivity(interval))
Base.isopen(interval::AbstractInterval) = isopen(inclusivity(interval))

Expand Down
Loading

0 comments on commit 91939f4

Please sign in to comment.