Skip to content

Commit

Permalink
Drop compat code for CartesianIndices and LinearIndices from #446
Browse files Browse the repository at this point in the history
…and #455
  • Loading branch information
martinholters committed Oct 4, 2019
1 parent c915545 commit 233e69f
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 155 deletions.
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,6 @@ Currently, the `@compat` macro supports the following syntaxes:
* `@compat finalizer(func, obj)` with the finalizer to run as the first argument and the object to be finalized
as the second ([#24605]).

* `CartesianIndices` and `LinearIndices` types represent cartesian and linear indices of
an array (respectively), and indexing such objects allows translating from one kind of index
to the other ([#25113]).

* `codeunits(s)` returns an array-like view of the `UInt8` code units of
a string and `ncodeunits(s)` returns the number of code units ([#25241]).
`codeunit(s)` returns the type of the code units of `s` ([#24999]).
Expand Down
128 changes: 0 additions & 128 deletions src/Compat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,134 +70,6 @@ end
end
end

@static if VERSION < v"0.7.0-DEV.3025"
import Base: convert, ndims, getindex, size, length, eltype,
start, next, done, first, last, in, tail
export CartesianIndices, LinearIndices

struct CartesianIndices{N,R<:NTuple{N,AbstractUnitRange{Int}}} <: AbstractArray{CartesianIndex{N},N}
indices::R
end

CartesianIndices(::Tuple{}) = CartesianIndices{0,typeof(())}(())
CartesianIndices(inds::NTuple{N,AbstractUnitRange{Int}}) where {N} =
CartesianIndices{N,typeof(inds)}(inds)
CartesianIndices(inds::Vararg{AbstractUnitRange{Int},N}) where {N} =
CartesianIndices(inds)
CartesianIndices(inds::NTuple{N,AbstractUnitRange{<:Integer}}) where {N} =
CartesianIndices(map(r->convert(AbstractUnitRange{Int}, r), inds))
CartesianIndices(inds::Vararg{AbstractUnitRange{<:Integer},N}) where {N} =
CartesianIndices(inds)

CartesianIndices(index::CartesianIndex) = CartesianIndices(index.I)
CartesianIndices(sz::NTuple{N,<:Integer}) where {N} = CartesianIndices(map(Base.OneTo, sz))
CartesianIndices(inds::NTuple{N,Union{<:Integer,AbstractUnitRange{<:Integer}}}) where {N} =
CartesianIndices(map(i->first(i):last(i), inds))

CartesianIndices(A::AbstractArray) = CartesianIndices(axes(A))

convert(::Type{Tuple{}}, R::CartesianIndices{0}) = ()
convert(::Type{NTuple{N,AbstractUnitRange{Int}}}, R::CartesianIndices{N}) where {N} =
R.indices

convert(::Type{NTuple{N,AbstractUnitRange}}, R::CartesianIndices{N}) where {N} =
convert(NTuple{N,AbstractUnitRange{Int}}, R)
convert(::Type{NTuple{N,UnitRange{Int}}}, R::CartesianIndices{N}) where {N} =
UnitRange{Int}.(convert(NTuple{N,AbstractUnitRange}, R))
convert(::Type{NTuple{N,UnitRange}}, R::CartesianIndices{N}) where {N} =
UnitRange.(convert(NTuple{N,AbstractUnitRange}, R))
convert(::Type{Tuple{Vararg{AbstractUnitRange{Int}}}}, R::CartesianIndices{N}) where {N} =
convert(NTuple{N,AbstractUnitRange{Int}}, R)
convert(::Type{Tuple{Vararg{AbstractUnitRange}}}, R::CartesianIndices) =
convert(Tuple{Vararg{AbstractUnitRange{Int}}}, R)
convert(::Type{Tuple{Vararg{UnitRange{Int}}}}, R::CartesianIndices{N}) where {N} =
convert(NTuple{N,UnitRange{Int}}, R)
convert(::Type{Tuple{Vararg{UnitRange}}}, R::CartesianIndices) =
convert(Tuple{Vararg{UnitRange{Int}}}, R)

# AbstractArray implementation
Base.IndexStyle(::Type{CartesianIndices{N,R}}) where {N,R} = IndexCartesian()
@inline Base.getindex(iter::CartesianIndices{N,R}, I::Vararg{Int, N}) where {N,R} = CartesianIndex(first.(iter.indices) .- 1 .+ I)

ndims(R::CartesianIndices) = ndims(typeof(R))
ndims(::Type{CartesianIndices{N}}) where {N} = N
ndims(::Type{CartesianIndices{N,TT}}) where {N,TT} = N

eltype(R::CartesianIndices) = eltype(typeof(R))
eltype(::Type{CartesianIndices{N}}) where {N} = CartesianIndex{N}
eltype(::Type{CartesianIndices{N,TT}}) where {N,TT} = CartesianIndex{N}
Base.iteratorsize(::Type{<:CartesianIndices}) = Base.HasShape()

@inline function start(iter::CartesianIndices)
iterfirst, iterlast = first(iter), last(iter)
if Base.any(map(>, iterfirst.I, iterlast.I))
return iterlast+1
end
iterfirst
end
@inline function next(iter::CartesianIndices, state)
state, CartesianIndex(inc(state.I, first(iter).I, last(iter).I))
end
# increment & carry
@inline inc(::Tuple{}, ::Tuple{}, ::Tuple{}) = ()
@inline inc(state::Tuple{Int}, start::Tuple{Int}, stop::Tuple{Int}) = (state[1]+1,)
@inline function inc(state, start, stop)
if state[1] < stop[1]
return (state[1]+1,Base.tail(state)...)
end
newtail = inc(Base.tail(state), Base.tail(start), Base.tail(stop))
(start[1], newtail...)
end
@inline done(iter::CartesianIndices, state) = state.I[end] > last(iter.indices[end])

# 0-d cartesian ranges are special-cased to iterate once and only once
start(iter::CartesianIndices{0}) = false
next(iter::CartesianIndices{0}, state) = CartesianIndex(), true
done(iter::CartesianIndices{0}, state) = state

size(iter::CartesianIndices) = map(dimlength, first(iter).I, last(iter).I)
dimlength(start, stop) = stop-start+1

length(iter::CartesianIndices) = Base.prod(size(iter))

first(iter::CartesianIndices) = CartesianIndex(map(first, iter.indices))
last(iter::CartesianIndices) = CartesianIndex(map(last, iter.indices))

@inline function in(i::CartesianIndex{N}, r::CartesianIndices{N}) where {N}
_in(true, i.I, first(r).I, last(r).I)
end
_in(b, ::Tuple{}, ::Tuple{}, ::Tuple{}) = b
@inline _in(b, i, start, stop) = _in(b & (start[1] <= i[1] <= stop[1]), tail(i), tail(start), tail(stop))

struct LinearIndices{N,R<:NTuple{N,AbstractUnitRange{Int}}} <: AbstractArray{Int,N}
indices::R
end

LinearIndices(inds::CartesianIndices{N,R}) where {N,R} = LinearIndices{N,R}(inds.indices)
LinearIndices(::Tuple{}) = LinearIndices(CartesianIndices(()))
LinearIndices(inds::NTuple{N,AbstractUnitRange{Int}}) where {N} = LinearIndices(CartesianIndices(inds))
LinearIndices(inds::Vararg{AbstractUnitRange{Int},N}) where {N} = LinearIndices(CartesianIndices(inds))
LinearIndices(inds::NTuple{N,AbstractUnitRange{<:Integer}}) where {N} = LinearIndices(CartesianIndices(inds))
LinearIndices(inds::Vararg{AbstractUnitRange{<:Integer},N}) where {N} = LinearIndices(CartesianIndices(inds))
LinearIndices(index::CartesianIndex) = LinearIndices(CartesianIndices(index))
LinearIndices(sz::NTuple{N,<:Integer}) where {N} = LinearIndices(CartesianIndices(sz))
LinearIndices(inds::NTuple{N,Union{<:Integer,AbstractUnitRange{<:Integer}}}) where {N} = LinearIndices(CartesianIndices(inds))
LinearIndices(A::AbstractArray) = LinearIndices(CartesianIndices(A))

# AbstractArray implementation
Base.IndexStyle(::Type{LinearIndices{N,R}}) where {N,R} = IndexCartesian()
Compat.axes(iter::LinearIndices{N,R}) where {N,R} = iter.indices
Base.size(iter::LinearIndices{N,R}) where {N,R} = length.(iter.indices)
@inline function Base.getindex(iter::LinearIndices{N,R}, I::Vararg{Int, N}) where {N,R}
dims = length.(iter.indices)
#without the inbounds, this is slower than Base._sub2ind(iter.indices, I...)
@inbounds result = reshape(1:Base.prod(dims), dims)[(I .- first.(iter.indices) .+ 1)...]
return result
end
elseif VERSION < v"0.7.0-DEV.3395"
Base.size(iter::LinearIndices{N,R}) where {N,R} = length.(iter.indices)
end

@static if !isdefined(Base, Symbol("@info"))
macro info(msg, args...)
return :(info($(esc(msg)), prefix = "Info: "))
Expand Down
23 changes: 23 additions & 0 deletions test/old.jl
Original file line number Diff line number Diff line change
Expand Up @@ -613,3 +613,26 @@ end
let A = [0, 0, 0], B = [1, 2, 3]
@test unsafe_copyto!(A, 2, B, 1, 1) === A == [0, 1, 0]
end

# 0.7.0-DEV.3025
let c = CartesianIndices((1:3, 1:2)), l = LinearIndices((1:3, 1:2))
@test LinearIndices(c) == collect(l)
@test CartesianIndices(l) == collect(c)
@test first(c) == CartesianIndex(1, 1)
@test CartesianIndex(1, 1) in c
@test first(l) == 1
@test size(c) == size(l) == (3, 2)
@test c == collect(c) == [CartesianIndex(1, 1) CartesianIndex(1, 2)
CartesianIndex(2, 1) CartesianIndex(2, 2)
CartesianIndex(3, 1) CartesianIndex(3, 2)]
@test l == collect(l) == reshape(1:6, 3, 2)
@test c[1:6] == vec(c)
@test l[1:6] == vec(l)
# TODO the following test fails on current Julia master (since 0.7.0-DEV.4742), and
# it's not clear yet whether it should work or not. See
# https://github.com/JuliaLang/julia/pull/26682#issuecomment-379762632 and the
# discussion following it
#@test l == l[c] == map(i -> l[i], c)
@test l[vec(c)] == collect(1:6)
@test CartesianIndex(1, 1) in CartesianIndices((3, 4))
end
23 changes: 0 additions & 23 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -80,29 +80,6 @@ let A = [1]
@test x == 1
end

# 0.7.0-DEV.3025
let c = CartesianIndices((1:3, 1:2)), l = LinearIndices((1:3, 1:2))
@test LinearIndices(c) == collect(l)
@test CartesianIndices(l) == collect(c)
@test first(c) == CartesianIndex(1, 1)
@test CartesianIndex(1, 1) in c
@test first(l) == 1
@test size(c) == size(l) == (3, 2)
@test c == collect(c) == [CartesianIndex(1, 1) CartesianIndex(1, 2)
CartesianIndex(2, 1) CartesianIndex(2, 2)
CartesianIndex(3, 1) CartesianIndex(3, 2)]
@test l == collect(l) == reshape(1:6, 3, 2)
@test c[1:6] == vec(c)
@test l[1:6] == vec(l)
# TODO the following test fails on current Julia master (since 0.7.0-DEV.4742), and
# it's not clear yet whether it should work or not. See
# https://github.com/JuliaLang/julia/pull/26682#issuecomment-379762632 and the
# discussion following it
#@test l == l[c] == map(i -> l[i], c)
@test l[vec(c)] == collect(1:6)
@test CartesianIndex(1, 1) in CartesianIndices((3, 4))
end

if !isdefined(Base, Symbol("@info"))
let fname = tempname()
try
Expand Down

0 comments on commit 233e69f

Please sign in to comment.