From b4188c83155bbde70f081617c6edc654738b98d6 Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Fri, 17 Apr 2020 16:50:50 +1000 Subject: [PATCH] Widening-based map() to remove return_type --- src/mapreduce.jl | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/mapreduce.jl b/src/mapreduce.jl index 890fb24..b5537d4 100644 --- a/src/mapreduce.jl +++ b/src/mapreduce.jl @@ -1,8 +1,32 @@ function Base.map(f, a::StaticArrayLite) - T = Core.Compiler.return_type(f, Tuple{eltype(a)}) - out = similar(a, T, size(a)) - map!(f, out, a) - return freeze(out) + if length(a) == 0 + T = Core.Compiler.return_type(f, Tuple{eltype(a)}) + return freeze(similar(a, T, size(a))) + end + @inbounds x = f(a[first(LinearIndices(a))]) + out = similar(a, typeof(x), size(a)) + freeze(_map_widen!(out, 0, x, f, a)) +end + +function _map_widen!(out, offset, x, f, a) + a_i1 = first(LinearIndices(a)) + out_i1 = first(LinearIndices(out)) + T = eltype(out) + while true + @inbounds out[out_i1+offset] = x + offset += 1 + if offset >= length(a) + break + end + @inbounds x = f(a[a_i1+offset]) + if !(typeof(x) === T || x isa T) + T2 = Base.promote_typejoin(T, typeof(x)) + out2 = similar(a, T2, size(a)) + copyto!(out2, out_i1, out, out_i1, offset) + return _map_widen!(out2, ) + end + end + return out end function Base.map(f, a::StaticArrayLite, b::StaticArrayLite) @@ -44,4 +68,4 @@ function Base.mapreduce(f, op, a::StaticArrayLite, b::StaticArrayLite; init) out = op(f(@inbounds(a[i]),@inbounds(b[i])), out) end return out -end \ No newline at end of file +end