@@ -94,14 +94,27 @@ known_length(::Type{<:Number}) = 1
94
94
known_length (:: Type{<:AbstractCartesianIndex{N}} ) where {N} = N
95
95
known_length (:: Type{T} ) where {T} = _maybe_known_length (Base. IteratorSize (T), T)
96
96
97
- @inline _prod_or_nothing (x, :: Tuple{} ) = x
98
- @inline _prod_or_nothing (_, :: Tuple{Nothing,Vararg} ) = nothing
99
- @inline _prod_or_nothing (x, y:: Tuple{I,Vararg} ) where {I} = _prod_or_nothing (x* first (y), Base. tail (y))
97
+ @generated function _prod_or_nothing (x:: Tuple )
98
+ p = 1
99
+ for i in eachindex (x. parameters)
100
+ x. parameters[i] === Nothing && return nothing
101
+ p *= x. parameters[i]. parameters[1 ]
102
+ end
103
+ StaticInt (p)
104
+ end
105
+
106
+ function _maybe_known_length (:: Base.HasShape , :: Type{T} ) where {T}
107
+ t = map (_static_or_nothing, known_size (T))
108
+ _int_or_nothing (_prod_or_nothing (t))
109
+ end
100
110
101
- _maybe_known_length (:: Base.HasShape , :: Type{T} ) where {T} = _prod_or_nothing (1 , known_size (T))
102
111
_maybe_known_length (:: Base.IteratorSize , :: Type ) = nothing
112
+ _static_or_nothing (:: Nothing ) = nothing
113
+ @inline _static_or_nothing (x:: Int ) = StaticInt {x} ()
114
+ _int_or_nothing (:: StaticInt{N} ) where {N} = N
115
+ _int_or_nothing (:: Nothing ) = nothing
103
116
function known_length (:: Type{<:Iterators.Flatten{I}} ) where {I}
104
- _prod_or_nothing (1 , ( known_length (I), known_length (eltype (I))))
117
+ _int_or_nothing ( _prod_or_nothing (( _static_or_nothing ( known_length (I)), _static_or_nothing ( known_length (eltype (I)) ))))
105
118
end
106
119
107
120
"""
0 commit comments