@@ -27,8 +27,7 @@ size(a::Base.Broadcast.Broadcasted) = map(length, axes(a))
27
27
28
28
_maybe_size (:: Base.HasShape{N} , a:: A ) where {N,A} = map (length, axes (a))
29
29
_maybe_size (:: Base.HasLength , a:: A ) where {A} = (length (a),)
30
- size (x:: SubArray ) = eachop (_sub_size, to_parent_dims (x), x. indices)
31
- _sub_size (x:: Tuple , :: StaticInt{dim} ) where {dim} = length (getfield (x, dim))
30
+ @inline size (x:: SubArray ) = flatten_tuples (map (size, x. indices))
32
31
@inline size (B:: VecAdjTrans ) = (One (), length (parent (B)))
33
32
@inline size (B:: MatAdjTrans ) = permute (size (parent (B)), to_parent_dims (B))
34
33
@inline function size (B:: PermutedDimsArray{T,N,I1} ) where {T,N,I1}
@@ -58,6 +57,7 @@ size(x::Iterators.Pairs) = size(getfield(x, :itr))
58
57
@inline function size (x:: Iterators.ProductIterator )
59
58
eachop (_sub_size, ntuple (static, StaticInt (ndims (x))), getfield (x, :iterators ))
60
59
end
60
+ _sub_size (x:: Tuple , :: StaticInt{dim} ) where {dim} = length (getfield (x, dim))
61
61
62
62
size (a, dim) = size (a, to_dims (a, dim))
63
63
size (a:: Array , dim:: CanonicalInt ) = Base. arraysize (a, convert (Int, dim))
@@ -73,14 +73,6 @@ function size(a::A, dim::CanonicalInt) where {A}
73
73
end
74
74
end
75
75
end
76
- function size (A:: SubArray , dim:: CanonicalInt )
77
- pdim = to_parent_dims (A, dim)
78
- if pdim > ndims (parent_type (A))
79
- return size (parent (A), pdim)
80
- else
81
- return length (A. indices[pdim])
82
- end
83
- end
84
76
size (x:: Iterators.Zip ) = Static. reduce_tup (promote_shape, map (size, getfield (x, :is )))
85
77
86
78
"""
@@ -92,6 +84,41 @@ compile time. If a dimension does not have a known size along a dimension then `
92
84
returned in its position.
93
85
"""
94
86
known_size (x) = known_size (typeof (x))
87
+ @inline known_size (@nospecialize T:: Type{<:Number} ) = ()
88
+ @inline known_size (@nospecialize T:: Type{<:VecAdjTrans} ) = (1 , known_length (parent_type (T)))
89
+ @inline function known_size (@nospecialize T:: Type{<:MatAdjTrans} )
90
+ s1, s2 = known_size (parent_type (T))
91
+ (s2, s1)
92
+ end
93
+ function known_size (@nospecialize T:: Type{<:Diagonal} )
94
+ s = known_length (parent_type (T))
95
+ (s, s)
96
+ end
97
+ known_size (@nospecialize T:: Type{<:Union{Symmetric,Hermitian}} ) = known_size (parent_type (T))
98
+ @inline function known_size (:: Type{<:Base.ReinterpretArray{T,N,S,A,IsReshaped}} ) where {T,N,S,A,IsReshaped}
99
+ psize = known_size (A)
100
+ if IsReshaped
101
+ if sizeof (S) > sizeof (T)
102
+ return (div (sizeof (S), sizeof (T)), psize... )
103
+ elseif sizeof (S) < sizeof (T)
104
+ return Base. tail (psize)
105
+ else
106
+ return psize
107
+ end
108
+ else
109
+ if Base. issingletontype (T) || first (psize) === nothing
110
+ return psize
111
+ else
112
+ return (div (first (psize) * sizeof (S), sizeof (T)), Base. tail (psize)... )
113
+ end
114
+ end
115
+ end
116
+
117
+ @inline function known_size (:: Type{<:PermutedDimsArray{<:Any,N,I1,<:Any,P}} ) where {N,I1,P}
118
+ sz = known_size (P)
119
+ ntuple (i -> getfield (sz, getfield (I1, i)), Val {N} ())
120
+ end
121
+
95
122
@inline function known_size (:: Type{T} ) where {T}
96
123
if is_forwarding_wrapper (T)
97
124
return known_size (parent_type (T))
@@ -103,17 +130,31 @@ function _maybe_known_size(::Base.HasShape{N}, ::Type{T}) where {N,T}
103
130
eachop (_known_size, ntuple (static, StaticInt (N)), axes_types (T))
104
131
end
105
132
_maybe_known_size (:: Base.IteratorSize , :: Type{T} ) where {T} = (known_length (T),)
106
- function known_size (:: Type{T} ) where {T<: AbstractRange }
107
- (_range_length (known_first (T), known_step (T), known_last (T)),)
108
- end
109
133
known_size (:: Type{<:Base.IdentityUnitRange{I}} ) where {I} = known_size (I)
110
134
known_size (:: Type{<:Base.Generator{I}} ) where {I} = known_size (I)
111
135
known_size (:: Type{<:Iterators.Reverse{I}} ) where {I} = known_size (I)
112
136
known_size (:: Type{<:Iterators.Enumerate{I}} ) where {I} = known_size (I)
113
137
known_size (:: Type{<:Iterators.Accumulate{<:Any,I}} ) where {I} = known_size (I)
114
138
known_size (:: Type{<:Iterators.Pairs{<:Any,<:Any,I}} ) where {I} = known_size (I)
115
139
@inline function known_size (:: Type{<:Iterators.ProductIterator{T}} ) where {T}
116
- eachop (_known_size, ntuple (static, StaticInt (known_length (T))), T)
140
+ ntuple (i -> known_length (T. parameters[i]), Val (known_length (T)))
141
+ end
142
+ @inline function known_size (@nospecialize T:: Type{<:AbstractRange} )
143
+ if is_forwarding_wrapper (T)
144
+ return known_size (parent_type (T))
145
+ else
146
+ return (_range_length (known_first (T), known_step (T), known_last (T)),)
147
+ end
148
+ end
149
+ @inline function known_size (@nospecialize T:: Type{<:Union{LinearIndices,CartesianIndices}} )
150
+ I = fieldtype (T, :indices )
151
+ ntuple (i -> known_length (I. parameters[i]), Val (ndims (T)))
152
+ end
153
+ @inline function known_size (@nospecialize T:: Type{<:SubArray} )
154
+ _known_sub_sizes (fieldtype (T, :indices ))
155
+ end
156
+ @inline function _known_sub_sizes (T:: Type{<:Tuple} )
157
+ flatten_tuples (ntuple (i -> known_size (T. parameters[i]), Val (known_length (T))))
117
158
end
118
159
119
160
# 1. `Zip` doesn't check that its collections are compatible (same size) at construction,
0 commit comments