@@ -107,15 +107,32 @@ unaliascopy(A::SubArray) = typeof(A)(unaliascopy(A.parent), map(unaliascopy, A.i
107107# When the parent is an Array we can trim the size down a bit. In the future this
108108# could possibly be extended to any mutable array.
109109function unaliascopy (V:: SubArray{T,N,A,I,LD} ) where {T,N,A<: Array ,I<: Tuple{Vararg{Union{Real,AbstractRange,Array}}} ,LD}
110- dest = Array {T} (undef, index_lengths (V. indices... ))
111- copyto! (dest, V )
110+ dest = Array {T} (undef, _trimmed_shape (V. indices... ))
111+ copyto! (dest, view (V, _trimmed_vind (V . indices ... ) ... ) )
112112 SubArray {T,N,A,I,LD} (dest, map (_trimmedindex, V. indices), 0 , Int (LD))
113113end
114+ # We can avoid the repeation from `AbstractArray{CartesianIndex{0}}`
115+ @inline _trimmed_vind (A, rest... ) = (_trimmed_vind1 (A)... , _trimmed_vind (rest... )... )
116+ _trimmed_vind () = ()
117+ _trimmed_vind1 (i:: AbstractArray{<:AbstractCartesianIndex{0}} ) = map (firstindex, axes (i))
118+ _trimmed_vind1 (i) = axes (i)
119+ # Get the proper trimmed shape
120+ @inline _trimmed_shape (A, rest... ) = (_trimmed_shape1 (A)... , _trimmed_shape (rest... )... )
121+ _trimmed_shape () = ()
122+ _trimmed_shape1 (:: Real ) = (1 ,)
123+ _trimmed_shape1 (i:: AbstractArray{<:Integer} ) = (length (i),)
124+ _trimmed_shape1 (i:: AbstractArray{<:AbstractCartesianIndex{0}} ) = ()
125+ _trimmed_shape1 (i:: AbstractArray{<:AbstractCartesianIndex{N}} ) where {N} = (length (i), ntuple (Returns (1 ), Val (N - 1 ))... )
114126# Transform indices to be "dense"
115127_trimmedindex (i:: Real ) = oftype (i, 1 )
116- _trimmedindex (i:: AbstractUnitRange ) = oftype (i, oneto (length (i)))
117- _trimmedindex (i:: AbstractArray ) = oftype (i, reshape (eachindex (IndexLinear (), i), axes (i)))
118-
128+ _trimmedindex (i:: AbstractUnitRange{<:Integer} ) = oftype (i, oneto (length (i)))
129+ _trimmedindex (i:: AbstractArray{<:Integer} ) = oftype (i, reshape (eachindex (IndexLinear (), i), axes (i)))
130+ _trimmedindex (i:: AbstractArray{<:AbstractCartesianIndex{0}} ) = oftype (i, copy (i))
131+ function _trimmedindex (i:: AbstractArray{<:AbstractCartesianIndex{N}} ) where {N}
132+ padding = ntuple (Returns (1 ), Val (N - 1 ))
133+ ax1 = eachindex (IndexLinear (), i)
134+ return oftype (i, reshape (CartesianIndices ((ax1, padding... )), axes (i)))
135+ end
119136# # SubArray creation
120137# We always assume that the dimensionality of the parent matches the number of
121138# indices that end up getting passed to it, so we store the parent as a
0 commit comments