|
1 | 1 | ### Views
|
| 2 | + |
| 3 | +""" |
| 4 | + unblock(block_sizes, inds, I) |
| 5 | +
|
| 6 | +Returns the indices associated with a block as a `BlockSlice`. |
| 7 | +""" |
| 8 | +function unblock(A, inds, I) |
| 9 | + B = first(I) |
| 10 | + if length(inds) == 0 |
| 11 | + # Allow `ones(2)[Block(1)[1:1], Block(1)[1:1]]` which is |
| 12 | + # similar to `ones(2)[1:1, 1:1]`. |
| 13 | + BlockSlice(B,Base.OneTo(1)) |
| 14 | + else |
| 15 | + BlockSlice(B,inds[1][B]) |
| 16 | + end |
| 17 | +end |
| 18 | + |
| 19 | +to_index(::Block) = throw(ArgumentError("Block must be converted by to_indices(...)")) |
| 20 | +to_index(::BlockIndex) = throw(ArgumentError("BlockIndex must be converted by to_indices(...)")) |
2 | 21 | to_index(::BlockIndexRange) = throw(ArgumentError("BlockIndexRange must be converted by to_indices(...)"))
|
| 22 | +to_index(::BlockRange) = throw(ArgumentError("BlockRange must be converted by to_indices(...)")) |
3 | 23 |
|
| 24 | + |
| 25 | +@inline to_indices(A, inds, I::Tuple{Block{1}, Vararg{Any}}) = |
| 26 | + (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) |
| 27 | +@inline to_indices(A, inds, I::Tuple{BlockRange{1,R}, Vararg{Any}}) where R = |
| 28 | + (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) |
| 29 | +@inline to_indices(A, inds, I::Tuple{BlockIndex{1}, Vararg{Any}}) where R = |
| 30 | + (inds[1][I[1]], to_indices(A, _maybetail(inds), tail(I))...) |
4 | 31 | @inline to_indices(A, inds, I::Tuple{BlockIndexRange{1,R}, Vararg{Any}}) where R =
|
5 | 32 | (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...)
|
6 | 33 |
|
7 | 34 | # splat out higher dimensional blocks
|
8 | 35 | # this mimics view of a CartesianIndex
|
| 36 | +@inline to_indices(A, inds, I::Tuple{Block, Vararg{Any}}) = |
| 37 | + to_indices(A, inds, (Block.(I[1].n)..., tail(I)...)) |
| 38 | +@inline to_indices(A, inds, I::Tuple{BlockIndex, Vararg{Any}}) = |
| 39 | + to_indices(A, inds, (BlockIndex.(I[1].I, I[1].α)..., tail(I)...)) |
9 | 40 | @inline to_indices(A, inds, I::Tuple{BlockIndexRange, Vararg{Any}}) =
|
10 |
| - to_indices(A, inds, (BlockRange.(Block.(I[1].block.n), tuple.(I[1].indices))..., tail(I)...)) |
11 |
| - |
| 41 | + to_indices(A, inds, (BlockIndexRange.(Block.(I[1].block.n), tuple.(I[1].indices))..., tail(I)...)) |
| 42 | +@inline to_indices(A, inds, I::Tuple{BlockRange, Vararg{Any}}) = |
| 43 | + to_indices(A, inds, (BlockRange.(tuple.(I[1].indices))..., tail(I)...)) |
12 | 44 |
|
13 | 45 | # In 0.7, we need to override to_indices to avoid calling linearindices
|
14 |
| -@inline to_indices(A, I::Tuple{BlockIndexRange, Vararg{Any}}) = |
15 |
| - to_indices(A, axes(A), I) |
| 46 | +@inline to_indices(A, I::Tuple{BlockIndexRange, Vararg{Any}}) = to_indices(A, axes(A), I) |
| 47 | +@inline to_indices(A, I::Tuple{Block, Vararg{Any}}) = to_indices(A, axes(A), I) |
| 48 | +@inline to_indices(A, I::Tuple{BlockRange, Vararg{Any}}) = to_indices(A, axes(A), I) |
16 | 49 |
|
17 | 50 | if VERSION >= v"1.2-" # See also `reindex` definitions in views.jl
|
18 | 51 | reindex(idxs::Tuple{BlockSlice{<:BlockRange}, Vararg{Any}},
|
|
68 | 101 | end
|
69 | 102 |
|
70 | 103 |
|
71 |
| -""" |
72 |
| - unblock(block_sizes, inds, I) |
73 |
| -
|
74 |
| -Returns the indices associated with a block as a `BlockSlice`. |
75 |
| -""" |
76 |
| -function unblock(A, inds, I) |
77 |
| - B = first(I) |
78 |
| - if length(inds) == 0 |
79 |
| - # Allow `ones(2)[Block(1)[1:1], Block(1)[1:1]]` which is |
80 |
| - # similar to `ones(2)[1:1, 1:1]`. |
81 |
| - BlockSlice(B,Base.OneTo(1)) |
82 |
| - else |
83 |
| - BlockSlice(B,inds[1][B]) |
84 |
| - end |
85 |
| -end |
86 |
| - |
87 |
| - |
88 |
| -to_index(::Block) = throw(ArgumentError("Block must be converted by to_indices(...)")) |
89 |
| -to_index(::BlockIndex) = throw(ArgumentError("BlockIndex must be converted by to_indices(...)")) |
90 |
| -to_index(::BlockRange) = throw(ArgumentError("BlockRange must be converted by to_indices(...)")) |
91 |
| - |
92 |
| -@inline to_indices(A, inds, I::Tuple{Block{1}, Vararg{Any}}) = |
93 |
| - (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) |
94 |
| - |
95 |
| -# splat out higher dimensional blocks |
96 |
| -# this mimics view of a CartesianIndex |
97 |
| -@inline to_indices(A, inds, I::Tuple{Block, Vararg{Any}}) = |
98 |
| - to_indices(A, inds, (Block.(I[1].n)..., tail(I)...)) |
99 |
| - |
100 |
| -@inline to_indices(A, inds, I::Tuple{BlockRange{1,R}, Vararg{Any}}) where R = |
101 |
| - (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) |
102 |
| - |
103 |
| -# splat out higher dimensional blocks |
104 |
| -# this mimics view of a CartesianIndex |
105 |
| -@inline to_indices(A, inds, I::Tuple{BlockRange, Vararg{Any}}) = |
106 |
| - to_indices(A, inds, (BlockRange.(tuple.(I[1].indices))..., tail(I)...)) |
107 |
| - |
108 |
| - |
109 |
| -# In 0.7, we need to override to_indices to avoid calling linearindices |
110 |
| -@inline to_indices(A, I::Tuple{Block, Vararg{Any}}) = |
111 |
| - to_indices(A, axes(A), I) |
112 |
| - |
113 |
| -@inline to_indices(A, I::Tuple{BlockRange, Vararg{Any}}) = |
114 |
| - to_indices(A, axes(A), I) |
115 |
| - |
116 |
| - |
117 | 104 | # The first argument for `reindex` is removed as of
|
118 | 105 | # https://github.com/JuliaLang/julia/pull/30789 in Julia `Base`. So,
|
119 | 106 | # we define 2-arg `reindex` for Julia 1.2 and later.
|
120 | 107 | if VERSION >= v"1.2-"
|
| 108 | + # BlockSlices map the blocks and the indices |
| 109 | + # this is loosely based on Slice reindex in subarray.jl |
| 110 | + reindex(idxs::Tuple{BlockSlice{<:BlockRange}, Vararg{Any}}, |
| 111 | + subidxs::Tuple{BlockSlice{<:BlockRange}, Vararg{Any}}) = |
| 112 | + (@_propagate_inbounds_meta; (BlockSlice(BlockRange(idxs[1].block.indices[1][Int.(subidxs[1].block)]), |
| 113 | + idxs[1].indices[subidxs[1].indices]), |
| 114 | + reindex(tail(idxs), tail(subidxs))...)) |
121 | 115 |
|
122 |
| -# BlockSlices map the blocks and the indices |
123 |
| -# this is loosely based on Slice reindex in subarray.jl |
124 |
| -reindex(idxs::Tuple{BlockSlice{<:BlockRange}, Vararg{Any}}, |
125 |
| - subidxs::Tuple{BlockSlice{<:BlockRange}, Vararg{Any}}) = |
126 |
| - (@_propagate_inbounds_meta; (BlockSlice(BlockRange(idxs[1].block.indices[1][Int.(subidxs[1].block)]), |
127 |
| - idxs[1].indices[subidxs[1].indices]), |
128 |
| - reindex(tail(idxs), tail(subidxs))...)) |
129 |
| - |
130 |
| -reindex(idxs::Tuple{BlockSlice{BlockRange{1,Tuple{UnitRange{Int}}}}, Vararg{Any}}, |
131 |
| - subidxs::Tuple{BlockSlice{Block{1,Int}}, Vararg{Any}}) = |
132 |
| - (@_propagate_inbounds_meta; (BlockSlice(Block(idxs[1].block.indices[1][Int(subidxs[1].block)]), |
133 |
| - idxs[1].indices[subidxs[1].indices]), |
134 |
| - reindex(tail(idxs), tail(subidxs))...)) |
135 |
| - |
136 |
| -function reindex(idxs::Tuple{BlockSlice{Block{1,Int}}, Vararg{Any}}, |
137 |
| - subidxs::Tuple{BlockSlice{Block{1,Int}}, Vararg{Any}}) |
138 |
| - (idxs[1], reindex(tail(idxs), tail(subidxs))...) |
139 |
| -end |
| 116 | + reindex(idxs::Tuple{BlockSlice{BlockRange{1,Tuple{UnitRange{Int}}}}, Vararg{Any}}, |
| 117 | + subidxs::Tuple{BlockSlice{Block{1,Int}}, Vararg{Any}}) = |
| 118 | + (@_propagate_inbounds_meta; (BlockSlice(Block(idxs[1].block.indices[1][Int(subidxs[1].block)]), |
| 119 | + idxs[1].indices[subidxs[1].indices]), |
| 120 | + reindex(tail(idxs), tail(subidxs))...)) |
140 | 121 |
|
| 122 | + function reindex(idxs::Tuple{BlockSlice{Block{1,Int}}, Vararg{Any}}, |
| 123 | + subidxs::Tuple{BlockSlice{Block{1,Int}}, Vararg{Any}}) |
| 124 | + (idxs[1], reindex(tail(idxs), tail(subidxs))...) |
| 125 | + end |
141 | 126 | else # if VERSION >= v"1.2-"
|
| 127 | + reindex(V, idxs::Tuple{BlockSlice{<:BlockRange}, Vararg{Any}}, |
| 128 | + subidxs::Tuple{BlockSlice{<:BlockRange}, Vararg{Any}}) = |
| 129 | + (@_propagate_inbounds_meta; (BlockSlice(BlockRange(idxs[1].block.indices[1][Int.(subidxs[1].block)]), |
| 130 | + idxs[1].indices[subidxs[1].indices]), |
| 131 | + reindex(V, tail(idxs), tail(subidxs))...)) |
142 | 132 |
|
143 |
| -reindex(V, idxs::Tuple{BlockSlice{<:BlockRange}, Vararg{Any}}, |
144 |
| - subidxs::Tuple{BlockSlice{<:BlockRange}, Vararg{Any}}) = |
145 |
| - (@_propagate_inbounds_meta; (BlockSlice(BlockRange(idxs[1].block.indices[1][Int.(subidxs[1].block)]), |
146 |
| - idxs[1].indices[subidxs[1].indices]), |
147 |
| - reindex(V, tail(idxs), tail(subidxs))...)) |
148 |
| - |
149 |
| -reindex(V, idxs::Tuple{BlockSlice{BlockRange{1,Tuple{UnitRange{Int}}}}, Vararg{Any}}, |
150 |
| - subidxs::Tuple{BlockSlice{Block{1,Int}}, Vararg{Any}}) = |
151 |
| - (@_propagate_inbounds_meta; (BlockSlice(Block(idxs[1].block.indices[1][Int(subidxs[1].block)]), |
152 |
| - idxs[1].indices[subidxs[1].indices]), |
153 |
| - reindex(V, tail(idxs), tail(subidxs))...)) |
154 |
| - |
155 |
| -function reindex(V, idxs::Tuple{BlockSlice{Block{1,Int}}, Vararg{Any}}, |
156 |
| - subidxs::Tuple{BlockSlice{Block{1,Int}}, Vararg{Any}}) |
157 |
| - subidxs[1].block == Block(1) || throw(BoundsError(V, subidxs[1].block)) |
158 |
| - (idxs[1], reindex(V, tail(idxs), tail(subidxs))...) |
159 |
| -end |
| 133 | + reindex(V, idxs::Tuple{BlockSlice{BlockRange{1,Tuple{UnitRange{Int}}}}, Vararg{Any}}, |
| 134 | + subidxs::Tuple{BlockSlice{Block{1,Int}}, Vararg{Any}}) = |
| 135 | + (@_propagate_inbounds_meta; (BlockSlice(Block(idxs[1].block.indices[1][Int(subidxs[1].block)]), |
| 136 | + idxs[1].indices[subidxs[1].indices]), |
| 137 | + reindex(V, tail(idxs), tail(subidxs))...)) |
160 | 138 |
|
| 139 | + function reindex(V, idxs::Tuple{BlockSlice{Block{1,Int}}, Vararg{Any}}, |
| 140 | + subidxs::Tuple{BlockSlice{Block{1,Int}}, Vararg{Any}}) |
| 141 | + subidxs[1].block == Block(1) || throw(BoundsError(V, subidxs[1].block)) |
| 142 | + (idxs[1], reindex(V, tail(idxs), tail(subidxs))...) |
| 143 | + end |
161 | 144 | end # if VERSION >= v"1.2-"
|
162 | 145 |
|
163 | 146 |
|
|
0 commit comments