From 0a7800908f722858db8ac13ec0e126501835ec6f Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Thu, 2 Nov 2017 07:22:41 +1000 Subject: [PATCH] Use promotion rather than typejoin to infer map/broadcast output eltype This allows `Union`s as the output type for mixtures of `Null` and numeric types, which can be more efficient than the `Any` you'd get from typejoin, at least in 0.7. It also makes `SVectors` of abstract types like `Number` become concrete after numerical operations, which is inconsistent with base, but probably not a problem for realisitc uses of this package. --- src/broadcast.jl | 2 +- src/mapreduce.jl | 4 ++-- test/broadcast.jl | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/broadcast.jl b/src/broadcast.jl index 46bb33e2..22ac5a1a 100644 --- a/src/broadcast.jl +++ b/src/broadcast.jl @@ -105,7 +105,7 @@ end return quote @_inline_meta elements = tuple($(exprs...)) - @inbounds return similar_type($first_staticarray, eltype(elements), Size($newsize))(elements) + @inbounds return similar_type($first_staticarray, promote_tuple_eltype(elements), Size($newsize))(elements) end end diff --git a/src/mapreduce.jl b/src/mapreduce.jl index e1fd6f01..8ee56fc4 100644 --- a/src/mapreduce.jl +++ b/src/mapreduce.jl @@ -25,7 +25,7 @@ end return quote @_inline_meta elements = tuple($(exprs...)) - @inbounds return similar_type(typeof(_first(a...)), eltype(elements), Size(S))(elements) + @inbounds return similar_type(typeof(_first(a...)), promote_tuple_eltype(elements), Size(S))(elements) end end @@ -126,7 +126,7 @@ end return quote @_inline_meta elements = tuple($(exprs...)) - @inbounds return similar_type(a, eltype(elements), Size($Snew))(elements) + @inbounds return similar_type(a, promote_tuple_eltype(elements), Size($Snew))(elements) end end diff --git a/test/broadcast.jl b/test/broadcast.jl index f0540b7c..79f8cadd 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -134,16 +134,16 @@ end @testset "eltype after broadcast" begin # test cases issue #198 let a = SVector{4, Number}(2, 2.0, 4//2, 2+0im) - @test eltype(a + 2) == Number - @test eltype(a - 2) == Number - @test eltype(a * 2) == Number - @test eltype(a / 2) == Number + @test_broken eltype(a + 2) == Number + @test_broken eltype(a - 2) == Number + @test_broken eltype(a * 2) == Number + @test_broken eltype(a / 2) == Number end let a = SVector{3, Real}(2, 2.0, 4//2) - @test eltype(a + 2) == Real - @test eltype(a - 2) == Real - @test eltype(a * 2) == Real - @test eltype(a / 2) == Real + @test_broken eltype(a + 2) == Real + @test_broken eltype(a - 2) == Real + @test_broken eltype(a * 2) == Real + @test_broken eltype(a / 2) == Real end let a = SVector{3, Real}(2, 2.0, 4//2) @test eltype(a + 2.0) == Float64