Skip to content

Commit

Permalink
Merge pull request #15144 from mbauman/mb/strange-indices
Browse files Browse the repository at this point in the history
Better SubArray support for strange indices
  • Loading branch information
mbauman committed Feb 20, 2016
2 parents 1757229 + 0cd7a93 commit de1f565
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 8 deletions.
12 changes: 6 additions & 6 deletions base/subarray.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This file is a part of Julia. License is MIT: http://julialang.org/license

typealias NonSliceIndex Union{Colon, AbstractVector}
typealias ViewIndex Union{Int, NonSliceIndex}
typealias ViewIndex Union{Real, NonSliceIndex}

# L is true if the view itself supports fast linear indexing
immutable SubArray{T,N,P,I,L} <: AbstractArray{T,N}
Expand All @@ -12,8 +12,8 @@ immutable SubArray{T,N,P,I,L} <: AbstractArray{T,N}
stride1::Int # used only for linear indexing
end
# Compute the linear indexability of the indices, and combine it with the linear indexing of the parent
function SubArray(parent::AbstractArray, indexes::Tuple, dims::Dims)
SubArray(linearindexing(viewindexing(indexes), linearindexing(parent)), parent, indexes, dims)
function SubArray(parent::AbstractArray, indexes::Tuple, dims::Tuple)
SubArray(linearindexing(viewindexing(indexes), linearindexing(parent)), parent, indexes, convert(Dims, dims))
end
function SubArray{P, I, N}(::LinearSlow, parent::P, indexes::I, dims::NTuple{N, Int})
SubArray{eltype(P), N, P, I, false}(parent, indexes, dims, 0, 0)
Expand Down Expand Up @@ -82,7 +82,7 @@ parentindexes(a::AbstractArray) = ntuple(i->1:size(a,i), ndims(a))

## SubArray creation
# Drops singleton dimensions (those indexed with a scalar)
function slice(A::AbstractArray, I...)
function slice(A::AbstractArray, I::ViewIndex...)
@_inline_meta
@boundscheck checkbounds(A, I...)
J = to_indexes(I...)
Expand All @@ -94,7 +94,7 @@ keep_leading_scalars(T::Tuple{Real, Vararg{Real}}) = T
keep_leading_scalars(T::Tuple{Real, Vararg{Any}}) = (@_inline_meta; (NoSlice(T[1]), keep_leading_scalars(tail(T))...))
keep_leading_scalars(T::Tuple{Any, Vararg{Any}}) = (@_inline_meta; (T[1], keep_leading_scalars(tail(T))...))

function sub(A::AbstractArray, I...)
function sub(A::AbstractArray, I::ViewIndex...)
@_inline_meta
@boundscheck checkbounds(A, I...)
J = keep_leading_scalars(to_indexes(I...))
Expand Down Expand Up @@ -207,7 +207,7 @@ unsafe_getindex(::Colon, i) = to_index(i)
step(::Colon) = 1
first(::Colon) = 1
isempty(::Colon) = false
in(::Int, ::Colon) = true
in(::Integer, ::Colon) = true

# Strides are the distance between adjacent elements in a given dimension,
# so they are well-defined even for non-linear memory layouts
Expand Down
16 changes: 14 additions & 2 deletions test/subarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,8 @@ if !testfull
(:,3:7,:),
(3:7,:,:),
(3:7,6,:),
(3:7,6,6),
(6,3:7,3:7),
(3:7,6,0x6),
(6,UInt(3):UInt(7),3:7),
(13:-2:1,:,:),
([8,4,6,12,5,7],:,3:7),
(6,6,[8,4,6,12,5,7]),
Expand Down Expand Up @@ -445,3 +445,15 @@ let a = ones(Float64, (2,2)),
b[2] = 2
@test b[2] === 2.0
end

# issue #15138
let a = [1,2,3],
b = sub(a, UInt(1):UInt(2))
@test b == slice(a, UInt(1):UInt(2)) == slice(slice(a, :), UInt(1):UInt(2)) == [1,2]
end

let A = reshape(1:4, 2, 2)
B = sub(A, :, :)
@test parent(B) === A
@test parent(sub(B, 0x1, :)) === parent(slice(B, 0x1, :)) === A
end

0 comments on commit de1f565

Please sign in to comment.