@@ -11,23 +11,37 @@ Implementation detail. Do not use.
1111"""
1212struct Internal end
1313
14- struct FixedSizeArray{T,N} <: DenseArray{T,N}
15- mem:: Memory{T}
14+ struct FixedSizeArray{T,N,Mem <: GenericMemory{<:Any,T} } <: DenseArray{T,N}
15+ mem:: Mem
1616 size:: NTuple{N,Int}
17- function FixedSizeArray {T,N} (:: Internal , mem:: Memory{T} , size:: NTuple{N,Int} ) where {T,N}
18- new {T,N} (mem, size)
17+ function FixedSizeArray {T,N,M } (:: Internal , mem:: M , size:: NTuple{N,Int} ) where {T,N,M <: GenericMemory{<:Any,T} }
18+ new {T,N,M } (mem, size)
1919 end
2020end
2121
2222const FixedSizeVector{T} = FixedSizeArray{T,1 }
2323const FixedSizeMatrix{T} = FixedSizeArray{T,2 }
2424
25- function FixedSizeArray {T,N} (:: UndefInitializer , size:: NTuple{N,Int} ) where {T,N}
26- FixedSizeArray {T,N} (Internal (), Memory {T} (undef, checked_dims (size)), size)
25+ const default_underlying_storage_type = Memory
26+
27+ function FixedSizeArray {T,N,V} (:: UndefInitializer , size:: NTuple{N,Int} ) where {T,N,V}
28+ FixedSizeArray {T,N,V} (Internal (), V (undef, checked_dims (size)):: V , size)
2729end
28- function FixedSizeArray {T,N} (:: UndefInitializer , size:: NTuple{N,Integer} ) where {T,N}
30+ function FixedSizeArray {T,N,V } (:: UndefInitializer , size:: NTuple{N,Integer} ) where {T,N,V }
2931 ints = map (Int, size):: NTuple{N,Int} # prevent infinite recursion
30- FixedSizeArray {T,N} (undef, ints)
32+ FixedSizeArray {T,N,V} (undef, ints)
33+ end
34+ function FixedSizeArray {T,N,V} (:: UndefInitializer , size:: Vararg{Integer,N} ) where {T,N,V}
35+ FixedSizeArray {T,N,V} (undef, size)
36+ end
37+ function FixedSizeArray {T,<:Any,V} (:: UndefInitializer , size:: NTuple{N,Integer} ) where {T,N,V}
38+ FixedSizeArray {T,N,V} (undef, size)
39+ end
40+ function FixedSizeArray {T,<:Any,V} (:: UndefInitializer , size:: Vararg{Integer,N} ) where {T,N,V}
41+ FixedSizeArray {T,N,V} (undef, size)
42+ end
43+ function FixedSizeArray {T,N} (:: UndefInitializer , size:: NTuple{N,Integer} ) where {T,N}
44+ FixedSizeArray {T,N,default_underlying_storage_type{T}} (undef, size)
3145end
3246function FixedSizeArray {T,N} (:: UndefInitializer , size:: Vararg{Integer,N} ) where {T,N}
3347 FixedSizeArray {T,N} (undef, size)
@@ -45,8 +59,8 @@ Base.@propagate_inbounds Base.setindex!(A::FixedSizeArray, v, i::Int) = A.mem[i]
4559
4660Base. size (a:: FixedSizeArray ) = a. size
4761
48- function Base. similar (:: FixedSizeArray , :: Type{S } , size:: NTuple{N,Int} ) where {S ,N}
49- FixedSizeArray {S,N} (undef, size)
62+ function Base. similar (:: T , :: Type{E } , size:: NTuple{N,Int} ) where {T <: FixedSizeArray ,E ,N}
63+ with_replaced_parameters (DenseArray, T, Val (E), Val (N)) (undef, size)
5064end
5165
5266Base. isassigned (a:: FixedSizeArray , i:: Int ) = isassigned (a. mem, i)
8397
8498# broadcasting
8599
86- function Base. BroadcastStyle (:: Type{<:FixedSizeArray} )
87- Broadcast. ArrayStyle {FixedSizeArray } ()
100+ function Base. BroadcastStyle (:: Type{T} ) where {T <: FixedSizeArray }
101+ Broadcast. ArrayStyle {stripped_type(DenseArray, T) } ()
88102end
89103
90104function Base. similar (
91- bc:: Broadcast.Broadcasted{Broadcast.ArrayStyle{FixedSizeArray }} ,
105+ bc:: Broadcast.Broadcasted{Broadcast.ArrayStyle{S }} ,
92106 :: Type{E} ,
93- ) where {E}
94- similar (FixedSizeArray {E}, axes (bc))
107+ ) where {S <: FixedSizeArray , E}
108+ similar (S {E}, axes (bc))
95109end
96110
97111# helper functions
98112
113+ normalized_type (:: Type{T} ) where {T} = T
114+
115+ function stripped_type_unchecked (:: Type{DenseVector} , :: Type{<:GenericMemory{K,<:Any,AS}} ) where {K,AS}
116+ GenericMemory{K,<: Any ,AS}
117+ end
118+
119+ Base. @assume_effects :consistent function stripped_type_unchecked (
120+ :: Type{DenseArray} , :: Type{<:FixedSizeArray{<:Any,<:Any,V}} ,
121+ ) where {V}
122+ U = stripped_type (DenseVector, V)
123+ FixedSizeArray{E,N,U{E}} where {E,N}
124+ end
125+
126+ function stripped_type (:: Type{T} , :: Type{S} ) where {T,S<: T }
127+ ret = stripped_type_unchecked (T, S):: Type{<:T} :: UnionAll
128+ S:: Type{<:ret}
129+ normalized_type (ret) # ensure `UnionAll` type variable order is normalized
130+ end
131+
132+ function with_replaced_parameters (:: Type{T} , :: Type{S} , :: Val{P1} , :: Val{P2} ) where {T,S<: T ,P1,P2}
133+ t = T{P1,P2}:: Type{<:T}
134+ s = stripped_type (T, S)
135+ S:: Type{<:s}
136+ s{P1,P2}:: Type{<:s} :: Type{<:T} :: Type{<:t}
137+ end
138+
99139dimension_count_of (:: Base.SizeUnknown ) = 1
100140dimension_count_of (:: Base.HasLength ) = 1
101141dimension_count_of (:: Base.HasShape{N} ) where {N} = convert (Int, N):: Int
@@ -115,23 +155,49 @@ function check_count_value(n)
115155 throw (ArgumentError (" count must be an `Int`" ))
116156end
117157
118- struct SpecFSA{T,N} end
158+ # TODO : use `SpecFSA` for implementing each `FixedSizeArray` constructor?
159+ struct SpecFSA{N,Mem<: GenericMemory } end
119160function fsa_spec_from_type (:: Type{FixedSizeArray} )
120- SpecFSA {nothing,nothing } ()
161+ SpecFSA {nothing,default_underlying_storage_type } ()
121162end
122163function fsa_spec_from_type (:: Type{FixedSizeArray{<:Any,M}} ) where {M}
123164 check_count_value (M)
124- SpecFSA {nothing,M } ()
165+ SpecFSA {M,default_underlying_storage_type } ()
125166end
126167function fsa_spec_from_type (:: Type{FixedSizeArray{E}} ) where {E}
127- SpecFSA {E::Type,nothing} ()
168+ E:: Type
169+ SpecFSA {nothing,default_underlying_storage_type{E}} ()
128170end
129171function fsa_spec_from_type (:: Type{FixedSizeArray{E,M}} ) where {E,M}
130172 check_count_value (M)
131- SpecFSA {E::Type,M} ()
173+ E:: Type
174+ SpecFSA {M,default_underlying_storage_type{E}} ()
175+ end
176+ function fsa_spec_from_type (:: Type{FixedSizeArray{E,<:Any,V}} ) where {E,V}
177+ E:: Type
178+ V:: Type{<:DenseVector{E}}
179+ SpecFSA {nothing,V} ()
180+ end
181+ function fsa_spec_from_type (:: Type{FixedSizeArray{E,M,V}} ) where {E,M,V}
182+ check_count_value (M)
183+ E:: Type
184+ V:: Type{<:DenseVector{E}}
185+ SpecFSA {M,V} ()
186+ end
187+ for V ∈ (Memory, AtomicMemory)
188+ T = FixedSizeArray{E,M,V{E}} where {E,M}
189+ @eval begin
190+ function fsa_spec_from_type (:: Type{$T} )
191+ SpecFSA {nothing,$V} ()
192+ end
193+ function fsa_spec_from_type (:: Type{($T){<:Any,M}} ) where {M}
194+ check_count_value (M)
195+ SpecFSA {M,$V} ()
196+ end
197+ end
132198end
133199
134- parent_type (:: Type{<:FixedSizeArray{T}} ) where {T} = Memory{T}
200+ parent_type (:: Type{<:FixedSizeArray{<:Any,<:Any, T}} ) where {T} = T
135201
136202underlying_storage (m) = m
137203underlying_storage (f:: FixedSizeArray ) = f. mem
@@ -140,19 +206,22 @@ axes_are_one_based(axes) = all(isone ∘ first, axes)
140206
141207# converting constructors for copying other array types
142208
143- function FixedSizeArray {T,N} (src:: AbstractArray{S,N} ) where {T,N,S}
209+ function FixedSizeArray {T,N,V } (src:: AbstractArray{S,N} ) where {T,N,V ,S}
144210 axs = axes (src)
145211 if ! axes_are_one_based (axs)
146212 throw (DimensionMismatch (" source array has a non-one-based indexing axis" ))
147213 end
148214 # Can't use `Base.size` because, according to it's doc string, it's not
149215 # available for all `AbstractArray` types.
150216 size = map (length, axs)
151- dst = FixedSizeArray {T,N} (undef, size)
217+ dst = FixedSizeArray {T,N,V } (undef, size)
152218 copyto! (dst. mem, src)
153219 dst
154220end
155221
222+ FixedSizeArray {T,<:Any,V} (a:: AbstractArray{<:Any,N} ) where {V,T,N} = FixedSizeArray {T,N,V} (a)
223+
224+ FixedSizeArray {T,N} (a:: AbstractArray{<:Any,N} ) where {T,N} = FixedSizeArray {T,N,default_underlying_storage_type{T}} (a)
156225FixedSizeArray {T} (a:: AbstractArray{<:Any,N} ) where {T,N} = FixedSizeArray {T,N} (a)
157226FixedSizeArray {<:Any,N} (a:: AbstractArray{T,N} ) where {T,N} = FixedSizeArray {T,N} (a)
158227FixedSizeArray (a:: AbstractArray{T,N} ) where {T,N} = FixedSizeArray {T,N} (a)
@@ -197,27 +266,29 @@ Base.elsize(::Type{A}) where {A<:FixedSizeArray} = Base.elsize(parent_type(A))
197266
198267# `reshape`: specializing it to ensure it returns a `FixedSizeArray`
199268
200- function Base. reshape (a:: FixedSizeArray{T} , size:: NTuple{N,Int} ) where {T,N}
269+ function Base. reshape (a:: FixedSizeArray{T,<:Any,V } , size:: NTuple{N,Int} ) where {V, T,N}
201270 len = checked_dims (size)
202271 if length (a) != len
203272 throw (DimensionMismatch (" new shape not consistent with existing array length" ))
204273 end
205- FixedSizeArray {T,N} (Internal (), a. mem, size)
274+ FixedSizeArray {T,N,V } (Internal (), a. mem, size)
206275end
207276
208277# `collect_as`
209278
210- function collect_as_fsa0 (iterator, :: Val{nothing} )
279+ function collect_as_fsa0 (iterator, :: SpecFSA{0,V} ) where {V}
280+ V:: UnionAll
211281 x = only (iterator)
212- ret = FixedSizeArray {typeof(x),0} (undef)
282+ E = typeof (x):: Type
283+ ret = FixedSizeArray {E,0,V{E}} (undef)
213284 ret[] = x
214285 ret
215286end
216287
217- function collect_as_fsa0 (iterator, :: Val{E } ) where {E}
288+ function collect_as_fsa0 (iterator, :: SpecFSA{0,V } ) where {E,V <: DenseVector{E} }
218289 E:: Type
219290 x = only (iterator)
220- ret = FixedSizeArray {E,0} (undef)
291+ ret = FixedSizeArray {E,0,V } (undef)
221292 ret[] = x
222293 ret
223294end
@@ -234,24 +305,26 @@ function fill_fsa_from_iterator!(a, iterator)
234305end
235306
236307function collect_as_fsam_with_shape (
237- iterator, :: SpecFSA{nothing,M} , shape:: Tuple{Vararg{Int}} ,
238- ) where {M}
308+ iterator, :: SpecFSA{M,V} , shape:: Tuple{Vararg{Int}} ,
309+ ) where {M,V}
310+ V:: UnionAll
239311 E = eltype (iterator):: Type
240- ret = FixedSizeArray {E,M} (undef, shape)
312+ U = V{E}
313+ ret = FixedSizeArray {E,M,U} (undef, shape)
241314 fill_fsa_from_iterator! (ret, iterator)
242- map (identity, ret):: FixedSizeArray{<:Any,M}
315+ map (identity, ret):: ( FixedSizeArray{T,M,V{T}} where {T})
243316end
244317
245318function collect_as_fsam_with_shape (
246- iterator, :: SpecFSA{E,M } , shape:: Tuple{Vararg{Int}} ,
247- ) where {E,M }
319+ iterator, :: SpecFSA{M,V } , shape:: Tuple{Vararg{Int}} ,
320+ ) where {M,E,V <: DenseVector{E} }
248321 E:: Type
249- ret = FixedSizeArray {E,M} (undef, shape)
322+ ret = FixedSizeArray {E,M,V } (undef, shape)
250323 fill_fsa_from_iterator! (ret, iterator)
251- ret:: FixedSizeArray{E,M}
324+ ret:: FixedSizeArray{E,M,V }
252325end
253326
254- function collect_as_fsam (iterator, spec:: SpecFSA{<:Any, M} ) where {M}
327+ function collect_as_fsam (iterator, spec:: SpecFSA{M} ) where {M}
255328 check_count_value (M)
256329 shape = if isone (M)
257330 (length (iterator),)
@@ -262,39 +335,42 @@ function collect_as_fsam(iterator, spec::SpecFSA{<:Any,M}) where {M}
262335 collect_as_fsam_with_shape (iterator, spec, shap):: FixedSizeArray{<:Any,M}
263336end
264337
265- function collect_as_fsa1_from_unknown_length (iterator, :: Val{nothing} )
338+ function collect_as_fsa1_from_unknown_length (iterator, :: SpecFSA{1,V} ) where {V}
339+ V:: UnionAll
266340 v = collect (iterator):: AbstractVector
267- T = FixedSizeVector
268- map (identity, T (v)):: T
341+ t = FixedSizeVector (v):: FixedSizeVector
342+ s = map (identity, t):: FixedSizeVector # fix element type
343+ et = eltype (s)
344+ FixedSizeVector {et,V{et}} (s) # fix underlying storage type
269345end
270346
271- function collect_as_fsa1_from_unknown_length (iterator, :: Val{E } ) where {E}
347+ function collect_as_fsa1_from_unknown_length (iterator, :: SpecFSA{1,V } ) where {E,V <: DenseVector{E} }
272348 E:: Type
273349 v = collect (E, iterator):: AbstractVector{E}
274- T = FixedSizeVector{E}
350+ T = FixedSizeVector{E,V }
275351 T (v):: T
276352end
277353
278- function collect_as_fsa_impl (iterator, :: SpecFSA{E, 0} , :: LengthIsKnown ) where {E}
279- collect_as_fsa0 (iterator, Val (E) ):: FixedSizeArray{<:Any,0}
354+ function collect_as_fsa_impl (iterator, spec :: SpecFSA{0} , :: LengthIsKnown )
355+ collect_as_fsa0 (iterator, spec ):: FixedSizeArray{<:Any,0}
280356end
281357
282358function collect_as_fsa_impl (iterator, spec:: SpecFSA , :: LengthIsKnown )
283359 collect_as_fsam (iterator, spec):: FixedSizeArray
284360end
285361
286- function collect_as_fsa_impl (iterator, :: SpecFSA{E, 1} , :: LengthIsUnknown ) where {E}
287- collect_as_fsa1_from_unknown_length (iterator, Val (E) ):: FixedSizeVector
362+ function collect_as_fsa_impl (iterator, spec :: SpecFSA{1} , :: LengthIsUnknown )
363+ collect_as_fsa1_from_unknown_length (iterator, spec ):: FixedSizeVector
288364end
289365
290- function collect_as_fsa_checked (iterator, :: SpecFSA{E, nothing} , :: Val{M} , length_status) where {E ,M}
366+ function collect_as_fsa_checked (iterator, :: SpecFSA{nothing,V } , :: Val{M} , length_status) where {V ,M}
291367 check_count_value (M)
292- collect_as_fsa_impl (iterator, SpecFSA {E,M } (), length_status):: FixedSizeArray{<:Any,M}
368+ collect_as_fsa_impl (iterator, SpecFSA {M,V } (), length_status):: FixedSizeArray{<:Any,M}
293369end
294370
295- function collect_as_fsa_checked (iterator, :: SpecFSA{E, M} , :: Val{M} , length_status) where {E, M}
371+ function collect_as_fsa_checked (iterator, spec :: SpecFSA{M} , :: Val{M} , length_status) where {M}
296372 check_count_value (M)
297- collect_as_fsa_impl (iterator, SpecFSA {E,M} () , length_status):: FixedSizeArray{<:Any,M}
373+ collect_as_fsa_impl (iterator, spec , length_status):: FixedSizeArray{<:Any,M}
298374end
299375
300376"""
0 commit comments