@@ -8,6 +8,9 @@ using Compat: axes, CartesianIndices
8
8
9
9
export OffsetArray, OffsetVector, @unsafe
10
10
11
+ # # Major change in 0.7: OffsetArray now uses Offset axes
12
+ const AxisType = VERSION < v " 0.7.0-DEV.5242" ? identity : Base. Slice
13
+
11
14
# TODO : just use .+
12
15
# See https://github.com/JuliaLang/julia/pull/22932#issuecomment-330711997
13
16
if VERSION < v " 0.7.0-DEV.1759"
74
77
OffsetArray (A:: AbstractArray{T,0} , inds:: Tuple{} ) where {T} = OffsetArray {T,0,typeof(A)} (A, ())
75
78
OffsetArray (A:: AbstractArray{T,N} , inds:: Tuple{} ) where {T,N} = error (" this should never be called" )
76
79
function OffsetArray (A:: AbstractArray{T,N} , inds:: NTuple{N,AbstractUnitRange} ) where {T,N}
77
- lA = map (length , axes (A))
78
- lI = map (length , inds)
80
+ lA = map (indexlength , axes (A))
81
+ lI = map (indexlength , inds)
79
82
lA == lI || throw (DimensionMismatch (" supplied axes do not agree with the size of the array (got size $lA for the array and $lI for the indices" ))
80
83
OffsetArray (A, map (indexoffset, inds))
81
84
end
@@ -98,38 +101,48 @@ Base.eachindex(::IndexLinear, A::OffsetVector) = axes(A, 1)
98
101
# performance-critical and relies on axes, these are usually worth
99
102
# optimizing thoroughly.
100
103
@inline Compat. axes (A:: OffsetArray , d) =
101
- 1 <= d <= length (A. offsets) ? plus (axes (parent (A))[d], A. offsets[d]) : (1 : 1 )
104
+ 1 <= d <= length (A. offsets) ? AxisType ( plus (axes (parent (A))[d], A. offsets[d]) ) : (1 : 1 )
102
105
@inline Compat. axes (A:: OffsetArray ) =
103
106
_axes (axes (parent (A)), A. offsets) # would rather use ntuple, but see #15276
104
107
@inline _axes (inds, offsets) =
105
- (plus (inds[1 ], offsets[1 ]), _axes (tail (inds), tail (offsets))... )
108
+ (AxisType ( plus (inds[1 ], offsets[1 ]) ), _axes (tail (inds), tail (offsets))... )
106
109
_axes (:: Tuple{} , :: Tuple{} ) = ()
107
110
Base. indices1 (A:: OffsetArray{T,0} ) where {T} = 1 : 1 # we only need to specialize this one
108
111
112
+
113
+ const OffsetAxis = Union{Integer, UnitRange, Base. Slice{<: UnitRange }, Base. OneTo}
109
114
function Base. similar (A:: OffsetArray , :: Type{T} , dims:: Dims ) where T
110
115
B = similar (parent (A), T, dims)
111
116
end
112
- function Base. similar (A:: AbstractArray , :: Type{T} , inds:: Tuple{UnitRange ,Vararg{UnitRange }} ) where T
113
- B = similar (A, T, map (length , inds))
117
+ function Base. similar (A:: AbstractArray , :: Type{T} , inds:: Tuple{OffsetAxis ,Vararg{OffsetAxis }} ) where T
118
+ B = similar (A, T, map (indexlength , inds))
114
119
OffsetArray (B, map (indexoffset, inds))
115
120
end
116
121
117
- Base. similar (:: Type{T} , shape:: Tuple{UnitRange,Vararg{UnitRange}} ) where {T<: OffsetArray } =
118
- OffsetArray (T (map (length, shape)), map (indexoffset, shape))
119
- Base. similar (:: Type{T} , shape:: Tuple{UnitRange,Vararg{UnitRange}} ) where {T<: Array } =
120
- OffsetArray (T (undef, map (length, shape)), map (indexoffset, shape))
121
- Base. similar (:: Type{T} , shape:: Tuple{UnitRange,Vararg{UnitRange}} ) where {T<: BitArray } =
122
- OffsetArray (T (undef, map (length, shape)), map (indexoffset, shape))
122
+ Base. similar (:: Type{T} , shape:: Tuple{OffsetAxis,Vararg{OffsetAxis}} ) where {T<: AbstractArray } =
123
+ OffsetArray (T (undef, map (indexlength, shape)), map (indexoffset, shape))
123
124
125
+ if VERSION < v " 0.7.0-DEV.5242"
126
+ # Reshape's methods in Base changed, so using the new definitions leads to ambiguities
124
127
Base. reshape (A:: AbstractArray , inds:: Tuple{UnitRange,Vararg{UnitRange}} ) =
125
128
OffsetArray (reshape (A, map (length, inds)), map (indexoffset, inds))
126
-
127
129
Base. reshape (A:: OffsetArray , inds:: Tuple{UnitRange,Vararg{UnitRange}} ) =
128
130
OffsetArray (reshape (parent (A), map (length, inds)), map (indexoffset, inds))
129
-
130
131
function Base. reshape (A:: OffsetArray , inds:: Tuple{UnitRange,Vararg{Union{UnitRange,Int,Base.OneTo}}} )
131
132
throw (ArgumentError (" reshape must supply UnitRange axes, got $(typeof (inds)) .\n Note that reshape(A, Val{N}) is not supported for OffsetArrays." ))
132
133
end
134
+ else
135
+ Base. reshape (A:: AbstractArray , inds:: Tuple{OffsetAxis,Vararg{OffsetAxis}} ) =
136
+ OffsetArray (reshape (A, map (indexlength, inds)), map (indexoffset, inds))
137
+
138
+ # Reshaping OffsetArrays can "pop" the original OffsetArray wrapper and return
139
+ # an OffsetArray(reshape(...)) instead of an OffsetArray(reshape(OffsetArray(...)))
140
+ Base. reshape (A:: OffsetArray , inds:: Tuple{OffsetAxis,Vararg{OffsetAxis}} ) =
141
+ OffsetArray (reshape (parent (A), map (indexlength, inds)), map (indexoffset, inds))
142
+ # And for non-offset axes, we can just return a reshape of the parent directly
143
+ Base. reshape (A:: OffsetArray , inds:: Tuple{Union{Integer,Base.OneTo},Vararg{Union{Integer,Base.OneTo}}} ) = reshape (parent (A), inds)
144
+ Base. reshape (A:: OffsetArray , inds:: Dims ) = reshape (parent (A), inds)
145
+ end
133
146
134
147
if VERSION < v " 0.7.0-DEV.4873"
135
148
# Julia PR #26733 removed similar(f, ...) in favor of just using method extension directly
@@ -201,7 +214,7 @@ offset(offsets::Tuple{Vararg{Int}}, inds::Tuple{}) = error("inds cannot be short
201
214
202
215
indexoffset (r:: AbstractRange ) = first (r) - 1
203
216
indexoffset (i:: Integer ) = 0
204
- indexlength (r:: AbstractRange ) = length (r)
217
+ indexlength (r:: AbstractRange ) = Base . _length (r)
205
218
indexlength (i:: Integer ) = i
206
219
207
220
macro unsafe (ex)
@@ -290,8 +303,10 @@ if VERSION >= v"0.7.0-DEV.1790"
290
303
toplevel && print (io, " with eltype " , eltype (a))
291
304
end
292
305
printindices (io:: IO , ind1, inds... ) =
293
- (print (io, ind1, " , " ); printindices (io, inds... ))
294
- printindices (io:: IO , ind1) = print (io, ind1)
306
+ (print (io, _unslice (ind1), " , " ); printindices (io, inds... ))
307
+ printindices (io:: IO , ind1) = print (io, _unslice (ind1))
308
+ _unslice (x) = x
309
+ _unslice (x:: Base.Slice ) = x. indices
295
310
end
296
311
297
312
end # module
0 commit comments