Skip to content

Commit 49487b8

Browse files
fix tests and constructors
1 parent 6d0389b commit 49487b8

File tree

3 files changed

+31
-13
lines changed

3 files changed

+31
-13
lines changed

ext/OffsetArraysAdaptExt.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Adapt.adapt_structure(to, O::OffsetArray) = OffsetArrays.parent_call(x -> Adapt.
1010

1111
@static if isdefined(Adapt, :parent_type)
1212
# To support Adapt 3.0 which doesn't have parent_type defined
13+
Adapt.parent_type(::Type{OffsetArray{T,N,AA,I}}) where {T,N,AA,I} = AA
1314
Adapt.parent_type(::Type{OffsetArray{T,N,AA}}) where {T,N,AA} = AA
1415
Adapt.unwrap_type(W::Type{<:OffsetArray}) = unwrap_type(parent_type(W))
1516
end

src/OffsetArrays.jl

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,17 +112,32 @@ julia> OffsetArray(a, OffsetArrays.Origin(0)) # set the origin to zero along eac
112112
struct OffsetArray{T, N, AA<:AbstractArray{T,N}, I<:Integer} <: AbstractArray{T, N}
113113
parent::AA
114114
offsets::NTuple{N,I}
115-
@inline function OffsetArray{T, N, AA}(parent::AA, offsets::NTuple{N, I}; checkoverflow=true) where {T, N, AA<:AbstractArray{T,N}, I<:Integer}
115+
# Inner constructor with all 4 type parameters bound
116+
@inline function OffsetArray{T, N, AA, I}(parent::AA, offsets::NTuple{N, I}; checkoverflow=true) where {T, N, AA<:AbstractArray{T,N}, I<:Integer}
116117
# allocation of `map` on tuple is optimized away
117118
checkoverflow && map(overflow_check, axes(parent), offsets)
118119
new{T, N, AA, I}(parent, offsets)
119120
end
120-
#special case of a 0-dimensional array, offsets do not make sense here
121-
@inline function OffsetArray{T, N, AA}(parent::AA, offsets::Tuple{}; checkoverflow=true) where {T, N, AA<:AbstractArray{T,0}}
122-
new{T, N, AA, Int}(parent, offsets)
121+
# Special case of a 0-dimensional array, offsets do not make sense here
122+
@inline function OffsetArray{T, N, AA, I}(parent::AA, offsets::Tuple{}; checkoverflow=true) where {T, N, AA<:AbstractArray{T,0}, I<:Integer}
123+
new{T, N, AA, I}(parent, offsets)
123124
end
124125
end
125126

127+
# Helper to get the element type of an offset tuple
128+
_offset_eltype(::Tuple{I, Vararg{I}}) where {I<:Integer} = I
129+
_offset_eltype(::Tuple{}) = Int
130+
131+
# Outer constructor that infers I from the offsets - for backwards compatibility with 3-param calls
132+
@inline function OffsetArray{T, N, AA}(parent::AA, offsets::NTuple{N, <:Integer}; checkoverflow=true) where {T, N, AA<:AbstractArray{T,N}}
133+
I = _offset_eltype(offsets)
134+
OffsetArray{T, N, AA, I}(parent, offsets; checkoverflow=checkoverflow)
135+
end
136+
# Special case for 0-dimensional arrays with 3-param call
137+
@inline function OffsetArray{T, N, AA}(parent::AA, offsets::Tuple{}; checkoverflow=true) where {T, N, AA<:AbstractArray{T,0}}
138+
OffsetArray{T, N, AA, Int}(parent, offsets; checkoverflow=checkoverflow)
139+
end
140+
126141
"""
127142
OffsetVector(v, index)
128143

test/runtests.jl

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -459,9 +459,10 @@ Base.Int(a::WeirdInteger) = a
459459
]
460460

461461
offsets = size.(one_based_axes[1], 1)
462-
offsets_big = map(big, offsets)
462+
# Test with different integer offset types (Int8, Int16, Int32, Int64, Int128, BigInt)
463+
offsets_all = [map(T, offsets) for T in (Int8, Int16, Int32, Int64, Int128, BigInt)]
463464

464-
for inds in Any[offsets, offsets_big, one_based_axes...]
465+
for inds in Any[offsets_all..., one_based_axes...]
465466
# test indices API
466467
a = OffsetVector{Float64}(undef, inds)
467468
@test eltype(a) === Float64
@@ -489,7 +490,7 @@ Base.Int(a::WeirdInteger) = a
489490
end
490491

491492
# nested OffsetVectors
492-
for inds in Any[offsets, offsets_big]
493+
for inds in offsets_all
493494
a = OffsetVector{Float64}(undef, inds)
494495
b = OffsetVector(a, inds); b2 = OffsetVector(a, inds...);
495496
@test eltype(b) === eltype(b2) === Float64
@@ -653,9 +654,10 @@ Base.Int(a::WeirdInteger) = a
653654
]
654655

655656
offsets = size.(one_based_axes[1], 1)
656-
offsets_big = map(big, offsets)
657+
# Test with different integer offset types (Int8, Int16, Int32, Int64, Int128, BigInt)
658+
offsets_all = [map(T, offsets) for T in (Int8, Int16, Int32, Int64, Int128, BigInt)]
657659

658-
for inds in Any[offsets, offsets_big, one_based_axes...]
660+
for inds in Any[offsets_all..., one_based_axes...]
659661
# test API
660662
a = OffsetMatrix{Float64}(undef, inds)
661663
ax = (IdOffsetRange(Base.OneTo(4), 0), IdOffsetRange(Base.OneTo(3), 0))
@@ -682,7 +684,7 @@ Base.Int(a::WeirdInteger) = a
682684
@test_throws Union{ArgumentError, ErrorException} OffsetMatrix{Float64}(undef, 2, -2) # only positive numbers works
683685

684686
# nested OffsetMatrices
685-
for inds in Any[offsets, offsets_big]
687+
for inds in offsets_all
686688
a = OffsetMatrix{Float64}(undef, inds)
687689
b = OffsetMatrix(a, inds); b2 = OffsetMatrix(a, inds...);
688690
@test eltype(b) === eltype(b2) === Float64
@@ -857,9 +859,9 @@ Base.Int(a::WeirdInteger) = a
857859
# ndim of an OffsetArray should match that of the parent
858860
@test_throws TypeError OffsetArray{Float64,3,Matrix{Float64}}
859861

860-
# should throw a TypeError if the offsets can not be converted to Ints
861-
# this test does not work anymore?
862-
@test_throws TypeError OffsetVector{Int,Vector{Int}}(zeros(Int,2), (WeirdInteger(1),))
862+
# should throw an error if the offset type doesn't support proper arithmetic operations
863+
# (previously threw TypeError when converting to Int, now throws during overflow_check)
864+
@test_throws Exception OffsetVector{Int,Vector{Int}}(zeros(Int,2), (WeirdInteger(1),))
863865
end
864866

865867
@testset "custom range types" begin

0 commit comments

Comments
 (0)