@@ -11,23 +11,37 @@ Implementation detail. Do not use.
11
11
"""
12
12
struct Internal end
13
13
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
16
16
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)
19
19
end
20
20
end
21
21
22
22
const FixedSizeVector{T} = FixedSizeArray{T,1 }
23
23
const FixedSizeMatrix{T} = FixedSizeArray{T,2 }
24
24
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)
27
29
end
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 }
29
31
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)
31
45
end
32
46
function FixedSizeArray {T,N} (:: UndefInitializer , size:: Vararg{Integer,N} ) where {T,N}
33
47
FixedSizeArray {T,N} (undef, size)
@@ -45,8 +59,8 @@ Base.@propagate_inbounds Base.setindex!(A::FixedSizeArray, v, i::Int) = A.mem[i]
45
59
46
60
Base. size (a:: FixedSizeArray ) = a. size
47
61
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)
50
64
end
51
65
52
66
Base. isassigned (a:: FixedSizeArray , i:: Int ) = isassigned (a. mem, i)
83
97
84
98
# broadcasting
85
99
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) } ()
88
102
end
89
103
90
104
function Base. similar (
91
- bc:: Broadcast.Broadcasted{Broadcast.ArrayStyle{FixedSizeArray }} ,
105
+ bc:: Broadcast.Broadcasted{Broadcast.ArrayStyle{S }} ,
92
106
:: Type{E} ,
93
- ) where {E}
94
- similar (FixedSizeArray {E}, axes (bc))
107
+ ) where {S <: FixedSizeArray , E}
108
+ similar (S {E}, axes (bc))
95
109
end
96
110
97
111
# helper functions
98
112
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
+
99
139
dimension_count_of (:: Base.SizeUnknown ) = 1
100
140
dimension_count_of (:: Base.HasLength ) = 1
101
141
dimension_count_of (:: Base.HasShape{N} ) where {N} = convert (Int, N):: Int
@@ -115,23 +155,49 @@ function check_count_value(n)
115
155
throw (ArgumentError (" count must be an `Int`" ))
116
156
end
117
157
118
- struct SpecFSA{T,N} end
158
+ # TODO : use `SpecFSA` for implementing each `FixedSizeArray` constructor?
159
+ struct SpecFSA{N,Mem<: GenericMemory } end
119
160
function fsa_spec_from_type (:: Type{FixedSizeArray} )
120
- SpecFSA {nothing,nothing } ()
161
+ SpecFSA {nothing,default_underlying_storage_type } ()
121
162
end
122
163
function fsa_spec_from_type (:: Type{FixedSizeArray{<:Any,M}} ) where {M}
123
164
check_count_value (M)
124
- SpecFSA {nothing,M } ()
165
+ SpecFSA {M,default_underlying_storage_type } ()
125
166
end
126
167
function 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}} ()
128
170
end
129
171
function fsa_spec_from_type (:: Type{FixedSizeArray{E,M}} ) where {E,M}
130
172
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
132
198
end
133
199
134
- parent_type (:: Type{<:FixedSizeArray{T}} ) where {T} = Memory{T}
200
+ parent_type (:: Type{<:FixedSizeArray{<:Any,<:Any, T}} ) where {T} = T
135
201
136
202
underlying_storage (m) = m
137
203
underlying_storage (f:: FixedSizeArray ) = f. mem
@@ -140,19 +206,22 @@ axes_are_one_based(axes) = all(isone ∘ first, axes)
140
206
141
207
# converting constructors for copying other array types
142
208
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}
144
210
axs = axes (src)
145
211
if ! axes_are_one_based (axs)
146
212
throw (DimensionMismatch (" source array has a non-one-based indexing axis" ))
147
213
end
148
214
# Can't use `Base.size` because, according to it's doc string, it's not
149
215
# available for all `AbstractArray` types.
150
216
size = map (length, axs)
151
- dst = FixedSizeArray {T,N} (undef, size)
217
+ dst = FixedSizeArray {T,N,V } (undef, size)
152
218
copyto! (dst. mem, src)
153
219
dst
154
220
end
155
221
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)
156
225
FixedSizeArray {T} (a:: AbstractArray{<:Any,N} ) where {T,N} = FixedSizeArray {T,N} (a)
157
226
FixedSizeArray {<:Any,N} (a:: AbstractArray{T,N} ) where {T,N} = FixedSizeArray {T,N} (a)
158
227
FixedSizeArray (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))
197
266
198
267
# `reshape`: specializing it to ensure it returns a `FixedSizeArray`
199
268
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}
201
270
len = checked_dims (size)
202
271
if length (a) != len
203
272
throw (DimensionMismatch (" new shape not consistent with existing array length" ))
204
273
end
205
- FixedSizeArray {T,N} (Internal (), a. mem, size)
274
+ FixedSizeArray {T,N,V } (Internal (), a. mem, size)
206
275
end
207
276
208
277
# `collect_as`
209
278
210
- function collect_as_fsa0 (iterator, :: Val{nothing} )
279
+ function collect_as_fsa0 (iterator, :: SpecFSA{0,V} ) where {V}
280
+ V:: UnionAll
211
281
x = only (iterator)
212
- ret = FixedSizeArray {typeof(x),0} (undef)
282
+ E = typeof (x):: Type
283
+ ret = FixedSizeArray {E,0,V{E}} (undef)
213
284
ret[] = x
214
285
ret
215
286
end
216
287
217
- function collect_as_fsa0 (iterator, :: Val{E } ) where {E}
288
+ function collect_as_fsa0 (iterator, :: SpecFSA{0,V } ) where {E,V <: DenseVector{E} }
218
289
E:: Type
219
290
x = only (iterator)
220
- ret = FixedSizeArray {E,0} (undef)
291
+ ret = FixedSizeArray {E,0,V } (undef)
221
292
ret[] = x
222
293
ret
223
294
end
@@ -234,24 +305,26 @@ function fill_fsa_from_iterator!(a, iterator)
234
305
end
235
306
236
307
function 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
239
311
E = eltype (iterator):: Type
240
- ret = FixedSizeArray {E,M} (undef, shape)
312
+ U = V{E}
313
+ ret = FixedSizeArray {E,M,U} (undef, shape)
241
314
fill_fsa_from_iterator! (ret, iterator)
242
- map (identity, ret):: FixedSizeArray{<:Any,M}
315
+ map (identity, ret):: ( FixedSizeArray{T,M,V{T}} where {T})
243
316
end
244
317
245
318
function 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} }
248
321
E:: Type
249
- ret = FixedSizeArray {E,M} (undef, shape)
322
+ ret = FixedSizeArray {E,M,V } (undef, shape)
250
323
fill_fsa_from_iterator! (ret, iterator)
251
- ret:: FixedSizeArray{E,M}
324
+ ret:: FixedSizeArray{E,M,V }
252
325
end
253
326
254
- function collect_as_fsam (iterator, spec:: SpecFSA{<:Any, M} ) where {M}
327
+ function collect_as_fsam (iterator, spec:: SpecFSA{M} ) where {M}
255
328
check_count_value (M)
256
329
shape = if isone (M)
257
330
(length (iterator),)
@@ -262,39 +335,42 @@ function collect_as_fsam(iterator, spec::SpecFSA{<:Any,M}) where {M}
262
335
collect_as_fsam_with_shape (iterator, spec, shap):: FixedSizeArray{<:Any,M}
263
336
end
264
337
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
266
340
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
269
345
end
270
346
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} }
272
348
E:: Type
273
349
v = collect (E, iterator):: AbstractVector{E}
274
- T = FixedSizeVector{E}
350
+ T = FixedSizeVector{E,V }
275
351
T (v):: T
276
352
end
277
353
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}
280
356
end
281
357
282
358
function collect_as_fsa_impl (iterator, spec:: SpecFSA , :: LengthIsKnown )
283
359
collect_as_fsam (iterator, spec):: FixedSizeArray
284
360
end
285
361
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
288
364
end
289
365
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}
291
367
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}
293
369
end
294
370
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}
296
372
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}
298
374
end
299
375
300
376
"""
0 commit comments