Skip to content

Commit fa071ff

Browse files
authored
Merge pull request #35298 from JuliaLang/teh/collectto
Fix offset when widening collections
2 parents 58034ad + 7a63269 commit fa071ff

File tree

4 files changed

+72
-70
lines changed

4 files changed

+72
-70
lines changed

base/array.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,8 @@ end
696696
function setindex_widen_up_to(dest::AbstractArray{T}, el, i) where T
697697
@_inline_meta
698698
new = similar(dest, promote_typejoin(T, typeof(el)))
699-
copyto!(new, firstindex(new), dest, firstindex(dest), i-1)
699+
f = first(LinearIndices(dest))
700+
copyto!(new, first(LinearIndices(new)), dest, f, i-f)
700701
@inbounds new[i] = el
701702
return new
702703
end

test/abstractarray.jl

Lines changed: 2 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -231,76 +231,9 @@ mutable struct TestAbstractArray end
231231

232232
## Tests for the abstract array interfaces with minimally defined array types
233233

234-
# A custom linear fast array type with 24 elements that doesn't rely upon Array storage
235-
mutable struct T24Linear{T,N,dims} <: AbstractArray{T,N}
236-
v1::T; v2::T; v3::T; v4::T; v5::T; v6::T; v7::T; v8::T
237-
v9::T; v10::T; v11::T; v12::T; v13::T; v14::T; v15::T; v16::T
238-
v17::T; v18::T; v19::T; v20::T; v21::T; v22::T; v23::T; v24::T
239-
T24Linear{T,N,d}() where {T,N,d} =
240-
(prod(d) == 24 || throw(DimensionMismatch("T24Linear must have 24 elements")); new())
241-
function T24Linear{T,N,d}(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,
242-
v13,v14,v15,v16,v17,v18,v19,v20,v21,v22,v23,v24) where {T,N,d}
243-
prod(d) == 24 || throw(DimensionMismatch("T24Linear must have 24 elements"))
244-
new(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,v17,v18,v19,v20,v21,v22,v23,v24)
245-
end
246-
end
247-
248-
T24Linear(::Type{T}, dims::Int...) where T = T24Linear(T, dims)
249-
T24Linear(::Type{T}, dims::NTuple{N,Int}) where {T,N} = T24Linear{T,N,dims}()
250-
251-
T24Linear( X::AbstractArray{T,N}) where {T,N } = T24Linear{T,N}(X)
252-
T24Linear{T }(X::AbstractArray{_,N}) where {T,N,_} = T24Linear{T,N}(X)
253-
T24Linear{T,N}(X::AbstractArray ) where {T,N } = T24Linear{T,N,size(X)}(X...)
254-
255-
Base.size(::T24Linear{T,N,dims}) where {T,N,dims} = dims
256-
import Base: IndexLinear
257-
Base.IndexStyle(::Type{A}) where {A<:T24Linear} = IndexLinear()
258-
Base.getindex(A::T24Linear, i::Int) = getfield(A, i)
259-
Base.setindex!(A::T24Linear{T}, v, i::Int) where {T} = setfield!(A, i, convert(T, v))
260-
261-
# A custom linear slow sparse-like array that relies upon Dict for its storage
262-
struct TSlow{T,N} <: AbstractArray{T,N}
263-
data::Dict{NTuple{N,Int}, T}
264-
dims::NTuple{N,Int}
234+
if !isdefined(@__MODULE__, :T24Linear)
235+
include("testhelpers/arrayindexingtypes.jl")
265236
end
266-
TSlow(::Type{T}, dims::Int...) where {T} = TSlow(T, dims)
267-
TSlow(::Type{T}, dims::NTuple{N,Int}) where {T,N} = TSlow{T,N}(Dict{NTuple{N,Int}, T}(), dims)
268-
269-
TSlow{T,N}(X::TSlow{T,N}) where {T,N } = X
270-
TSlow( X::AbstractArray{T,N}) where {T,N } = TSlow{T,N}(X)
271-
TSlow{T }(X::AbstractArray{_,N}) where {T,N,_} = TSlow{T,N}(X)
272-
TSlow{T,N}(X::AbstractArray ) where {T,N } = begin
273-
A = TSlow(T, size(X))
274-
for I in CartesianIndices(size(X))
275-
A[I.I...] = X[I.I...]
276-
end
277-
A
278-
end
279-
280-
Base.size(A::TSlow) = A.dims
281-
Base.similar(A::TSlow, ::Type{T}, dims::Dims) where {T} = TSlow(T, dims)
282-
import Base: IndexCartesian
283-
Base.IndexStyle(::Type{A}) where {A<:TSlow} = IndexCartesian()
284-
# Until #11242 is merged, we need to define each dimension independently
285-
Base.getindex(A::TSlow{T,0}) where {T} = get(A.data, (), zero(T))
286-
Base.getindex(A::TSlow{T,1}, i1::Int) where {T} = get(A.data, (i1,), zero(T))
287-
Base.getindex(A::TSlow{T,2}, i1::Int, i2::Int) where {T} = get(A.data, (i1,i2), zero(T))
288-
Base.getindex(A::TSlow{T,3}, i1::Int, i2::Int, i3::Int) where {T} =
289-
get(A.data, (i1,i2,i3), zero(T))
290-
Base.getindex(A::TSlow{T,4}, i1::Int, i2::Int, i3::Int, i4::Int) where {T} =
291-
get(A.data, (i1,i2,i3,i4), zero(T))
292-
Base.getindex(A::TSlow{T,5}, i1::Int, i2::Int, i3::Int, i4::Int, i5::Int) where {T} =
293-
get(A.data, (i1,i2,i3,i4,i5), zero(T))
294-
295-
Base.setindex!(A::TSlow{T,0}, v) where {T} = (A.data[()] = v)
296-
Base.setindex!(A::TSlow{T,1}, v, i1::Int) where {T} = (A.data[(i1,)] = v)
297-
Base.setindex!(A::TSlow{T,2}, v, i1::Int, i2::Int) where {T} = (A.data[(i1,i2)] = v)
298-
Base.setindex!(A::TSlow{T,3}, v, i1::Int, i2::Int, i3::Int) where {T} =
299-
(A.data[(i1,i2,i3)] = v)
300-
Base.setindex!(A::TSlow{T,4}, v, i1::Int, i2::Int, i3::Int, i4::Int) where {T} =
301-
(A.data[(i1,i2,i3,i4)] = v)
302-
Base.setindex!(A::TSlow{T,5}, v, i1::Int, i2::Int, i3::Int, i4::Int, i5::Int) where {T} =
303-
(A.data[(i1,i2,i3,i4,i5)] = v)
304237

305238
const can_inline = Base.JLOptions().can_inline != 0
306239
function test_scalar_indexing(::Type{T}, shape, ::Type{TestAbstractArray}) where T

test/offsetarray.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ using Statistics
99

1010
const OAs_name = join(fullname(OffsetArrays), ".")
1111

12+
if !isdefined(@__MODULE__, :T24Linear)
13+
include("testhelpers/arrayindexingtypes.jl")
14+
end
15+
1216
let
1317
# Basics
1418
v0 = rand(4)
@@ -332,6 +336,16 @@ am = map(identity, a)
332336
@test isa(am, OffsetArray)
333337
@test am == a
334338

339+
# https://github.com/JuliaArrays/OffsetArrays.jl/issues/106
340+
@test isequal(map(!, OffsetArray([true,missing],2)), OffsetArray([false, missing], 2))
341+
@test isequal(map(!, OffsetArray([true missing; false true], 2, -1)), OffsetArray([false missing; true false], 2, -1))
342+
P = view([true missing; false true; true false], 1:2:3, :)
343+
@test IndexStyle(P) === IndexCartesian()
344+
@test isequal(map(!, OffsetArray(P, 2, -1)), OffsetArray(map(!, P), 2, -1))
345+
P = TSlow([true missing; false true])
346+
@test IndexStyle(P) === IndexCartesian()
347+
@test isequal(map(!, OffsetArray(P, 2, -1)), OffsetArray(map(!, P), 2, -1))
348+
335349
# dropdims
336350
a0 = rand(1,1,8,8,1)
337351
a = OffsetArray(a0, (-1,2,3,4,5))
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
## Tests for the abstract array interfaces and operations with arrays
2+
## with different indexing rules
3+
4+
# A custom linear fast array type with 24 elements that doesn't rely upon Array storage
5+
mutable struct T24Linear{T,N,dims} <: AbstractArray{T,N}
6+
v1::T; v2::T; v3::T; v4::T; v5::T; v6::T; v7::T; v8::T
7+
v9::T; v10::T; v11::T; v12::T; v13::T; v14::T; v15::T; v16::T
8+
v17::T; v18::T; v19::T; v20::T; v21::T; v22::T; v23::T; v24::T
9+
T24Linear{T,N,d}() where {T,N,d} =
10+
(prod(d) == 24 || throw(DimensionMismatch("T24Linear must have 24 elements")); new())
11+
function T24Linear{T,N,d}(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,
12+
v13,v14,v15,v16,v17,v18,v19,v20,v21,v22,v23,v24) where {T,N,d}
13+
prod(d) == 24 || throw(DimensionMismatch("T24Linear must have 24 elements"))
14+
new(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,v17,v18,v19,v20,v21,v22,v23,v24)
15+
end
16+
end
17+
18+
T24Linear(::Type{T}, dims::Int...) where T = T24Linear(T, dims)
19+
T24Linear(::Type{T}, dims::NTuple{N,Int}) where {T,N} = T24Linear{T,N,dims}()
20+
21+
T24Linear( X::AbstractArray{T,N}) where {T,N } = T24Linear{T,N}(X)
22+
T24Linear{T }(X::AbstractArray{_,N}) where {T,N,_} = T24Linear{T,N}(X)
23+
T24Linear{T,N}(X::AbstractArray ) where {T,N } = T24Linear{T,N,size(X)}(X...)
24+
25+
Base.size(::T24Linear{T,N,dims}) where {T,N,dims} = dims
26+
import Base: IndexLinear
27+
Base.IndexStyle(::Type{A}) where {A<:T24Linear} = IndexLinear()
28+
Base.getindex(A::T24Linear, i::Int) = getfield(A, i)
29+
Base.setindex!(A::T24Linear{T}, v, i::Int) where {T} = setfield!(A, i, convert(T, v))
30+
31+
# A custom linear slow sparse-like array that relies upon Dict for its storage
32+
struct TSlow{T,N} <: AbstractArray{T,N}
33+
data::Dict{NTuple{N,Int}, T}
34+
dims::NTuple{N,Int}
35+
end
36+
TSlow(::Type{T}, dims::Int...) where {T} = TSlow(T, dims)
37+
TSlow(::Type{T}, dims::NTuple{N,Int}) where {T,N} = TSlow{T,N}(Dict{NTuple{N,Int}, T}(), dims)
38+
39+
TSlow{T,N}(X::TSlow{T,N}) where {T,N } = X
40+
TSlow( X::AbstractArray{T,N}) where {T,N } = TSlow{T,N}(X)
41+
TSlow{T }(X::AbstractArray{_,N}) where {T,N,_} = TSlow{T,N}(X)
42+
TSlow{T,N}(X::AbstractArray ) where {T,N } = begin
43+
A = TSlow(T, size(X))
44+
for I in CartesianIndices(X)
45+
A[Tuple(I)...] = X[Tuple(I)...]
46+
end
47+
A
48+
end
49+
50+
Base.size(A::TSlow) = A.dims
51+
Base.similar(A::TSlow, ::Type{T}, dims::Dims) where {T} = TSlow(T, dims)
52+
Base.IndexStyle(::Type{A}) where {A<:TSlow} = IndexCartesian()
53+
Base.getindex(A::TSlow{T,N}, i::Vararg{Int,N}) where {T,N} = get(A.data, i, zero(T))
54+
Base.setindex!(A::TSlow{T,N}, v, i::Vararg{Int,N}) where {T,N} = (A.data[i] = v)

0 commit comments

Comments
 (0)