Skip to content

Commit e95b5e2

Browse files
committed
Move OffsetArray definition to TestHelpers
1 parent 9f017a0 commit e95b5e2

File tree

2 files changed

+104
-103
lines changed

2 files changed

+104
-103
lines changed

test/TestHelpers.jl

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,101 @@ function with_fake_pty(f)
4343
close(master)
4444
end
4545

46+
# OffsetArrays (arrays with indexing that doesn't start at 1)
47+
48+
# This test file is designed to exercise support for generic indexing,
49+
# even though offset arrays aren't implemented in Base.
50+
51+
module OAs
52+
53+
using Base: Indices, LinearSlow, LinearFast, tail
54+
55+
export OffsetArray
56+
57+
immutable OffsetArray{T,N,AA<:AbstractArray} <: AbstractArray{T,N}
58+
parent::AA
59+
offsets::NTuple{N,Int}
60+
end
61+
typealias OffsetVector{T,AA<:AbstractArray} OffsetArray{T,1,AA}
62+
63+
OffsetArray{T,N}(A::AbstractArray{T,N}, offsets::NTuple{N,Int}) = OffsetArray{T,N,typeof(A)}(A, offsets)
64+
OffsetArray{T,N}(A::AbstractArray{T,N}, offsets::Vararg{Int,N}) = OffsetArray(A, offsets)
65+
66+
(::Type{OffsetArray{T,N}}){T,N}(inds::Indices{N}) = OffsetArray{T,N,Array{T,N}}(Array{T,N}(map(length, inds)), map(indsoffset, inds))
67+
(::Type{OffsetArray{T}}){T,N}(inds::Indices{N}) = OffsetArray{T,N}(inds)
68+
69+
Base.linearindexing{T<:OffsetArray}(::Type{T}) = Base.linearindexing(parenttype(T))
70+
parenttype{T,N,AA}(::Type{OffsetArray{T,N,AA}}) = AA
71+
parenttype(A::OffsetArray) = parenttype(typeof(A))
72+
73+
Base.parent(A::OffsetArray) = A.parent
74+
75+
errmsg(A) = error("size not supported for arrays with indices $(indices(A)); see http://docs.julialang.org/en/latest/devdocs/offset-arrays/")
76+
Base.size(A::OffsetArray) = errmsg(A)
77+
Base.size(A::OffsetArray, d) = errmsg(A)
78+
Base.eachindex(::LinearSlow, A::OffsetArray) = CartesianRange(indices(A))
79+
Base.eachindex(::LinearFast, A::OffsetVector) = indices(A, 1)
80+
81+
# Implementations of indices and indices1. Since bounds-checking is
82+
# performance-critical and relies on indices, these are usually worth
83+
# optimizing thoroughly.
84+
@inline Base.indices(A::OffsetArray, d) = 1 <= d <= length(A.offsets) ? indices(parent(A))[d] + A.offsets[d] : (1:1)
85+
@inline Base.indices(A::OffsetArray) = _indices(indices(parent(A)), A.offsets) # would rather use ntuple, but see #15276
86+
@inline _indices(inds, offsets) = (inds[1]+offsets[1], _indices(tail(inds), tail(offsets))...)
87+
_indices(::Tuple{}, ::Tuple{}) = ()
88+
Base.indices1{T}(A::OffsetArray{T,0}) = 1:1 # we only need to specialize this one
89+
90+
function Base.similar(A::OffsetArray, T::Type, dims::Dims)
91+
B = similar(parent(A), T, dims)
92+
end
93+
function Base.similar(A::AbstractArray, T::Type, inds::Tuple{UnitRange,Vararg{UnitRange}})
94+
B = similar(A, T, map(length, inds))
95+
OffsetArray(B, map(indsoffset, inds))
96+
end
97+
98+
Base.similar(f::Union{Function,DataType}, shape::Tuple{UnitRange,Vararg{UnitRange}}) = OffsetArray(f(map(length, shape)), map(indsoffset, shape))
99+
100+
Base.reshape(A::AbstractArray, inds::Tuple{UnitRange,Vararg{UnitRange}}) = OffsetArray(reshape(A, map(length, inds)), map(indsoffset, inds))
101+
102+
@inline function Base.getindex{T,N}(A::OffsetArray{T,N}, I::Vararg{Int,N})
103+
checkbounds(A, I...)
104+
@inbounds ret = parent(A)[offset(A.offsets, I)...]
105+
ret
106+
end
107+
@inline function Base._getindex(::LinearFast, A::OffsetVector, i::Int)
108+
checkbounds(A, i)
109+
@inbounds ret = parent(A)[offset(A.offsets, (i,))[1]]
110+
ret
111+
end
112+
@inline function Base._getindex(::LinearFast, A::OffsetArray, i::Int)
113+
checkbounds(A, i)
114+
@inbounds ret = parent(A)[i]
115+
ret
116+
end
117+
@inline function Base.setindex!{T,N}(A::OffsetArray{T,N}, val, I::Vararg{Int,N})
118+
checkbounds(A, I...)
119+
@inbounds parent(A)[offset(A.offsets, I)...] = val
120+
val
121+
end
122+
@inline function Base._setindex!(::LinearFast, A::OffsetVector, val, i::Int)
123+
checkbounds(A, i)
124+
@inbounds parent(A)[offset(A.offsets, (i,))[1]] = val
125+
val
126+
end
127+
@inline function Base._setindex!(::LinearFast, A::OffsetArray, val, i::Int)
128+
checkbounds(A, i)
129+
@inbounds parent(A)[i] = val
130+
val
131+
end
132+
133+
# Computing a shifted index (subtracting the offset)
134+
offset{N}(offsets::NTuple{N,Int}, inds::NTuple{N,Int}) = _offset((), offsets, inds)
135+
_offset(out, ::Tuple{}, ::Tuple{}) = out
136+
@inline _offset(out, offsets, inds) = _offset((out..., inds[1]-offsets[1]), Base.tail(offsets), Base.tail(inds))
137+
138+
indsoffset(r::Range) = first(r) - 1
139+
indsoffset(i::Integer) = 0
140+
141+
end
142+
46143
end

test/offsetarray.jl

Lines changed: 7 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,7 @@
11
# This file is a part of Julia. License is MIT: http://julialang.org/license
22

3-
# OffsetArrays (arrays with indexing that doesn't start at 1)
4-
5-
# This test file is designed to exercise support for generic indexing,
6-
# even though offset arrays aren't implemented in Base.
7-
8-
module OAs
9-
10-
using Base: Indices, LinearSlow, LinearFast, tail
11-
12-
export OffsetArray
13-
14-
immutable OffsetArray{T,N,AA<:AbstractArray} <: AbstractArray{T,N}
15-
parent::AA
16-
offsets::NTuple{N,Int}
17-
end
18-
typealias OffsetVector{T,AA<:AbstractArray} OffsetArray{T,1,AA}
19-
20-
OffsetArray{T,N}(A::AbstractArray{T,N}, offsets::NTuple{N,Int}) = OffsetArray{T,N,typeof(A)}(A, offsets)
21-
OffsetArray{T,N}(A::AbstractArray{T,N}, offsets::Vararg{Int,N}) = OffsetArray(A, offsets)
22-
23-
(::Type{OffsetArray{T,N}}){T,N}(inds::Indices{N}) = OffsetArray{T,N,Array{T,N}}(Array{T,N}(map(length, inds)), map(indsoffset, inds))
24-
(::Type{OffsetArray{T}}){T,N}(inds::Indices{N}) = OffsetArray{T,N}(inds)
25-
26-
Base.linearindexing{T<:OffsetArray}(::Type{T}) = Base.linearindexing(parenttype(T))
27-
parenttype{T,N,AA}(::Type{OffsetArray{T,N,AA}}) = AA
28-
parenttype(A::OffsetArray) = parenttype(typeof(A))
29-
30-
Base.parent(A::OffsetArray) = A.parent
31-
32-
errmsg(A) = error("size not supported for arrays with indices $(indices(A)); see http://docs.julialang.org/en/latest/devdocs/offset-arrays/")
33-
Base.size(A::OffsetArray) = errmsg(A)
34-
Base.size(A::OffsetArray, d) = errmsg(A)
35-
Base.eachindex(::LinearSlow, A::OffsetArray) = CartesianRange(indices(A))
36-
Base.eachindex(::LinearFast, A::OffsetVector) = indices(A, 1)
37-
38-
# Implementations of indices and indices1. Since bounds-checking is
39-
# performance-critical and relies on indices, these are usually worth
40-
# optimizing thoroughly.
41-
@inline Base.indices(A::OffsetArray, d) = 1 <= d <= length(A.offsets) ? indices(parent(A))[d] + A.offsets[d] : (1:1)
42-
@inline Base.indices(A::OffsetArray) = _indices(indices(parent(A)), A.offsets) # would rather use ntuple, but see #15276
43-
@inline _indices(inds, offsets) = (inds[1]+offsets[1], _indices(tail(inds), tail(offsets))...)
44-
_indices(::Tuple{}, ::Tuple{}) = ()
45-
Base.indices1{T}(A::OffsetArray{T,0}) = 1:1 # we only need to specialize this one
46-
47-
function Base.similar(A::OffsetArray, T::Type, dims::Dims)
48-
B = similar(parent(A), T, dims)
49-
end
50-
function Base.similar(A::AbstractArray, T::Type, inds::Tuple{UnitRange,Vararg{UnitRange}})
51-
B = similar(A, T, map(length, inds))
52-
OffsetArray(B, map(indsoffset, inds))
53-
end
54-
55-
Base.similar(f::Union{Function,DataType}, shape::Tuple{UnitRange,Vararg{UnitRange}}) = OffsetArray(f(map(length, shape)), map(indsoffset, shape))
56-
57-
Base.reshape(A::AbstractArray, inds::Tuple{UnitRange,Vararg{UnitRange}}) = OffsetArray(reshape(A, map(length, inds)), map(indsoffset, inds))
58-
59-
@inline function Base.getindex{T,N}(A::OffsetArray{T,N}, I::Vararg{Int,N})
60-
checkbounds(A, I...)
61-
@inbounds ret = parent(A)[offset(A.offsets, I)...]
62-
ret
63-
end
64-
@inline function Base._getindex(::LinearFast, A::OffsetVector, i::Int)
65-
checkbounds(A, i)
66-
@inbounds ret = parent(A)[offset(A.offsets, (i,))[1]]
67-
ret
68-
end
69-
@inline function Base._getindex(::LinearFast, A::OffsetArray, i::Int)
70-
checkbounds(A, i)
71-
@inbounds ret = parent(A)[i]
72-
ret
73-
end
74-
@inline function Base.setindex!{T,N}(A::OffsetArray{T,N}, val, I::Vararg{Int,N})
75-
checkbounds(A, I...)
76-
@inbounds parent(A)[offset(A.offsets, I)...] = val
77-
val
78-
end
79-
@inline function Base._setindex!(::LinearFast, A::OffsetVector, val, i::Int)
80-
checkbounds(A, i)
81-
@inbounds parent(A)[offset(A.offsets, (i,))[1]] = val
82-
val
83-
end
84-
@inline function Base._setindex!(::LinearFast, A::OffsetArray, val, i::Int)
85-
checkbounds(A, i)
86-
@inbounds parent(A)[i] = val
87-
val
88-
end
89-
90-
# Computing a shifted index (subtracting the offset)
91-
offset{N}(offsets::NTuple{N,Int}, inds::NTuple{N,Int}) = _offset((), offsets, inds)
92-
_offset(out, ::Tuple{}, ::Tuple{}) = out
93-
@inline _offset(out, offsets, inds) = _offset((out..., inds[1]-offsets[1]), Base.tail(offsets), Base.tail(inds))
94-
95-
indsoffset(r::Range) = first(r) - 1
96-
indsoffset(i::Integer) = 0
97-
98-
end
99-
100-
using OAs
3+
isdefined(:TestHelpers) || include(joinpath(dirname(@__FILE__), "TestHelpers.jl"))
4+
using TestHelpers.OAs
1015

1026
let
1037
# Basics
@@ -219,11 +123,11 @@ cmp_showf(Base.print_matrix, io, OffsetArray(rand(5,5), (10,-9))) # rows&c
219123
cmp_showf(Base.print_matrix, io, OffsetArray(rand(10^3,5), (10,-9))) # columns fit
220124
cmp_showf(Base.print_matrix, io, OffsetArray(rand(5,10^3), (10,-9))) # rows fit
221125
cmp_showf(Base.print_matrix, io, OffsetArray(rand(10^3,10^3), (10,-9))) # neither fits
222-
targets1 = ["0-dimensional OAs.OffsetArray{Float64,0,Array{Float64,0}}:\n1.0",
223-
"OAs.OffsetArray{Float64,1,Array{Float64,1}} with indices 2:2:\n 1.0",
224-
"OAs.OffsetArray{Float64,2,Array{Float64,2}} with indices 2:2×3:3:\n 1.0",
225-
"OAs.OffsetArray{Float64,3,Array{Float64,3}} with indices 2:2×3:3×4:4:\n[:, :, 4] =\n 1.0",
226-
"OAs.OffsetArray{Float64,4,Array{Float64,4}} with indices 2:2×3:3×4:4×5:5:\n[:, :, 4, 5] =\n 1.0"]
126+
targets1 = ["0-dimensional TestHelpers.OAs.OffsetArray{Float64,0,Array{Float64,0}}:\n1.0",
127+
"TestHelpers.OAs.OffsetArray{Float64,1,Array{Float64,1}} with indices 2:2:\n 1.0",
128+
"TestHelpers.OAs.OffsetArray{Float64,2,Array{Float64,2}} with indices 2:2×3:3:\n 1.0",
129+
"TestHelpers.OAs.OffsetArray{Float64,3,Array{Float64,3}} with indices 2:2×3:3×4:4:\n[:, :, 4] =\n 1.0",
130+
"TestHelpers.OAs.OffsetArray{Float64,4,Array{Float64,4}} with indices 2:2×3:3×4:4×5:5:\n[:, :, 4, 5] =\n 1.0"]
227131
targets2 = ["(1.0,1.0)",
228132
"([1.0],[1.0])",
229133
"(\n[1.0],\n\n[1.0])",

0 commit comments

Comments
 (0)