diff --git a/base/deprecated.jl b/base/deprecated.jl index 2f2b3d9d8acd3..4d727980340f6 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -207,6 +207,8 @@ macro get!(h, key0, default) end end +pointer(V::SubArray{<:Any,<:Any,<:Array,<:Tuple{Vararg{RangeIndex}}}, is::Tuple) = pointer(V, CartesianIndex(is)) + # END 1.5 deprecations # BEGIN 1.6 deprecations diff --git a/base/io.jl b/base/io.jl index d95b474d48cc3..da46f90c5ae26 100644 --- a/base/io.jl +++ b/base/io.jl @@ -680,14 +680,14 @@ function write(s::IO, a::SubArray{T,N,<:Array}) where {T,N} colsz = size(a,1) * elsz GC.@preserve a if stride(a,1) != 1 for idxs in CartesianIndices(size(a)) - unsafe_write(s, pointer(a, idxs.I), elsz) + unsafe_write(s, pointer(a, idxs), elsz) end return elsz * length(a) elseif N <= 1 return unsafe_write(s, pointer(a, 1), colsz) else - for idxs in CartesianIndices((1, size(a)[2:end]...)) - unsafe_write(s, pointer(a, idxs.I), colsz) + for colstart in CartesianIndices((1, size(a)[2:end]...)) + unsafe_write(s, pointer(a, colstart), colsz) end return colsz * trailingsize(a,2) end diff --git a/base/subarray.jl b/base/subarray.jl index 3ecbe972cf3c8..04008860403ed 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -408,6 +408,15 @@ end pointer(V::FastSubArray, i::Int) = pointer(V.parent, V.offset1 + V.stride1*i) pointer(V::FastContiguousSubArray, i::Int) = pointer(V.parent, V.offset1 + i) +function pointer(V::SubArray{<:Any,<:Any,<:Array,<:Tuple{Vararg{RangeIndex}}}, is::AbstractCartesianIndex{N}) where {N} + index = first_index(V) + strds = strides(V) + for d = 1:N + index += (is[d]-1)*strds[d] + end + return pointer(V.parent, index) +end + # indices are taken from the range/vector # Since bounds-checking is performance-critical and uses # indices, it's worth optimizing these implementations thoroughly diff --git a/test/subarray.jl b/test/subarray.jl index 33efc27f9bf9a..d31e4d46d90f7 100644 --- a/test/subarray.jl +++ b/test/subarray.jl @@ -615,6 +615,27 @@ end v = Vector{UInt48}(undef, 5) read!(io, v) @test v == view(a, :, 2) + + seekstart(io) + @test write(io, view(a, 2:5, 1:4)) == 4*4*8 + seekstart(io) + v = Matrix{UInt48}(undef, 4, 4) + read!(io, v) + @test v == view(a, 2:5, 1:4) + + seekstart(io) + @test write(io, view(a, 5:-1:1, 3)) == 5*8 + seekstart(io) + v = Vector{UInt48}(undef, 5) + read!(io, v) + @test v == view(a, 5:-1:1, 3) + + seekstart(io) + @test write(io, view(a, 1:2:5, :)) == 3*5*8 + seekstart(io) + v = Matrix{UInt48}(undef, 3, 5) + read!(io, v) + @test v == view(a, 1:2:5, :) end @testset "unaliascopy trimming; Issue #26263" begin