diff --git a/src/OffsetArrays.jl b/src/OffsetArrays.jl index 195697f3..d8a7bae7 100644 --- a/src/OffsetArrays.jl +++ b/src/OffsetArrays.jl @@ -15,10 +15,21 @@ include("axes.jl") struct OffsetArray{T,N,AA<:AbstractArray} <: AbstractArray{T,N} parent::AA offsets::NTuple{N,Int} + function OffsetArray{T, N, AA}(parent::AA, offsets::NTuple{N, Int}) where {T, N, AA<:AbstractArray} + overflow_check.(axes(parent), offsets) + new{T, N, AA}(parent, offsets) + end end OffsetVector{T,AA<:AbstractArray} = OffsetArray{T,1,AA} OffsetMatrix{T,AA<:AbstractArray} = OffsetArray{T,2,AA} +function overflow_check(r, offset::T) where T + if offset > 0 && last(r) > typemax(T) - offset + throw(ArgumentError("Boundary overflow detected: offset $offset should be equal or less than $(typemax(T) - last(r))")) + elseif offset < 0 && first(r) < typemin(T) - offset + throw(ArgumentError("Boundary overflow detected: offset $offset should be equal or greater than $(typemin(T) - first(r))")) + end +end ## OffsetArray constructors offset(axparent::AbstractUnitRange, ax::AbstractUnitRange) = first(ax) - first(axparent) diff --git a/test/runtests.jl b/test/runtests.jl index d1cec2e2..da604adb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,6 @@ using OffsetArrays using OffsetArrays: IdentityUnitRange, no_offset_view +using OffsetArrays: IdOffsetRange using Test, Aqua using LinearAlgebra using DelimitedFiles @@ -125,6 +126,13 @@ end w = zeros(5:6) @test OffsetVector(w, :) == OffsetArray(w, (:,)) == OffsetArray(w, :) == OffsetArray(w, axes(w)) @test axes(OffsetVector(w, :)) == axes(w) + + @test axes(OffsetVector(v, typemax(Int)-length(v))) == (IdOffsetRange(axes(v)[1], typemax(Int)-length(v)), ) + @test_throws ArgumentError OffsetVector(v, typemax(Int)-length(v)+1) + ao = OffsetArray(v, typemin(Int)) + @test_nowarn OffsetArray{Float64, 1, typeof(ao)}(ao, (-1, )) + @test_throws ArgumentError OffsetArray{Float64, 1, typeof(ao)}(ao, (-2, )) # inner Constructor + @test_throws ArgumentError OffsetArray(ao, (-2, )) # convinient constructor accumulate offsets end @testset "OffsetMatrix constructors" begin @@ -158,6 +166,10 @@ end @test axes(OffsetMatrix(w, :, CartesianIndices((0:1,)))) == (3:4, 0:1) @test axes(OffsetMatrix(w, CartesianIndices((0:1,)), :)) == (0:1, 5:6) + + @test axes(OffsetMatrix(v, typemax(Int)-size(v, 1), 0)) == (IdOffsetRange(axes(v)[1], typemax(Int)-size(v, 1)), axes(v, 2)) + @test_throws ArgumentError OffsetMatrix(v, typemax(Int)-size(v,1)+1, 0) + @test_throws ArgumentError OffsetMatrix(v, 0, typemax(Int)-size(v, 2)+1) end @testset "construct OffsetArray with CartesianIndices" begin