@@ -39,7 +39,9 @@ from_parent_dims(::Type{<:SubArray{T,N,A,I}}) where {T,N,A,I} = _from_sub_dims(A
3939 end
4040 out
4141end
42- from_parent_dims (:: Type{<:PermutedDimsArray{T,N,<:Any,I}} ) where {T,N,I} = static (Val (I))
42+ function from_parent_dims (:: Type{<:PermutedDimsArray{T,N,<:Any,I}} ) where {T,N,I}
43+ return _val_to_static (Val (I))
44+ end
4345
4446"""
4547 to_parent_dims(::Type{T}) -> Bool
@@ -49,7 +51,7 @@ Returns the mapping from child dimensions to parent dimensions.
4951to_parent_dims (x) = to_parent_dims (typeof (x))
5052to_parent_dims (:: Type{T} ) where {T} = nstatic (Val (ndims (T)))
5153to_parent_dims (:: Type{T} ) where {T<: Union{Transpose,Adjoint} } = (StaticInt (2 ), One ())
52- to_parent_dims (:: Type{<:PermutedDimsArray{T,N,I}} ) where {T,N,I} = static (Val (I))
54+ to_parent_dims (:: Type{<:PermutedDimsArray{T,N,I}} ) where {T,N,I} = _val_to_static (Val (I))
5355to_parent_dims (:: Type{<:SubArray{T,N,A,I}} ) where {T,N,A,I} = _to_sub_dims (A, I)
5456@generated function _to_sub_dims (:: Type{A} , :: Type{I} ) where {A,N,I<: Tuple{Vararg{Any,N}} }
5557 out = Expr (:tuple )
@@ -77,35 +79,18 @@ function has_dimnames(::Type{T}) where {T}
7779 end
7880end
7981
80- # this takes the place of dimension names that aren't defined
81- const SUnderscore = StaticSymbol (:_ )
82-
8382"""
84- dimnames(::Type{T}) -> Tuple{Vararg{StaticSymbol }}
85- dimnames(::Type{T}, dim ) -> StaticSymbol
83+ dimnames(::Type{T}) -> Tuple{Vararg{Symbol }}
84+ dimnames(::Type{T}, d ) -> Symbol
8685
8786Return the names of the dimensions for `x`.
8887"""
8988@inline dimnames (x) = dimnames (typeof (x))
90- @inline dimnames (x, dim:: Int ) = dimnames (typeof (x), dim)
91- @inline dimnames (x, dim:: StaticInt ) = dimnames (typeof (x), dim)
92- @inline function dimnames (:: Type{T} , :: StaticInt{dim} ) where {T,dim}
93- if ndims (T) < dim
94- return SUnderscore
95- else
96- return getfield (dimnames (T), dim)
97- end
98- end
99- @inline function dimnames (:: Type{T} , dim:: Int ) where {T}
100- if ndims (T) < dim
101- return SUnderscore
102- else
103- return getfield (dimnames (T), dim)
104- end
105- end
89+ @inline dimnames (x, i:: Integer ) = dimnames (typeof (x), i)
90+ @inline dimnames (:: Type{T} , d:: Integer ) where {T} = getfield (dimnames (T), to_dims (T, d))
10691@inline function dimnames (:: Type{T} ) where {T}
10792 if parent_type (T) <: T
108- return ntuple (_ -> SUnderscore , Val (ndims (T)))
93+ return ntuple (i -> :_ , Val (ndims (T)))
10994 else
11095 return dimnames (parent_type (T))
11196 end
@@ -116,15 +101,15 @@ end
116101# inserting the Val here seems to help inferability; I got a test failure without it.
117102function _transpose_dimnames (:: Val{S} ) where {S}
118103 if length (S) == 1
119- (SUnderscore , first (S))
104+ (:_ , first (S))
120105 elseif length (S) == 2
121106 (last (S), first (S))
122107 else
123108 throw (" Can't transpose $S of dim $(length (S)) ." )
124109 end
125110end
126111@inline _transpose_dimnames (x:: Tuple{Symbol,Symbol} ) = (last (x), first (x))
127- @inline _transpose_dimnames (x:: Tuple{Symbol} ) = (SUnderscore , first (x))
112+ @inline _transpose_dimnames (x:: Tuple{Symbol} ) = (:_ , first (x))
128113
129114@inline function dimnames (:: Type{T} ) where {I,T<: PermutedDimsArray{<:Any,<:Any,I} }
130115 return map (i -> dimnames (parent_type (T), i), I)
138123 for i in 1 : length (I)
139124 if I[i] > 0
140125 if nl < i
141- push! (e. args, :(ArrayInterface . SUnderscore ))
126+ push! (e. args, QuoteNode ( :_ ))
142127 else
143128 push! (e. args, QuoteNode (L[i]))
144129 end
@@ -147,108 +132,58 @@ end
147132 return e
148133end
149134
150- _to_int (x:: Integer ) = Int (x)
151- _to_int (x:: StaticInt ) = x
152-
153- function no_dimname_error (@nospecialize (x), @nospecialize (dim))
154- throw (ArgumentError (" ($(repr (dim)) ) does not correspond to any dimension of ($(x) )" ))
155- end
156-
157135"""
158- to_dims(::Type{T}, dim) -> Integer
136+ to_dims(x[, d])
159137
160138This returns the dimension(s) of `x` corresponding to `d`.
161139"""
162- to_dims (x, dim) = to_dims (typeof (x), dim)
163- to_dims (:: Type{T} , dim:: Integer ) where {T} = _to_int (dim)
164- to_dims (:: Type{T} , dim:: Colon ) where {T} = dim
165- function to_dims (:: Type{T} , dim:: StaticSymbol ) where {T}
166- i = find_first_eq (dim, dimnames (T))
167- i === nothing && no_dimname_error (T, dim)
140+ to_dims (x, d) = to_dims (dimnames (x), d)
141+ to_dims (x:: Tuple{Vararg{Symbol}} , d:: Integer ) = Int (d)
142+ to_dims (x:: Tuple{Vararg{Symbol}} , d:: Colon ) = d # `:` is the default for most methods that take `dims`
143+ @inline to_dims (x:: Tuple{Vararg{Symbol}} , d:: Tuple ) = map (i -> to_dims (x, i), d)
144+ @inline function to_dims (x:: Tuple{Vararg{Symbol}} , d:: Symbol ):: Int
145+ i = _sym_to_dim (x, d)
146+ if i === 0
147+ throw (ArgumentError (" Specified name ($(repr (d)) ) does not match any dimension name ($(x) )" ))
148+ end
168149 return i
169150end
170- @inline function to_dims (:: Type{T} , dim:: Symbol ) where {T}
171- i = find_first_eq (dim, Symbol .(dimnames (T)))
172- i === nothing && no_dimname_error (T, dim)
173- return i
151+ Base. @pure function _sym_to_dim (x:: Tuple{Vararg{Symbol,N}} , sym:: Symbol ) where {N}
152+ for i in 1 : N
153+ getfield (x, i) === sym && return i
154+ end
155+ return 0
174156end
175- #=
176- return i
177- i = 1
178- out = 0
179- for s in dimnames(T)
180- if Symbol(s) === dim
181- out = i
182- break
183- else
184- i += i
157+
158+ """
159+ tuple_issubset
160+
161+ A version of `issubset` sepecifically for `Tuple`s of `Symbol`s, that is `@pure`.
162+ This helps it get optimised out of existance. It is less of an abuse of `@pure` than
163+ most of the stuff for making `NamedTuples` work.
164+ """
165+ Base. @pure function tuple_issubset (
166+ lhs:: Tuple{Vararg{Symbol,N}} , rhs:: Tuple{Vararg{Symbol,M}}
167+ ) where {N,M}
168+ N <= M || return false
169+ for a in lhs
170+ found = false
171+ for b in rhs
172+ found |= a === b
185173 end
174+ found || return false
186175 end
187- if out === 0
188- no_dimname_error(T, dim)
189- end
190- return out
176+ return true
191177end
192- =#
193178
194- to_dims (:: Type{T} , dims:: Tuple ) where {T} = map (i -> to_dims (T, i), dims)
195- #=
196- order_named_inds(names, namedtuple)
197- order_named_inds(names, subnames, inds)
179+ """
180+ order_named_inds(Val(names); kwargs...)
181+ order_named_inds(Val(names), namedtuple)
198182
199183Returns the tuple of index values for an array with `names`, when indexed by keywords.
200184Any dimensions not fixed are given as `:`, to make a slice.
201185An error is thrown if any keywords are used which do not occur in `nda`'s names.
202-
203-
204- 1. parse into static dimnension names and key words.
205- 2. find each dimnames in key words
206- 3. if nothing is found use Colon()
207- 4. if (ndims - ncolon) === nkwargs then all were found, else error
208- =#
209- order_named_inds (x:: Tuple , :: NamedTuple{(),Tuple{}} ) = ()
210- function order_named_inds (x:: Tuple , nd:: NamedTuple{L} ) where {L}
211- return order_named_inds (x, static (Val (L)), Tuple (nd))
212- end
213- function order_named_inds (x:: Tuple{Vararg{Any,N}} , nd:: Tuple , inds:: Tuple ) where {N}
214- out = eachop (((x, nd, inds), i) -> order_named_inds (x, nd, inds, i), (x, nd, inds), nstatic (Val (N)))
215- _order_named_inds_check (out, length (nd))
216- return out
217- end
218- function order_named_inds (x:: Tuple , nd:: Tuple , inds:: Tuple , :: StaticInt{dim} ) where {dim}
219- index = find_first_eq (getfield (x, dim), nd)
220- if index === nothing
221- return Colon ()
222- else
223- return @inbounds (inds[index])
224- end
225- end
226-
227- ncolon (x:: Tuple{Colon,Vararg} , n:: Int ) = ncolon (tail (x), n + 1 )
228- ncolon (x:: Tuple{Any,Vararg} , n:: Int ) = ncolon (tail (x), n)
229- ncolon (x:: Tuple{Colon} , n:: Int ) = n + 1
230- ncolon (x:: Tuple{Any} , n:: Int ) = n
231- function _order_named_inds_check (inds:: Tuple{Vararg{Any,N}} , nkwargs:: Int ) where {N}
232- if (N - ncolon (inds, 0 )) != = nkwargs
233- error (" Not all keywords matched dimension names." )
234- end
235- return nothing
236- end
237-
238-
239- #=
240- name_to_idx(name::StaticSymbol, kwargs::Tuple, inds::Tuple, )
241- name_to_idx(name::StaticSymbol, kwargs::Tuple, inds::Tuple) = _name_to_index(find_first_eq(), inds)
242- _name_to_index(::Zero, ::Tuple) = Colon()
243- _name_to_index(::StaticInt{N}, inds::Tuple) where {N} = getfield(inds, N)
244-
245- # return permute(inds, static_find_all_in(nd, x))
246- _colon_or_inds(inds::Tuple, ::Zero) = :
247- _colon_or_inds(inds::Tuple, ::StaticInt{I}) where {I} = getfield(inds, I)
248-
249- n_i -> _colon_or_inds(inds, find_first_eq(n_i, x))
250- # FIXME this needs to insert a colon on missing names
251-
186+ """
252187@inline function order_named_inds (val:: Val{L} ; kwargs... ) where {L}
253188 if isempty (kwargs)
254189 return ()
268203 end
269204 return Expr (:tuple , exs... )
270205end
271- =#
272-
273206@generated function _perm_tuple (:: Type{T} , :: Val{P} ) where {T,P}
274207 out = Expr (:curly , :Tuple )
275208 for p in P
378311 Expr (:block , Expr (:meta , :inline ), out)
379312end
380313
314+
315+
381316"""
382317 size(A)
383318
@@ -395,7 +330,12 @@ julia> ArrayInterface.size(A)
395330@inline size (A) = Base. size (A)
396331@inline size (A, d:: Integer ) = size (A)[Int (d)]
397332@inline size (A, d) = Base. size (A, to_dims (A, d))
398- @inline size (x:: VecAdjTrans ) = (One (), static_length (x))
333+ @inline function size (x:: LinearAlgebra.Adjoint{T,V} ) where {T,V<: AbstractVector{T} }
334+ return (One (), static_length (x))
335+ end
336+ @inline function size (x:: LinearAlgebra.Transpose{T,V} ) where {T,V<: AbstractVector{T} }
337+ return (One (), static_length (x))
338+ end
399339
400340function size (B:: S ) where {N,NP,T,A<: AbstractArray{T,NP} ,I,S<: SubArray{T,N,A,I} }
401341 return _size (size (parent (B)), B. indices, map (static_length, B. indices))
0 commit comments