@@ -45,29 +45,43 @@ StructArrays.component(s::FieldArray, i) = invoke(StructArrays.component, Tuple{
4545StructArrays. createinstance (T:: Type{<:FieldArray} , args... ) = invoke (StructArrays. createinstance, Tuple{Type{<: Any }, Vararg}, T, args... )
4646
4747# Broadcast overload
48- @loadext using StaticArrays: StaticArrayStyle, similar_type
48+ @loadext using StaticArrays: StaticArrayStyle, similar_type, Size, SOneTo
49+ @loadext using StaticArrays: broadcast_flatten, broadcast_sizes, first_statictype, __broadcast
4950@loadext using StructArrays: isnonemptystructtype
5051using Base. Broadcast: Broadcasted
5152
5253# StaticArrayStyle has no similar defined.
5354# Overload `try_struct_copy` instead.
5455@inline function StructArrays. try_struct_copy (bc:: Broadcasted{StaticArrayStyle{M}} ) where {M}
55- sa = copy (bc)
56- ET = eltype (sa)
57- isnonemptystructtype (ET) || return sa
58- elements = Tuple (sa)
59- @static if VERSION >= v " 1.7"
60- arrs = ntuple (Val (fieldcount (ET))) do i
61- similar_type (sa, fieldtype (ET, i))(_getfields (elements, i))
62- end
56+ flat = broadcast_flatten (bc); as = flat. args; f = flat. f
57+ argsizes = broadcast_sizes (as... )
58+ ax = axes (bc)
59+ ax isa Tuple{Vararg{SOneTo}} || error (" Dimension is not static. Please file a bug." )
60+ return _broadcast (f, Size (map (length, ax)), argsizes, as... )
61+ end
62+
63+ @inline function _broadcast (f, sz:: Size{newsize} , s:: Tuple{Vararg{Size}} , a... ) where {newsize}
64+ first_staticarray = first_statictype (a... )
65+ elements, ET = if prod (newsize) == 0
66+ # Use inference to get eltype in empty case (see also comments in _map)
67+ eltys = Tuple{map (eltype, a)... }
68+ (), Core. Compiler. return_type (f, eltys)
6369 else
64- _fieldtype (:: Type{T} ) where {T} = i -> fieldtype (T, i)
65- __fieldtype = _fieldtype (ET)
66- arrs = ntuple (Val (fieldcount (ET))) do i
67- similar_type (sa, __fieldtype (i))(_getfields (elements, i))
68- end
70+ temp = __broadcast (f, sz, s, a... )
71+ temp, eltype (temp)
72+ end
73+ if isnonemptystructtype (ET)
74+ @static if VERSION >= v " 1.7"
75+ arrs = ntuple (Val (fieldcount (ET))) do i
76+ @inbounds similar_type (first_staticarray, fieldtype (ET, i), sz)(_getfields (elements, i))
77+ end
78+ else
79+ similarET (:: Type{SA} , :: Type{T} ) where {SA, T} = i -> @inbounds similar_type (SA, fieldtype (T, i), sz)(_getfields (elements, i))
80+ arrs = ntuple (similarET (first_staticarray, ET), Val (fieldcount (ET)))
81+ end
82+ return StructArray {ET} (arrs)
6983 end
70- return StructArray {ET} (arrs )
84+ @inbounds return similar_type (first_staticarray, ET, sz)(elements )
7185end
7286
7387@inline function _getfields (x:: Tuple , i:: Int )
0 commit comments