Skip to content

Commit cdaf9e4

Browse files
committed
Switch type parameters for AnchoredInterval
1 parent bcde3f7 commit cdaf9e4

File tree

6 files changed

+162
-149
lines changed

6 files changed

+162
-149
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
This package defines:
1010
* `AbstractInterval`, along with its subtypes:
1111
* `Interval{T}`, which represents a non-iterable range between two endpoints of type `T`
12-
* `AnchoredInterval{P, T}`, which represents a non-iterable range defined by a single
12+
* `AnchoredInterval{T, P}`, which represents a non-iterable range defined by a single
1313
value `anchor::T` and the value type `P` which represents the size of the range
14-
* `HourEnding`, a type alias for `AnchoredInterval{Hour(-1)}`
15-
* `HourBeginning`, a type alias for `AnchoredInterval{Hour(1)}`
14+
* `HourEnding`, a type alias for `AnchoredInterval{T, Hour(-1)}`
15+
* `HourBeginning`, a type alias for `AnchoredInterval{T, Hour(1)}`
1616
* `HE` and `HB`, pseudoconstructors for `HourEnding` and `HourBeginning` that round the
1717
anchor up (`HE`) or down (`HB`) to the nearest hour
1818
* `Inclusivity`, which represents whether an `AbstractInterval` is open, half-open, or

docs/src/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
This package defines:
44
* `AbstractInterval`, along with its subtypes:
55
* `Interval{T}`, which represents a non-iterable range between two endpoints of type `T`
6-
* `AnchoredInterval{P, T}`, which represents a non-iterable range defined by a single
6+
* `AnchoredInterval{T, P}`, which represents a non-iterable range defined by a single
77
value `anchor::T` and the value type `P` which represents the size of the range
8-
* `HourEnding`, a type alias for `AnchoredInterval{Hour(-1), T}`
9-
* `HourBeginning`, a type alias for `AnchoredInterval{Hour(1), T}`
8+
* `HourEnding`, a type alias for `AnchoredInterval{T, Hour(-1)}`
9+
* `HourBeginning`, a type alias for `AnchoredInterval{T, Hour(1)}`
1010
* `HE` and `HB`, pseudoconstructors for `HourEnding` and `HourBeginning` that round the
1111
anchor up (`HE`) or down (`HB`) to the nearest hour
1212
* `Inclusivity`, which represents whether an `AbstractInterval` is open, half-open, or

src/anchoredinterval.jl

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
using Base.Dates: value, coarserperiod
22

33
"""
4-
AnchoredInterval{P, T}(anchor::T, [inclusivity::Inclusivity]) where {P, T} -> AnchoredInterval{P, T}
5-
AnchoredInterval{P, T}(anchor::T, [closed_left::Bool, closed_right::Bool]) where {P, T} -> AnchoredInterval{P, T}
4+
AnchoredInterval{T, P}(anchor::T, [inclusivity::Inclusivity]) -> AnchoredInterval{T, P}
5+
AnchoredInterval{T, P}(anchor::T, [closed_left::Bool, closed_right::Bool]) -> AnchoredInterval{T, P}
6+
7+
AnchoredInterval(anchor::T, P, [inclusivity::Inclusivity]) -> AnchoredInterval{T, P}
8+
AnchoredInterval(anchor::T, P, [closed_left::Bool, closed_right::Bool]) -> AnchoredInterval{T, P}
69
710
`AnchoredInterval` is a subtype of `AbstractInterval` that represents a non-iterable range
811
or span of values defined not by two endpoints but instead by a single `anchor` point and
@@ -21,8 +24,8 @@ included for positive values of `P` and the greater endpoint included for negati
2124
range of values. This happens most often with dates and times, where "HE15" is often used as
2225
shorthand for (14:00..15:00].
2326
24-
To this end, `HourEnding` is a type alias for `AnchoredInterval{Hour(-1)}`. Similarly,
25-
`HourBeginning` is a type alias for `AnchoredInterval{Hour(1)}`.
27+
To this end, `HourEnding` is a type alias for `AnchoredInterval{T, Hour(-1)} where T`.
28+
Similarly, `HourBeginning` is a type alias for `AnchoredInterval{T, Hour(1)} where T`.
2629
2730
### Rounding
2831
@@ -48,44 +51,42 @@ HourBeginning{DateTime}(2016-08-11T02:00:00, Inclusivity(true, false))
4851
### Example
4952
5053
```julia
51-
julia> AnchoredInterval{Hour(-1)}(DateTime(2016, 8, 11, 12))
54+
julia> AnchoredInterval(DateTime(2016, 8, 11, 12), Hour(-1))
5255
HourEnding{DateTime}(2016-08-11T12:00:00, Inclusivity(false, true))
5356
54-
julia> AnchoredInterval{Day(1)}(DateTime(2016, 8, 11))
55-
AnchoredInterval{1 day, DateTime}(2016-08-11T00:00:00, Inclusivity(true, false))
57+
julia> AnchoredInterval(DateTime(2016, 8, 11), Day(1))
58+
AnchoredInterval{DateTime, 1 day}(2016-08-11T00:00:00, Inclusivity(true, false))
5659
57-
julia> AnchoredInterval{Minute(5)}(DateTime(2016, 8, 11, 12, 30), true, true)
58-
AnchoredInterval{5 minutes, DateTime}(2016-08-11T12:30:00, Inclusivity(true, true))
60+
julia> AnchoredInterval(DateTime(2016, 8, 11, 12, 30), Minute(5), true, true)
61+
AnchoredInterval{DateTime, 5 minutes}(2016-08-11T12:30:00, Inclusivity(true, true))
5962
```
6063
6164
See also: [`Interval`](@ref), [`Inclusivity`](@ref), [`HE`](@ref), [`HB`](@ref)
6265
"""
63-
struct AnchoredInterval{P, T} <: AbstractInterval{T}
66+
struct AnchoredInterval{T, P} <: AbstractInterval{T}
6467
anchor::T
6568
inclusivity::Inclusivity
6669
end
6770

6871
# When an interval is anchored to the lesser endpoint, default to Inclusivity(false, true)
6972
# When an interval is anchored to the greater endpoint, default to Inclusivity(true, false)
70-
function AnchoredInterval{P, T}(i::T) where {P, T}
71-
return AnchoredInterval{P, T}(i::T, Inclusivity(P zero(P), P zero(P)))
73+
function AnchoredInterval{T, P}(i::T) where {T, P}
74+
return AnchoredInterval{T, P}(i::T, Inclusivity(P zero(P), P zero(P)))
7275
end
7376

74-
AnchoredInterval{P}(i::T, inc::Inclusivity) where {P, T} = AnchoredInterval{P, T}(i, inc)
75-
AnchoredInterval{P}(i::T) where {P, T} = AnchoredInterval{P, T}(i)
76-
77-
function AnchoredInterval{P, T}(i::T, x::Bool, y::Bool) where {P, T}
78-
return AnchoredInterval{P, T}(i, Inclusivity(x, y))
77+
function AnchoredInterval{T, P}(i::T, x::Bool, y::Bool) where {T, P}
78+
return AnchoredInterval{T, P}(i, Inclusivity(x, y))
7979
end
8080

81-
function AnchoredInterval{P}(i::T, x::Bool, y::Bool) where {P, T}
82-
return AnchoredInterval{P, T}(i, Inclusivity(x, y))
83-
end
81+
AnchoredInterval(i::T, span, inc::Inclusivity) where T = AnchoredInterval{T, span}(i, inc)
82+
AnchoredInterval(i::T, span, x::Bool, y::Bool) where T = AnchoredInterval{T, span}(i, x, y)
83+
AnchoredInterval(i::T, span) where T = AnchoredInterval{T, span}(i)
84+
8485

85-
const HourEnding{T} = AnchoredInterval{Hour(-1), T} where T <: TimeType
86+
const HourEnding{T} = AnchoredInterval{T, Hour(-1)} where T <: TimeType
8687
HourEnding(a::T, args...) where T = HourEnding{T}(a, args...)
8788

88-
const HourBeginning{T} = AnchoredInterval{Hour(1), T} where T <: TimeType
89+
const HourBeginning{T} = AnchoredInterval{T, Hour(1)} where T <: TimeType
8990
HourBeginning(a::T, args...) where T = HourBeginning{T}(a, args...)
9091

9192
"""
@@ -104,32 +105,38 @@ nearest hour.
104105
"""
105106
HB(a, args...) = HourBeginning(floor(a, Hour), args...)
106107

107-
function Base.copy(x::AnchoredInterval{P, T}) where {P, T}
108-
return AnchoredInterval{P, T}(anchor(x), inclusivity(x))
108+
function Base.copy(x::AnchoredInterval{T, P}) where {T, P}
109+
return AnchoredInterval{T, P}(anchor(x), inclusivity(x))
109110
end
110111

111112
##### ACCESSORS #####
112113

113-
Base.first(interval::AnchoredInterval{P}) where P = min(interval.anchor, interval.anchor+P)
114-
Base.last(interval::AnchoredInterval{P}) where P = max(interval.anchor, interval.anchor+P)
114+
function Base.first(interval::AnchoredInterval{T, P}) where {T, P}
115+
min(interval.anchor, interval.anchor + P)
116+
end
117+
118+
function Base.last(interval::AnchoredInterval{T, P}) where {T, P}
119+
max(interval.anchor, interval.anchor + P)
120+
end
121+
115122
anchor(interval::AnchoredInterval) = interval.anchor
116-
span(interval::AnchoredInterval{P}) where P = abs(P)
123+
span(interval::AnchoredInterval{T, P}) where {T, P} = abs(P)
117124

118125
##### CONVERSION #####
119126

120-
function Base.convert(::Type{Interval}, interval::AnchoredInterval{P, T}) where {P, T}
127+
function Base.convert(::Type{Interval}, interval::AnchoredInterval{T}) where T
121128
return Interval{T}(first(interval), last(interval), inclusivity(interval))
122129
end
123130

124-
function Base.convert(::Type{Interval{T}}, interval::AnchoredInterval{P, T}) where {P, T}
131+
function Base.convert(::Type{Interval{T}}, interval::AnchoredInterval{T}) where T
125132
return Interval{T}(first(interval), last(interval), inclusivity(interval))
126133
end
127134

128-
Base.convert(::Type{T}, interval::AnchoredInterval{P, T}) where {P, T} = anchor(interval)
135+
Base.convert(::Type{T}, interval::AnchoredInterval{T}) where T = anchor(interval)
129136

130137
# Date/DateTime attempt to convert to Int64 instead of falling back to convert(T, ...)
131-
Base.Date(interval::AnchoredInterval{P, Date}) where P = convert(Date, interval)
132-
Base.DateTime(interval::AnchoredInterval{P, DateTime}) where P = convert(DateTime, interval)
138+
Base.Date(interval::AnchoredInterval{Date}) = convert(Date, interval)
139+
Base.DateTime(interval::AnchoredInterval{DateTime}) = convert(DateTime, interval)
133140

134141
##### DISPLAY #####
135142

@@ -139,8 +146,8 @@ Base.show(io::IO, ::Type{HourBeginning}) = print(io, "HourBeginning{T}")
139146
Base.show(io::IO, ::Type{HourEnding{T}}) where T <: TimeType = print(io, "HourEnding{$T}")
140147
Base.show(io::IO, ::Type{HourBeginning{T}}) where T <: TimeType = print(io, "HourBeginning{$T}")
141148

142-
function Base.show(io::IO, ::Type{AnchoredInterval{P, T}}) where {P, T}
143-
print(io, "AnchoredInterval{$P, $T}")
149+
function Base.show(io::IO, ::Type{AnchoredInterval{T, P}}) where {T, P}
150+
print(io, "AnchoredInterval{$T, $P}")
144151
end
145152

146153
function Base.show(io::IO, interval::T) where T <: AnchoredInterval
@@ -155,7 +162,7 @@ function Base.show(io::IO, interval::T) where T <: AnchoredInterval
155162
end
156163
end
157164

158-
function Base.print(io::IO, interval::AnchoredInterval{P, T}) where {P, T <: TimeType}
165+
function Base.print(io::IO, interval::AnchoredInterval{<:TimeType})
159166
# Print to io in order to keep properties like :limit and :compact
160167
if get(io, :compact, false)
161168
io = IOContext(io, :limit=>true)
@@ -174,11 +181,11 @@ Base.:-(a::AnchoredInterval, b) = a + -b
174181
# Required for StepRange{<:AnchoredInterval}
175182
Base.:-(a::AnchoredInterval, b::AnchoredInterval) = anchor(a) - anchor(b)
176183

177-
Base.:-(a::T, b::AnchoredInterval{P, T}) where {P, T <: Number} = a + -b
184+
Base.:-(a::T, b::AnchoredInterval{T}) where {T <: Number} = a + -b
178185

179-
function Base.:-(a::AnchoredInterval{P, T}) where {P, T <: Number}
186+
function Base.:-(a::AnchoredInterval{T, P}) where {T <: Number, P}
180187
inc = inclusivity(a)
181-
AnchoredInterval{-P, T}(-anchor(a), Inclusivity(last(inc), first(inc)))
188+
AnchoredInterval{T, -P}(-anchor(a), Inclusivity(last(inc), first(inc)))
182189
end
183190

184191
##### RANGE #####
@@ -189,7 +196,7 @@ function Base.steprem(a::T, b::T, c) where {T <: AnchoredInterval}
189196
end
190197

191198
# Infer step for two-argument StepRange{<:AnchoredInterval}
192-
function Base.colon(start::AnchoredInterval{P, T}, stop::AnchoredInterval{P, T}) where {P,T}
199+
function Base.colon(start::AnchoredInterval{T, P}, stop::AnchoredInterval{T, P}) where {T,P}
193200
return colon(start, abs(P), stop)
194201
end
195202

@@ -199,11 +206,11 @@ end
199206

200207
##### SET OPERATIONS #####
201208

202-
function Base.isempty(interval::AnchoredInterval{P, T}) where {P, T}
209+
function Base.isempty(interval::AnchoredInterval{T, P}) where {T, P}
203210
return P == zero(P) && !isclosed(interval)
204211
end
205212

206-
function Base.intersect(a::AnchoredInterval{P, T}, b::AnchoredInterval{Q, T}) where {P,Q,T}
213+
function Base.intersect(a::AnchoredInterval{T, P}, b::AnchoredInterval{T, Q}) where {T,P,Q}
207214
interval = invoke(intersect, Tuple{AbstractInterval{T}, AbstractInterval{T}}, a, b)
208215

209216
sp = isa(P, Period) ? canonicalize(typeof(P), span(interval)) : span(interval)
@@ -215,7 +222,7 @@ function Base.intersect(a::AnchoredInterval{P, T}, b::AnchoredInterval{Q, T}) wh
215222
new_P = sp
216223
end
217224

218-
return AnchoredInterval{new_P, T}(anchor, inclusivity(interval))
225+
return AnchoredInterval{T, new_P}(anchor, inclusivity(interval))
219226
end
220227

221228
##### UTILITIES #####

src/description.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
using Base.Dates: value, coarserperiod
22

3-
description(interval::AnchoredInterval{P}) where P = description(interval, P > zero(P) ? "B" : "E")
3+
function description(interval::AnchoredInterval{T, P}) where {T, P}
4+
description(interval, P > zero(P) ? "B" : "E")
5+
end
46

5-
function description(interval::AnchoredInterval{P, T}, s::String) where {P, T}
7+
function description(interval::AnchoredInterval{T, P}, s::String) where {T, P}
68
return string(
79
first(inclusivity(interval)) ? '[' : '(',
810
description(anchor(interval), abs(P), s),
911
last(inclusivity(interval)) ? ']' : ')',
1012
)
1113
end
1214

13-
function description(interval::AnchoredInterval{P, ZonedDateTime}, s::String) where P
15+
function description(interval::AnchoredInterval{ZonedDateTime, P}, s::String) where P
1416
return string(
1517
first(inclusivity(interval)) ? '[' : '(',
1618
description(anchor(interval), abs(P), s),

src/endpoint.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ struct Direction{T} end
22
const Left = Direction{:Left}()
33
const Right = Direction{:Right}()
44

5+
const Beginning = Left
6+
const Ending = Right
7+
58
struct Endpoint{T, D}
69
endpoint::T
710
included::Bool

0 commit comments

Comments
 (0)