diff --git a/src/OffsetArrays.jl b/src/OffsetArrays.jl index eecb2333..54b697a4 100644 --- a/src/OffsetArrays.jl +++ b/src/OffsetArrays.jl @@ -349,7 +349,8 @@ _similar_axes_or_length(AT, ax::I, ::I) where {I} = similar(AT, map(_indexlength Base.reshape(A::AbstractArray, inds::OffsetAxis...) = reshape(A, inds) function Base.reshape(A::AbstractArray, inds::Tuple{OffsetAxis,Vararg{OffsetAxis}}) AR = reshape(A, map(_indexlength, inds)) - return OffsetArray(AR, map(_offset, axes(AR), inds)) + O = OffsetArray(AR, map(_offset, axes(AR), inds)) + return _popreshape(O, axes(AR), _filterreshapeinds(inds)) end # Reshaping OffsetArrays can "pop" the original OffsetArray wrapper and return @@ -364,6 +365,10 @@ Base.reshape(A::OffsetVector, ::Colon) = A Base.reshape(A::OffsetArray, inds::Union{Int,Colon}...) = reshape(parent(A), inds) Base.reshape(A::OffsetArray, inds::Tuple{Vararg{Union{Int,Colon}}}) = reshape(parent(A), inds) +# permutedims in Base does not preserve axes, and can not be fixed in a non-breaking way +# This is a stopgap solution +Base.permutedims(v::OffsetVector) = reshape(v, (1, axes(v, 1))) + Base.fill(v, inds::NTuple{N, Union{Integer, AbstractUnitRange}}) where {N} = fill!(similar(Array{typeof(v)}, inds), v) Base.zeros(::Type{T}, inds::NTuple{N, Union{Integer, AbstractUnitRange}}) where {T, N} = diff --git a/src/utils.jl b/src/utils.jl index f2bf3dcc..2adc3538 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -4,7 +4,7 @@ _indexoffset(r::AbstractRange) = first(r) - 1 _indexoffset(i::Integer) = 0 _indexoffset(i::Colon) = 0 _indexlength(r::AbstractRange) = length(r) -_indexlength(i::Integer) = i +_indexlength(i::Integer) = Int(i) _indexlength(i::Colon) = Colon() _strip_IdOffsetRange(r::IdOffsetRange) = parent(r) @@ -102,3 +102,11 @@ end _of_eltype(::Type{T}, M::AbstractArray{T}) where {T} = M _of_eltype(T, M::AbstractArray) = map(T, M) + +# filter the arguments to reshape to check if there are any ranges +# If not, we may pop the parent array +_filterreshapeinds(t::Tuple{AbstractUnitRange, Vararg{Any}}) = t +_filterreshapeinds(t::Tuple) = _filterreshapeinds(tail(t)) +_filterreshapeinds(t::Tuple{}) = t +_popreshape(A::AbstractArray, ax::Tuple{Vararg{Base.OneTo}}, inds::Tuple{}) = no_offset_view(A) +_popreshape(A::AbstractArray, ax, inds) = A diff --git a/test/runtests.jl b/test/runtests.jl index 2ee6e854..d66dadc7 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1767,6 +1767,39 @@ end Arsc = reshape(A, :, 1) Arsc[1,1] = 5 @test first(A) == 5 + + @testset "issue #235" begin + Vec64 = zeros(6) + ind_a_64 = 3 + ind_a_32 =Int32.(ind_a_64) + @test reshape(Vec64, ind_a_32, :) == reshape(Vec64, ind_a_64, :) + end + + R = reshape(zeros(6), 2, :) + @test R isa Matrix + @test axes(R) == (1:2, 1:3) + R = reshape(zeros(6,1), 2, :) + @test R isa Matrix + @test axes(R) == (1:2, 1:3) + + R = reshape(zeros(6), 1:2, :) + @test axes(R) == (1:2, 1:3) + R = reshape(zeros(6,1), 1:2, :) + @test axes(R) == (1:2, 1:3) +end + +@testset "permutedims" begin + a = OffsetArray(1:2, 2:3) + @test permutedims(a) == reshape(1:2, 1, 2:3) + a = OffsetArray([10,11], Base.OneTo(2)) + @test permutedims(a) == reshape(10:11, 1, 1:2) + a = OffsetArray(SVector{2}(1,2), 3:4) + @test permutedims(a) == reshape(1:2, 1, 3:4) + + # check that the 2D case is unaffected + a = OffsetArray(reshape(1:2, 1, 2), 2:2, 4:5) + b = permutedims(a) + @test a[2,:] == b[:,2] end @testset "Indexing with OffsetArray axes" begin