@@ -271,10 +271,34 @@ end
271
271
272
272
Base. similar (A:: OffsetArray , :: Type{T} , dims:: Dims ) where T =
273
273
similar (parent (A), T, dims)
274
- function Base. similar (A:: AbstractArray , :: Type{T} , inds:: Tuple{OffsetAxisKnownLength,Vararg{OffsetAxisKnownLength}} ) where T
275
- B = similar (A, T, map (_indexlength, inds))
276
- return OffsetArray (B, map (_offset, axes (B), inds))
274
+ function Base. similar (A:: AbstractArray , :: Type{T} , shape:: Tuple{OffsetAxisKnownLength,Vararg{OffsetAxisKnownLength}} ) where T
275
+ # strip IdOffsetRanges to extract the parent range and use it to generate the array
276
+ new_shape = map (_strip_IdOffsetRange, shape)
277
+ # route through _similar_axes_or_length to avoid a stack overflow if map(_strip_IdOffsetRange, shape) === shape
278
+ # This tries to use new_shape directly in similar if similar(A, T, ::typeof(new_shape)) is defined
279
+ # If this fails, it calls similar(A, T, map(_indexlength, new_shape)) to use the size along each axis
280
+ # to generate the new array
281
+ P = _similar_axes_or_length (A, T, new_shape, shape)
282
+ return OffsetArray (P, map (_offset, axes (P), shape))
277
283
end
284
+ function Base. similar (:: Type{T} , shape:: Tuple{OffsetAxisKnownLength,Vararg{OffsetAxisKnownLength}} ) where {T<: AbstractArray }
285
+ new_shape = map (_strip_IdOffsetRange, shape)
286
+ P = _similar_axes_or_length (T, new_shape, shape)
287
+ OffsetArray (P, map (_offset, axes (P), shape))
288
+ end
289
+ # Try to use the axes to generate the parent array type
290
+ # This is useful if the axes have special meanings, such as with static arrays
291
+ # This method is hit if at least one axis provided to similar(A, T, axes) is an IdOffsetRange
292
+ # For example this is hit when similar(A::OffsetArray) is called,
293
+ # which expands to similar(A, eltype(A), axes(A))
294
+ _similar_axes_or_length (A, T, ax, :: Any ) = similar (A, T, ax)
295
+ _similar_axes_or_length (AT, ax, :: Any ) = similar (AT, ax)
296
+ # Handle the general case by resorting to lengths along each axis
297
+ # This is hit if none of the axes provided to similar(A, T, axes) are IdOffsetRanges,
298
+ # and if similar(A, T, axes::AX) is not defined for the type AX.
299
+ # In this case the best that we can do is to create a mutable array of the correct size
300
+ _similar_axes_or_length (A, T, ax:: I , :: I ) where {I} = similar (A, T, map (_indexlength, ax))
301
+ _similar_axes_or_length (AT, ax:: I , :: I ) where {I} = similar (AT, map (_indexlength, ax))
278
302
279
303
# reshape accepts a single colon
280
304
Base. reshape (A:: AbstractArray , inds:: OffsetAxis... ) = reshape (A, inds)
@@ -295,11 +319,6 @@ Base.reshape(A::OffsetVector, ::Colon) = A
295
319
Base. reshape (A:: OffsetArray , inds:: Union{Int,Colon} ...) = reshape (parent (A), inds)
296
320
Base. reshape (A:: OffsetArray , inds:: Tuple{Vararg{Union{Int,Colon}}} ) = reshape (parent (A), inds)
297
321
298
- function Base. similar (:: Type{T} , shape:: Tuple{OffsetAxisKnownLength,Vararg{OffsetAxisKnownLength}} ) where {T<: AbstractArray }
299
- P = T (undef, map (_indexlength, shape))
300
- OffsetArray (P, map (_offset, axes (P), shape))
301
- end
302
-
303
322
Base. fill (v, inds:: NTuple{N, Union{Integer, AbstractUnitRange}} ) where {N} =
304
323
fill! (similar (Array{typeof (v)}, inds), v)
305
324
Base. zeros (:: Type{T} , inds:: NTuple{N, Union{Integer, AbstractUnitRange}} ) where {T, N} =
0 commit comments