Skip to content

Commit

Permalink
Merge pull request #3 from JuliaArrays/mb/inbounds
Browse files Browse the repository at this point in the history
Update for 0.5 inbounds
  • Loading branch information
mbauman committed Apr 27, 2017
2 parents b0ee8f1 + 0c57a71 commit 435ed6e
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 16 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ os:
- linux
- osx
julia:
- 0.4
- 0.5
- nightly
notifications:
Expand Down
2 changes: 1 addition & 1 deletion REQUIRE
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
julia 0.4
julia 0.5
Compat 0.19
2 changes: 0 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
environment:
matrix:
- JULIAVERSION: "julialang/bin/winnt/x86/0.4/julia-0.4-latest-win32.exe"
- JULIAVERSION: "julialang/bin/winnt/x64/0.4/julia-0.4-latest-win64.exe"
- JULIAVERSION: "julialang/bin/winnt/x86/0.5/julia-0.5-latest-win32.exe"
- JULIAVERSION: "julialang/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe"
- JULIAVERSION: "julianightlies/bin/winnt/x86/julia-latest-win32.exe"
Expand Down
1 change: 1 addition & 0 deletions src/RangeArrays.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
__precompile__()
module RangeArrays

using Compat
Expand Down
27 changes: 21 additions & 6 deletions src/matrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,27 @@ Base.size(R::RangeMatrix) = R.dims
@compat Base.IndexStyle(::Type{<:RangeMatrix}) = IndexCartesian()

# Scalar indexing
Base.getindex(R::RangeMatrix, i::Int, j::Int) = (checkbounds(R, i, j); Base.unsafe_getindex(R, i, j))
Base.unsafe_getindex(R::RangeMatrix, i::Int, j::Int) = @inbounds return R.rs[j][i]
@inline function Base.getindex(R::RangeMatrix, i::Int, j::Int)
@boundscheck checkbounds(R, i, j);
@inbounds return R.rs[j][i]
end

# For non-scalar indexing, only specialize with inner Ranges and Colons to
# return Ranges or RangeMatrixes. For everything else, we can use the fallbacks.
Base.getindex(R::RangeMatrix, I::Union{Range, Colon}, J) = (checkbounds(R, I, J); Base.unsafe_getindex(R, I, J))
Base.unsafe_getindex(R::RangeMatrix, I::Union{Range, Colon}, j::Real) = @inbounds return R.rs[j][I]
Base.unsafe_getindex(R::RangeMatrix, I::Union{Range, Colon}, ::Colon) = @inbounds return RangeMatrix([R.rs[j][I] for j=1:length(R.rs)])
Base.unsafe_getindex(R::RangeMatrix, I::Union{Range, Colon}, J) = @inbounds return RangeMatrix([R.rs[j][I] for j in J])
@inline function Base.getindex(R::RangeMatrix, I::Union{Range, Colon}, J)
@boundscheck checkbounds(R, I, J)
unsafe_getindex(R, I, J)
end
@inline unsafe_getindex(R::RangeMatrix, I::Union{Range, Colon}, j::Real) = @inbounds return R.rs[j][I]
@inline unsafe_getindex(R::RangeMatrix, I::Union{Range, Colon}, ::Colon) = @inbounds return RangeMatrix([R.rs[j][I] for j=1:length(R.rs)])
@inline unsafe_getindex(R::RangeMatrix, I::Union{Range, Colon}, J) = @inbounds return RangeMatrix([R.rs[j][I] for j in J])

# We can also optimize bounds checks to only look at each range's endpoints
function Base.checkindex(::Type{Bool}, inds::AbstractUnitRange, R::RangeMatrix)
b = true
@inbounds for r in R.rs
b &= checkindex(Bool, inds, r[1])
b &= checkindex(Bool, inds, r[end])
end
b
end
28 changes: 22 additions & 6 deletions src/repeatedrange.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,28 @@ Base.size(R::RepeatedRangeMatrix) = (length(R.r), length(R.at))
@compat Base.IndexStyle(::Type{<:RepeatedRangeMatrix}) = IndexCartesian()

# Scalar indexing
Base.getindex(R::RepeatedRangeMatrix, i::Int, j::Int) = (checkbounds(R, i, j); Base.unsafe_getindex(R, i, j))
Base.unsafe_getindex(R::RepeatedRangeMatrix, i::Int, j::Int) = @inbounds return R.r[i] + R.at[j]
@inline function Base.getindex(R::RepeatedRangeMatrix, i::Int, j::Int)
@boundscheck checkbounds(R, i, j)
@inbounds return R.r[i] + R.at[j]
end

# For non-scalar indexing, only specialize with inner Ranges and Colons to
# return Ranges or RangeMatrixes. For everything else, we can use the fallbacks.
Base.getindex(R::RepeatedRangeMatrix, I::Union{Range, Colon}, J) = (checkbounds(R, I, J); Base.unsafe_getindex(R, I, J))
Base.unsafe_getindex(R::RepeatedRangeMatrix, I::Union{Range, Colon}, j::Real) = @inbounds return R.r[I] + R.at[j]
Base.unsafe_getindex(R::RepeatedRangeMatrix, I::Union{Range, Colon}, ::Colon) = @inbounds return RepeatedRangeMatrix(R.r[I], R.at[:])
Base.unsafe_getindex(R::RepeatedRangeMatrix, I::Union{Range, Colon}, J) = @inbounds return RepeatedRangeMatrix(R.r[I], R.at[J])
@inline function Base.getindex(R::RepeatedRangeMatrix, I::Union{Range, Colon}, j::Real)
@boundscheck checkbounds(R, I, j)
@inbounds return R.r[I] + R.at[j]
end
@inline function Base.getindex(R::RepeatedRangeMatrix, I::Union{Range, Colon}, J)
@boundscheck checkbounds(R, I, J)
@inbounds return RepeatedRangeMatrix(R.r[I], R.at[J])
end

# We can also optimize bounds checks to only look at the range's endpoints
function Base.checkindex(::Type{Bool}, inds::AbstractUnitRange, R::RepeatedRangeMatrix)
b = true
@inbounds for a in R.at
b &= checkindex(Bool, inds, R.r[1] + a)
b &= checkindex(Bool, inds, R.r[end] + a)
end
b
end
15 changes: 15 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,18 @@ end
@test R[:, 1:2] == RangeMatrix(1:10, 11:20)
@test R[:, 1:4] == R[:,:] == RangeMatrix(1:10, 11:20, 21:30, 31:40)
@test R[:, 3:4] == RangeMatrix(21:30, 31:40)

A = 1:100
@test_throws BoundsError A[RangeMatrix(0:9, 20:29)]
@test_throws BoundsError A[RangeMatrix(20:29, 0:9)]
@test_throws BoundsError A[RangeMatrix(20:29, 92:101)]
@test_throws BoundsError A[RangeMatrix(92:101, 20:29)]
@test_throws BoundsError A[RangeMatrix(-100:100)]
@test A[RangeMatrix(1:10, 91:100)] == [1:10 91:100]

@test_throws BoundsError A[RepeatedRangeMatrix(1:10, [-1,33])]
@test_throws BoundsError A[RepeatedRangeMatrix(1:10, [33,-1])]
@test_throws BoundsError A[RepeatedRangeMatrix(1:10, [91,33])]
@test_throws BoundsError A[RepeatedRangeMatrix(1:10, [33,91])]
@test_throws BoundsError A[RepeatedRangeMatrix(-100:100, [0])]
@test A[RepeatedRangeMatrix(1:10, [0,90])] == [1:10 91:100]

0 comments on commit 435ed6e

Please sign in to comment.