diff --git a/src/FixedPointNumbers.jl b/src/FixedPointNumbers.jl index fb99dc7..dad2ff1 100644 --- a/src/FixedPointNumbers.jl +++ b/src/FixedPointNumbers.jl @@ -49,7 +49,8 @@ reinterpret(::Type{X}, x::T) where {T <: Integer, X <: FixedPoint{T}} = X(x, 0) # static parameters nbitsfrac(::Type{X}) where {T, f, X <: FixedPoint{T,f}} = f -rawtype(::Type{X}) where {T, X <: FixedPoint{T}} = T +rawtype(::Type{X}) where {T <: Integer, X <: FixedPoint{T}} = T +rawtype(::Type{<:FixedPoint}) = Union{} # Don't care the constraints for `T` # traits based on static parameters signbits(::Type{X}) where {T, X <: FixedPoint{T}} = T <: Unsigned ? 0 : 1 @@ -539,15 +540,15 @@ promote_rule(::Type{X}, ::Type{Tr}) where {X <: FixedPoint, Tr <: Rational} = Tr promote_rule(::Type{X}, ::Type{Ti}) where {X <: FixedPoint, Ti <: Integer} = floattype(X) function promote_rule(::Type{X1}, ::Type{X2}) where {X1 <: FixedPoint, X2 <: FixedPoint} - (isconcretetype(X1) && isconcretetype(X2)) || return Union{} X1w, X2w = wrapper(X1), wrapper(X2) if X1w !== X2w - # X1w <: X2w && return X2w # for non-concrete types - # X2w <: X1w && return X1w # for non-concrete types + X1w <: X2w && return X2w + X2w <: X1w && return X1w return promote_type(floattype(X1), floattype(X2)) end X = X1w T1, T2 = rawtype(X1), rawtype(X2) + isconcretetype(T1) && isconcretetype(T2) || return X{promote_type(T1, T2)} f1, f2 = nbitsfrac(X1), nbitsfrac(X2) f = max(f1, f2) # ensure we have enough precision Tp = promote_type(T1, T2) diff --git a/test/traits.jl b/test/traits.jl index c248b4c..63d5646 100644 --- a/test/traits.jl +++ b/test/traits.jl @@ -1,5 +1,5 @@ using FixedPointNumbers, Test -using FixedPointNumbers: bitwidth +using FixedPointNumbers: bitwidth, rawtype struct MyReal <: Real end @@ -18,3 +18,13 @@ struct MyReal <: Real end @test_skip(@test_throws MethodError floattype(MyReal)) # TODO: eliminate `@test_skipped` when depwarn is eliminated. See #177. end + +@testset "rawtype" begin + @test rawtype(FixedPoint) === Union{} + @test rawtype(Normed) === Union{} + @test rawtype(Fixed) === Union{} + @test rawtype(Normed{<:Unsigned}) === Union{} + @test rawtype(Fixed{Union{Int8, Int16}}) === Union{Int8, Int16} + @test rawtype(N0f8) === UInt8 + @test rawtype(Q0f7) === Int8 +end