From ee8ec2faeeb61c3b8b5c5c7d4d50c79a6e8ab83a Mon Sep 17 00:00:00 2001 From: Fernando Chorney Date: Mon, 15 Jun 2020 15:24:29 -0500 Subject: [PATCH 1/3] Consolidate common functions. Add to README --- README.md | 88 +++++++++++++++++++++++-------- src/Infinity.jl | 5 +- src/common.jl | 43 +++++++++++++++ src/infextendedreal/arithmetic.jl | 5 -- src/infextendedreal/base.jl | 3 -- src/infextendedreal/comparison.jl | 6 --- src/infextendedreal/conversion.jl | 8 --- src/infextendedreal/io.jl | 10 ---- src/infextendedtime/arithmetic.jl | 5 +- src/infextendedtime/base.jl | 3 -- src/infextendedtime/comparison.jl | 3 -- src/infextendedtime/conversion.jl | 8 --- src/infextendedtime/io.jl | 10 ---- test/infextendedreal.jl | 6 +-- 14 files changed, 114 insertions(+), 89 deletions(-) create mode 100644 src/common.jl delete mode 100644 src/infextendedreal/io.jl delete mode 100644 src/infextendedtime/conversion.jl delete mode 100644 src/infextendedtime/io.jl diff --git a/README.md b/README.md index 080de20..892656a 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,15 @@ Provides `∞ :: Infinite <: Real` representing positive infinity and `-∞` is negative infinity. +## Extended Types +### InfExtendedReal + Promotion between `Infinite` and some `T <: Real` will yield either: * `T` itself if it can natively represent infinity (e.g. `Float64`, `Rational`); or -* `InfExtended{T} <: Real` otherwise, which represents the union of `T` and `Infinite`. (See the examples.) +* `InfExtendedReal{T} <: Real` otherwise, which represents positive/negative infinity, or a finite value of type `T`. (See the examples.) The following `Base` functions are extended for these types: -* Arithmetic: `+`, `-`, `*`, `/` +* Arithmetic: `typemin`, `typemax`, `+`, `-`, `*`, `/` * Comparison: `==`, `<`, `≤`, `hash`, `signbit`, `sign`, `isfinite`, `isinf`, `isapprox` * Conversion: `promote`, `convert`, `float`, `widen`, `big` * Random: `rand(Infinite)` @@ -19,9 +22,19 @@ The following `Base` functions are extended for these types: Additionally there is a submodule `Utils` exporting infinity-related functions: * `posinf(T)`, `neginf(T)`: positive or negative infinity as a `T` if possible, or else `nothing` * `hasposinf(T)`, `hasneginf(T)`: true if `T` contains positive or negative infinity -* `hasinf(T)`: true if `T` contains both positive and negative infinity (this is used to decide to promote to `InfExtended` or not) +* `hasinf(T)`: true if `T` contains both positive and negative infinity (this is used to decide to promote to `InfExtendedReal` or not) * `isposinf(x)`, `isneginf(x)`: true if `x` is positive or negative infinity +### InfExtendedTime + +Promotion between `Infinite` and some `T <: Dates.TimeType` will yield: +* `InfExtendedTime{T} <: Dates.TimeType`, which represents positive/negative infinity, or a finite value of type `T`. (See the examples.) + +The following `Base` functions are extended for these types: +* Arithmetic: `typemin`, `typemax`, `T+Period`, `T-Period` +* Comparison: `==`. `<`, `≤`, `hash`, `isfinite`, `isinf` +* Conversion: `promote`, `convert` + ## Installation In Julia, type `]` then run @@ -36,29 +49,58 @@ pkg> add Infinity julia> using Infinity julia> x = [1,2,3,∞,-1,-∞] -6-element Array{InfExtended{Int64},1}: - 1 - 2 - 3 - ∞ - -1 - -∞ +6-element Array{InfExtendedReal{Int64},1}: + InfExtendedReal{Int64}(1) + InfExtendedReal{Int64}(2) + InfExtendedReal{Int64}(3) + InfExtendedReal{Int64}(∞) + InfExtendedReal{Int64}(-1) + InfExtendedReal{Int64}(-∞) julia> sort(x) -6-element Array{InfExtended{Int64},1}: - -∞ - -1 - 1 - 2 - 3 - ∞ +6-element Array{InfExtendedReal{Int64},1}: + InfExtendedReal{Int64}(-∞) + InfExtendedReal{Int64}(-1) + InfExtendedReal{Int64}(1) + InfExtendedReal{Int64}(2) + InfExtendedReal{Int64}(3) + InfExtendedReal{Int64}(∞) julia> float(x) 6-element Array{Float64,1}: - 1.0 - 2.0 - 3.0 - Inf - -1.0 - Inf + 1.0 + 2.0 + 3.0 + Inf + -1.0 + -Inf + +julia> using Dates + +julia> x = [Date(2012, 1, 1), Date(2013, 1, 1), Date(2013, 1, 2), ∞, Date(1987, 1, 1), -∞] +6-element Array{InfExtendedTime{Date},1}: + InfExtendedTime{Date}(2012-01-01) + InfExtendedTime{Date}(2013-01-01) + InfExtendedTime{Date}(2013-01-02) + InfExtendedTime{Date}(∞) + InfExtendedTime{Date}(1987-01-01) + InfExtendedTime{Date}(-∞) + +julia> sort(x) +6-element Array{InfExtendedTime{Date},1}: + InfExtendedTime{Date}(-∞) + InfExtendedTime{Date}(1987-01-01) + InfExtendedTime{Date}(2012-01-01) + InfExtendedTime{Date}(2013-01-01) + InfExtendedTime{Date}(2013-01-02) + InfExtendedTime{Date}(∞) + +julia> Day(1) + x +6-element Array{InfExtendedTime{Date},1}: + InfExtendedTime{Date}(2012-01-02) + InfExtendedTime{Date}(2013-01-02) + InfExtendedTime{Date}(2013-01-03) + InfExtendedTime{Date}(∞) + InfExtendedTime{Date}(1987-01-02) + InfExtendedTime{Date}(-∞) ``` diff --git a/src/Infinity.jl b/src/Infinity.jl index c6b8bf8..189352c 100644 --- a/src/Infinity.jl +++ b/src/Infinity.jl @@ -18,15 +18,14 @@ include("infinite/rand.jl") # InfExtendedReal include("infextendedreal/base.jl") include("infextendedreal/arithmetic.jl") -include("infextendedreal/io.jl") include("infextendedreal/comparison.jl") include("infextendedreal/conversion.jl") # InfExtendedTime include("infextendedtime/base.jl") -include("infextendedtime/io.jl") include("infextendedtime/arithmetic.jl") include("infextendedtime/comparison.jl") -include("infextendedtime/conversion.jl") +# Extended Common Functions +include("common.jl") end diff --git a/src/common.jl b/src/common.jl new file mode 100644 index 0000000..5e47077 --- /dev/null +++ b/src/common.jl @@ -0,0 +1,43 @@ +# Extract out common functions/etc for the Extended Types + +for (Name, T) in ((InfExtendedReal, Real), (InfExtendedTime, TimeType)) + @eval begin + # base.jl + $Name{T}(x::$Name{T}) where {T<:$T} = x + + Utils.posinf(::Type{T}) where {T<:$Name} = T(PosInf) + Utils.neginf(::Type{T}) where {T<:$Name} = T(NegInf) + + # arithmetic.jl + Base.typemin(::Type{T}) where {T<:$Name} = neginf(T) + Base.typemax(::Type{T}) where {T<:$Name} = posinf(T) + + # io.jl + function Base.show(io::IO, x::T) where {T<:$Name} + value = isposinf(x) ? ∞ : isneginf(x) ? -∞ : x.finitevalue + if get(io, :compact, false) + print(io, value) + else + print(io, "$T(") + show(io, value) + print(io, ")") + end + end + + # comparison.jl + Base.isfinite(x::$Name) = x.flag == FINITE && isfinite(x.finitevalue) + Base.isinf(x::$Name) = isposinf(x) || isneginf(x) + + Base.:≤(x::$Name, y::$Name) = !(y < x) + + # conversion.jl + Base.promote_rule(::Type{Infinite}, ::Type{T}) where {T<:$T} = T <: $Name ? T : $Name{T} + Base.promote_rule(::Type{$Name{T}}, ::Type{$Name{S}}) where {T<:$T, S<:$T} = $Name(promote_type(T, S)) + Base.promote_rule(::Type{$Name{T}}, ::Type{S}) where {T<:$T, S<:$T} = $Name(promote_type(T, S)) + Base.promote_rule(::Type{$Name{T}}, ::Type{Infinite}) where {T<:$T} = $Name{T} + + Base.convert(::Type{T}, x::S) where {T<:$Name, S<:$T} = T(x) + Base.convert(::Type{T}, x::$Name) where {T<:$Name} = T(x) + Base.convert(::Type{T}, x::Infinite) where {T<:$Name} = T(x) + end +end diff --git a/src/infextendedreal/arithmetic.jl b/src/infextendedreal/arithmetic.jl index f48d047..a08f420 100644 --- a/src/infextendedreal/arithmetic.jl +++ b/src/infextendedreal/arithmetic.jl @@ -1,9 +1,4 @@ # todo: ^, fma, muladd, div, fld, cld, rem, mod, mod1, fld1 - -Base.typemin(::Type{T}) where {T<:InfExtendedReal} = T(NegInf) - -Base.typemax(::Type{T}) where {T<:InfExtendedReal} = T(PosInf) - Base.:+(x::T) where {T<:InfExtendedReal} = T(+x.val) Base.:-(x::T) where {T<:InfExtendedReal} = T(-x.val) diff --git a/src/infextendedreal/base.jl b/src/infextendedreal/base.jl index bfaa9c5..654cf6f 100644 --- a/src/infextendedreal/base.jl +++ b/src/infextendedreal/base.jl @@ -24,7 +24,6 @@ end InfExtendedReal{T}(x::Real) where {T<:Real} = InfExtendedReal{T}(isinf(x) ? convert(Infinite, x) : convert(T, x)) InfExtendedReal{T}(x::InfExtendedReal) where {T<:Real} = InfExtendedReal{T}(x.val) -InfExtendedReal{T}(x::InfExtendedReal{T}) where {T<:Real} = x """ InfExtendedReal(T) @@ -41,7 +40,5 @@ Converts `x` to a `InfExtendedReal(typeof(x))`. @generated InfExtendedReal(x::T) where {T<:Real} = hasinf(T) ? :x : :($(InfExtendedReal(T))(x)) -Utils.posinf(::Type{T}) where {T<:InfExtendedReal} = T(PosInf) -Utils.neginf(::Type{T}) where {T<:InfExtendedReal} = T(NegInf) Utils.isposinf(x::InfExtendedReal) = x.flag == POSINF || isposinf(x.finitevalue) Utils.isneginf(x::InfExtendedReal) = x.flag == NEGINF || isneginf(x.finitevalue) diff --git a/src/infextendedreal/comparison.jl b/src/infextendedreal/comparison.jl index 363b671..ab5b72d 100644 --- a/src/infextendedreal/comparison.jl +++ b/src/infextendedreal/comparison.jl @@ -1,7 +1,3 @@ -Base.isfinite(x::InfExtendedReal) = x.flag == FINITE && isfinite(x.finitevalue) - -Base.isinf(x::InfExtendedReal) = isposinf(x) || isneginf(x) - Base.:(==)(x::InfExtendedReal, y::InfExtendedReal) = isinf(x)==isinf(y) && x.val==y.val Base.hash(x::InfExtendedReal, h::UInt) = hash(x.val, h) @@ -15,8 +11,6 @@ Base.:<(x::InfExtendedReal, y::InfExtendedReal) = x.val < y.val end -Base.:≤(x::InfExtendedReal, y::InfExtendedReal) = !(y < x) - Base.signbit(x::InfExtendedReal) = signbit(x.val) Base.sign(x::InfExtendedReal{T}) where {T<:Real} = convert(T, sign(x.val)) diff --git a/src/infextendedreal/conversion.jl b/src/infextendedreal/conversion.jl index 1fe946d..08879b3 100644 --- a/src/infextendedreal/conversion.jl +++ b/src/infextendedreal/conversion.jl @@ -1,13 +1,5 @@ -Base.promote_rule(::Type{Infinite}, ::Type{T}) where {T<:Real} = InfExtendedReal(T) -Base.promote_rule(::Type{InfExtendedReal{T}}, ::Type{InfExtendedReal{S}}) where {T<:Real, S<:Real} = InfExtendedReal(promote_type(T, S)) -Base.promote_rule(::Type{InfExtendedReal{T}}, ::Type{S}) where {T<:Real, S<:Real} = InfExtendedReal(promote_type(T, S)) -Base.promote_rule(::Type{InfExtendedReal{T}}, ::Type{Infinite}) where {T<:Real} = InfExtendedReal{T} - @generated Base.convert(::Type{T}, x::InfExtendedReal{S}) where {T<:Real,S<:Real} = :(convert($(typeof(convert(T,zero(S)))), x.val)) Base.convert(::Type{Infinite}, x::InfExtendedReal{T}) where {T<:Real} = isinf(x) ? Infinite(signbit(x)) : throw(InexactError(:convert,Infinite,x)) -Base.convert(::Type{T}, x::S) where {T<:InfExtendedReal, S<:Real} = T(x) -Base.convert(::Type{T}, x::InfExtendedReal) where {T<:InfExtendedReal} = T(x) -Base.convert(::Type{T}, x::Infinite) where {T<:InfExtendedReal} = T(x) (::Type{T})(x::InfExtendedReal) where {T<:AbstractFloat} = convert(T, x) diff --git a/src/infextendedreal/io.jl b/src/infextendedreal/io.jl deleted file mode 100644 index 99dc6c5..0000000 --- a/src/infextendedreal/io.jl +++ /dev/null @@ -1,10 +0,0 @@ -function Base.show(io::IO, x::T) where {T<:InfExtendedReal} - value = x.val - if get(io, :compact, false) - print(io, value) - else - print(io, "$T(") - show(io, value) - print(io, ")") - end -end diff --git a/src/infextendedtime/arithmetic.jl b/src/infextendedtime/arithmetic.jl index ae1557a..8f916b0 100644 --- a/src/infextendedtime/arithmetic.jl +++ b/src/infextendedtime/arithmetic.jl @@ -1,12 +1,9 @@ -Base.typemin(::Type{T}) where {T<:InfExtendedTime} = neginf(T) -Base.typemax(::Type{T}) where {T<:InfExtendedTime} = posinf(T) - function Base.:+(x::T, y::S) where {T<:InfExtendedTime, S<:Period} isinf(x) ? x : T(x.finitevalue + y) end Base.:+(x::S, y::T) where {T<:InfExtendedTime, S<:Period} = y + x Base.:-(x::T, y::S) where {T<:InfExtendedTime, S<:Period} = x + -y -Base.:-(x::S, y::T) where {T<:InfExtendedTime, S<:Period} = isposinf(y) ? Utils.neginf(T) : y + -x +Base.:-(x::S, y::T) where {T<:InfExtendedTime, S<:Period} = isposinf(y) ? neginf(T) : y + -x for TType in (TimeType, Period) @eval begin diff --git a/src/infextendedtime/base.jl b/src/infextendedtime/base.jl index 91e2a43..716ef72 100644 --- a/src/infextendedtime/base.jl +++ b/src/infextendedtime/base.jl @@ -13,7 +13,6 @@ end InfExtendedTime{T}(x::TimeType) where {T<:TimeType} = InfExtendedTime{T}(convert(T, x)) InfExtendedTime{T}(x::InfExtendedTime) where {T<:TimeType} = InfExtendedTime{T}(convert(T, x.finitevalue)) -InfExtendedTime{T}(x::InfExtendedTime{T}) where {T<:TimeType} = x """ InfExtendedTime(T) @@ -29,7 +28,5 @@ Converts `x` to `InfExtendedTime(typeof(x))`. """ InfExtendedTime(x::T) where {T<:TimeType} = InfExtendedTime{T}(x) -Utils.posinf(::Type{T}) where {T<:InfExtendedTime} = T(PosInf) -Utils.neginf(::Type{T}) where {T<:InfExtendedTime} = T(NegInf) Utils.isposinf(x::InfExtendedTime) = x.flag == POSINF Utils.isneginf(x::InfExtendedTime) = x.flag == NEGINF diff --git a/src/infextendedtime/comparison.jl b/src/infextendedtime/comparison.jl index 2d965c5..d4e1159 100644 --- a/src/infextendedtime/comparison.jl +++ b/src/infextendedtime/comparison.jl @@ -1,5 +1,3 @@ -Base.isfinite(x::InfExtendedTime) = x.flag == FINITE && isfinite(x.finitevalue) -Base.isinf(x::InfExtendedTime) = isposinf(x) || isneginf(x) Base.:(==)(x::InfExtendedTime, y::InfExtendedTime) = (isfinite(x) && isfinite(y)) ? x.finitevalue == y.finitevalue : x.flag == y.flag Base.:(==)(x::Infinite, y::T) where {T<:InfExtendedTime} = T(x) == y Base.:(==)(x::T, y::Infinite) where {T<:InfExtendedTime} = x == T(y) @@ -18,6 +16,5 @@ end Base.isless(x::Infinite, y::T) where {T<:InfExtendedTime} = isless(T(x), y) Base.isless(x::T, y::Infinite) where {T<:InfExtendedTime} = isless(x, T(y)) -Base.:≤(x::InfExtendedTime, y::InfExtendedTime) = !(y < x) Base.:≤(x::Infinite, y::T) where {T<:InfExtendedTime} = T(x) ≤ y Base.:≤(x::T, y::Infinite) where {T<:InfExtendedTime} = x ≤ T(y) diff --git a/src/infextendedtime/conversion.jl b/src/infextendedtime/conversion.jl deleted file mode 100644 index b07ea16..0000000 --- a/src/infextendedtime/conversion.jl +++ /dev/null @@ -1,8 +0,0 @@ -Base.promote_rule(::Type{Infinite}, ::Type{S}) where {S<:TimeType} = S <: InfExtendedTime ? S : InfExtendedTime{S} -Base.promote_rule(::Type{InfExtendedTime{T}}, ::Type{InfExtendedTime{S}}) where {T<:TimeType, S<:TimeType} = InfExtendedTime(promote_type(T, S)) -Base.promote_rule(::Type{InfExtendedTime{T}}, ::Type{S}) where {T<:TimeType, S<:TimeType} = InfExtendedTime(promote_type(T, S)) -Base.promote_rule(::Type{InfExtendedTime{T}}, ::Type{Infinite}) where {T<:TimeType} = InfExtendedTime{T} - -Base.convert(::Type{T}, x::S) where {T<:InfExtendedTime, S<:TimeType} = T(x) -Base.convert(::Type{T}, x::InfExtendedTime) where {T<:InfExtendedTime} = T(x) -Base.convert(::Type{T}, x::Infinite) where {T<:InfExtendedTime} = T(x) diff --git a/src/infextendedtime/io.jl b/src/infextendedtime/io.jl deleted file mode 100644 index 633af32..0000000 --- a/src/infextendedtime/io.jl +++ /dev/null @@ -1,10 +0,0 @@ -function Base.show(io::IO, x::T) where {T<:InfExtendedTime} - value = isposinf(x) ? ∞ : isneginf(x) ? -∞ : x.finitevalue - if get(io, :compact, false) - print(io, value) - else - print(io, "$T(") - show(io, value) - print(io, ")") - end -end diff --git a/test/infextendedreal.jl b/test/infextendedreal.jl index e145806..10c34f9 100644 --- a/test/infextendedreal.jl +++ b/test/infextendedreal.jl @@ -49,7 +49,7 @@ end @testset "Conversion" begin - @test promote_rule(Infinite, Float64) === InfExtendedReal(Float64) + @test promote_rule(Infinite, Float64) === InfExtendedReal{Float64} @test promote_rule(InfExtendedReal{Int64}, InfExtendedReal{Float64}) === Float64 @test promote_rule(InfExtendedReal{Int32}, InfExtendedReal{Int64}) === InfExtendedReal{Int64} @@ -113,13 +113,13 @@ @testset "arithmetic" begin @inferred -∞ @inferred InfExtendedReal 2 + ∞ - @inferred ∞ + 2.3 + @inferred InfExtendedReal ∞ + 2.3 @test_throws InfMinusInfError ∞+(-∞) @inferred InfExtendedReal 10 - ∞ @inferred InfExtendedReal 10.0 - ∞ @test_throws InfMinusInfError ∞-∞ @inferred InfExtendedReal 2 * ∞ - @inferred ∞ * 1.0 + @inferred InfExtendedReal ∞ * 1.0 @test_throws DivideError ∞ * 0 @inferred Float64 1 / ∞ @inferred Float64 1.2 / ∞ From 4ddf44c706c40c2452e9f98b85c7c73cac7d0fdd Mon Sep 17 00:00:00 2001 From: Fernando Chorney Date: Mon, 15 Jun 2020 15:29:32 -0500 Subject: [PATCH 2/3] Bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index e1b5d36..f5202e8 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Infinity" uuid = "a303e19e-6eb4-11e9-3b09-cd9505f79100" authors = ["Christopher Doris "] -version = "0.2.0" +version = "0.2.1" [deps] Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" From 0bb28e2ed0c80b198acedf8309c76f13fb7881ac Mon Sep 17 00:00:00 2001 From: Fernando Chorney Date: Tue, 16 Jun 2020 14:05:19 -0500 Subject: [PATCH 3/3] Add `instant` accessfor for InfExtendedTime --- src/Infinity.jl | 2 +- src/infextendedtime/arithmetic.jl | 10 +++++----- src/infextendedtime/base.jl | 12 ++++++++++++ test/infextendedtime.jl | 17 ++++++++++++++++- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/Infinity.jl b/src/Infinity.jl index 189352c..b7a9d34 100644 --- a/src/Infinity.jl +++ b/src/Infinity.jl @@ -1,6 +1,6 @@ module Infinity -using Dates: Period, TimeType +using Dates: Period, TimeType, UTInstant export Infinite, PosInf, NegInf, ∞, InfMinusInfError, InfExtendedReal, InfExtendedTime diff --git a/src/infextendedtime/arithmetic.jl b/src/infextendedtime/arithmetic.jl index 8f916b0..1338756 100644 --- a/src/infextendedtime/arithmetic.jl +++ b/src/infextendedtime/arithmetic.jl @@ -5,12 +5,12 @@ Base.:+(x::S, y::T) where {T<:InfExtendedTime, S<:Period} = y + x Base.:-(x::T, y::S) where {T<:InfExtendedTime, S<:Period} = x + -y Base.:-(x::S, y::T) where {T<:InfExtendedTime, S<:Period} = isposinf(y) ? neginf(T) : y + -x -for TType in (TimeType, Period) +for TType in (TimeType, Period, UTInstant) @eval begin Base.:+(x::Infinite, y::T) where {T<:$TType} = x Base.:+(x::T, y::Infinite) where {T<:$TType} = y Base.:-(x::Infinite, y::T) where {T<:$TType} = x - Base.:-(x::T, y::Infinite) where {T<:$TType} = y + Base.:-(x::T, y::Infinite) where {T<:$TType} = Infinite(!y.signbit) end end @@ -18,7 +18,7 @@ function Base.:+(x::T, y::Infinite) where {T<:InfExtendedTime} if isfinite(x) return T(y) else - val = x.flag == POSINF ? ∞ : -∞ + val = isposinf(x) ? ∞ : -∞ return T(val + y) end end @@ -27,7 +27,7 @@ function Base.:-(x::T, y::Infinite) where {T<:InfExtendedTime} if isfinite(x) return T(-y) else - val = x.flag == POSINF ? ∞ : -∞ + val = isposinf(x) ? ∞ : -∞ return T(val - y) end end @@ -35,7 +35,7 @@ function Base.:-(x::Infinite, y::T) where {T<:InfExtendedTime} if isfinite(y) return T(x) else - val = y.flag == POSINF ? ∞ : -∞ + val = isposinf(y) ? ∞ : -∞ return T(x - val) end end diff --git a/src/infextendedtime/base.jl b/src/infextendedtime/base.jl index 716ef72..1e56c2f 100644 --- a/src/infextendedtime/base.jl +++ b/src/infextendedtime/base.jl @@ -11,6 +11,18 @@ struct InfExtendedTime{T<:TimeType} <: TimeType InfExtendedTime{T}(x::Infinite) where {T<:TimeType} = new{T}(x==PosInf ? POSINF : NEGINF) end +function Base.getproperty(x::InfExtendedTime, s::Symbol) + if s === :instant + if isinf(x) + return isposinf(x) ? ∞ : -∞ + else + return x.finitevalue.instant + end + else + return getfield(x, s) + end +end + InfExtendedTime{T}(x::TimeType) where {T<:TimeType} = InfExtendedTime{T}(convert(T, x)) InfExtendedTime{T}(x::InfExtendedTime) where {T<:TimeType} = InfExtendedTime{T}(convert(T, x.finitevalue)) diff --git a/test/infextendedtime.jl b/test/infextendedtime.jl index 1baadf2..8e361ca 100644 --- a/test/infextendedtime.jl +++ b/test/infextendedtime.jl @@ -60,6 +60,11 @@ test_time = Time(1, 1, 1, 1) @test !isneginf(InfExtendedTime{DateTime}(∞)) @test isneginf(InfExtendedTime{DateTime}(-∞)) @test !isneginf(dt) + + inf = InfExtendedTime{Date}(∞) + @test d.instant == test_date.instant + @test t.instant == test_time.instant + @test inf.instant == ∞ end @testset "IO" begin @@ -184,6 +189,16 @@ test_time = Time(1, 1, 1, 1) @test ∞ + test_date == ∞ @test test_date + ∞ == ∞ @test ∞ - test_date == ∞ - @test test_date - ∞ == ∞ + @test test_date - ∞ == -∞ + + @test ∞ + Day(1) == ∞ + @test Day(1) + ∞ == ∞ + @test ∞ - Day(1) == ∞ + @test Day(1) - ∞ == -∞ + + @test ∞ + test_date.instant == ∞ + @test test_date.instant + ∞ == ∞ + @test ∞ - test_date.instant == ∞ + @test test_date.instant - ∞ == -∞ end end