Skip to content

Commit df73941

Browse files
authored
OffsetArray constructor accepts Integer offsets (#188)
1 parent 94a4172 commit df73941

File tree

2 files changed

+23
-9
lines changed

2 files changed

+23
-9
lines changed

src/OffsetArrays.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ struct OffsetArray{T,N,AA<:AbstractArray{T,N}} <: AbstractArray{T,N}
117117
end
118118
end
119119

120+
function OffsetArray{T, N, AA}(parent::AA, offsets::NTuple{N, <:Integer}) where {T, N, AA<:AbstractArray{T,N}}
121+
OffsetArray{T, N, AA}(parent, map(x -> convert(Int, x), offsets))
122+
end
123+
120124
"""
121125
OffsetVector(v, index)
122126
@@ -133,8 +137,8 @@ const OffsetMatrix{T,AA<:AbstractMatrix{T}} = OffsetArray{T,2,AA}
133137

134138
function overflow_check(r, offset::T) where T
135139
# This gives some performance boost https://github.com/JuliaLang/julia/issues/33273
136-
throw_upper_overflow_error() = throw(ArgumentError("Boundary overflow detected: offset $offset should be equal or less than $(typemax(T) - last(r))"))
137-
throw_lower_overflow_error() = throw(ArgumentError("Boundary overflow detected: offset $offset should be equal or greater than $(typemin(T) - first(r))"))
140+
throw_upper_overflow_error() = throw(OverflowError("Boundary overflow detected: offset should be <= $(typemax(T) - last(r)) for offsets of type $T, received $offset"))
141+
throw_lower_overflow_error() = throw(OverflowError("Boundary overflow detected: offset should be >= $(typemin(T) - first(r)) for offsets of type $T, received $offset"))
138142

139143
if offset > 0 && last(r) > typemax(T) - offset
140144
throw_upper_overflow_error()

test/runtests.jl

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ end
201201
one_based_axes = Any[
202202
(Base.OneTo(4), ),
203203
(1:4, ),
204+
(big(1):big(4), ),
204205
(CartesianIndex(1):CartesianIndex(4), ),
205206
(IdentityUnitRange(1:4), ),
206207
(IdOffsetRange(1:4),),
@@ -209,13 +210,17 @@ end
209210

210211
offset_axes = Any[
211212
(-1:2, ),
213+
(big(-1):big(2), ),
212214
(CartesianIndex(-1):CartesianIndex(2), ),
213215
(IdentityUnitRange(-1:2), ),
214216
(IdOffsetRange(-1:2),),
215217
(IdOffsetRange(3:6, -4),)
216218
]
217219

218-
for inds in Any[size.(one_based_axes[1], 1), one_based_axes...]
220+
offsets = size.(one_based_axes[1], 1)
221+
offsets_big = map(big, offsets)
222+
223+
for inds in Any[offsets, offsets_big, one_based_axes...]
219224
# test indices API
220225
a = OffsetVector{Float64}(undef, inds)
221226
@test eltype(a) === Float64
@@ -294,11 +299,11 @@ end
294299
# overflow bounds check
295300
v = rand(5)
296301
@test axes(OffsetVector(v, typemax(Int)-length(v))) == (IdOffsetRange(axes(v)[1], typemax(Int)-length(v)), )
297-
@test_throws ArgumentError OffsetVector(v, typemax(Int)-length(v)+1)
302+
@test_throws OverflowError OffsetVector(v, typemax(Int)-length(v)+1)
298303
ao = OffsetArray(v, typemin(Int))
299304
@test_nowarn OffsetArray{Float64, 1, typeof(ao)}(ao, (-1, ))
300-
@test_throws ArgumentError OffsetArray{Float64, 1, typeof(ao)}(ao, (-2, )) # inner Constructor
301-
@test_throws ArgumentError OffsetArray(ao, (-2, )) # convinient constructor accumulate offsets
305+
@test_throws OverflowError OffsetArray{Float64, 1, typeof(ao)}(ao, (-2, )) # inner Constructor
306+
@test_throws OverflowError OffsetArray(ao, (-2, )) # convinient constructor accumulate offsets
302307

303308
# disallow OffsetVector(::Array{<:Any, N}, offsets) where N != 1
304309
@test_throws ArgumentError OffsetVector(zeros(2,2), (2, 2))
@@ -328,6 +333,7 @@ end
328333
one_based_axes = Any[
329334
(Base.OneTo(4), Base.OneTo(3)),
330335
(1:4, 1:3),
336+
(big(1):big(4), big(1):big(3)),
331337
(CartesianIndex(1, 1):CartesianIndex(4, 3), ),
332338
(CartesianIndex(1):CartesianIndex(4), CartesianIndex(1):CartesianIndex(3)),
333339
(CartesianIndex(1):CartesianIndex(4), 1:3),
@@ -340,6 +346,7 @@ end
340346

341347
offset_axes = Any[
342348
(-1:2, 0:2),
349+
(big(-1):big(2), big(0):big(2)),
343350
(CartesianIndex(-1, 0):CartesianIndex(2, 2), ),
344351
(-1:2, CartesianIndex(0):CartesianIndex(2)),
345352
(CartesianIndex(-1):CartesianIndex(2), CartesianIndex(0):CartesianIndex(2)),
@@ -351,7 +358,10 @@ end
351358
(IdOffsetRange(-1:2), 0:2),
352359
]
353360

354-
for inds in Any[size.(one_based_axes[1], 1), one_based_axes...]
361+
offsets = size.(one_based_axes[1], 1)
362+
offsets_big = map(big, offsets)
363+
364+
for inds in Any[offsets, offsets_big, one_based_axes...]
355365
# test API
356366
a = OffsetMatrix{Float64}(undef, inds)
357367
ax = (IdOffsetRange(Base.OneTo(4), 0), IdOffsetRange(Base.OneTo(3), 0))
@@ -433,8 +443,8 @@ end
433443
# overflow bounds check
434444
a = rand(4, 3)
435445
@test axes(OffsetMatrix(a, typemax(Int)-size(a, 1), 0)) == (IdOffsetRange(axes(a)[1], typemax(Int)-size(a, 1)), axes(a, 2))
436-
@test_throws ArgumentError OffsetMatrix(a, typemax(Int)-size(a,1)+1, 0)
437-
@test_throws ArgumentError OffsetMatrix(a, 0, typemax(Int)-size(a, 2)+1)
446+
@test_throws OverflowError OffsetMatrix(a, typemax(Int)-size(a,1)+1, 0)
447+
@test_throws OverflowError OffsetMatrix(a, 0, typemax(Int)-size(a, 2)+1)
438448

439449
# disallow OffsetMatrix(::Array{<:Any, N}, offsets) where N != 2
440450
@test_throws ArgumentError OffsetMatrix(zeros(2), (2,))

0 commit comments

Comments
 (0)