|
1 ####################################### |
|
2 # Simultaneous view to multiple arrays |
|
3 ####################################### |
|
4 |
|
5 """ |
|
6 Implements a type for zipped arrays; see `ZipArray`, `AbstractZipArray`, |
|
7 `ZipVector`, and `AbstractZipVector`. |
|
8 """ |
|
9 module ZipArrays |
|
10 |
|
11 export ZipArray, |
|
12 ZipVector, |
|
13 AbstractZipArray, |
|
14 AbstractZipVector |
|
15 |
|
16 """ |
|
17 `ZipArray{S,T,N,A,B}` |
|
18 |
|
19 `N`-dimensional array of element type `Tuple{S,T}`, the component of the tuple stored in separate |
|
20 arrays of type `A <: AbstractArray{S,N}` and `B <: AbstractArray{T,N}`. |
|
21 """ |
|
22 struct ZipArray{S,T,N,A <: AbstractArray{S,N}, B <: AbstractArray{T,N}} <: AbstractArray{Tuple{S,T}, N} |
|
23 a :: A |
|
24 b :: B |
|
25 |
|
26 function ZipArray(a :: A, b :: B) where {S,T,N,A <: AbstractArray{S,N}, B <: AbstractArray{T,N}} |
|
27 @assert(IndexStyle(A)==IndexStyle(B)) |
|
28 @assert(size(a)==size(b)) |
|
29 return new{S,T,N,A,B}(a, b) |
|
30 end |
|
31 |
|
32 end |
|
33 |
|
34 """ |
|
35 `AbstractZipArray{S,T,N}` |
|
36 |
|
37 A way to refer to a `ZipArray` without specifying the container types. |
|
38 """ |
|
39 AbstractZipArray{S,T,N} = ZipArray{S,T,N,A,B} where {A <: AbstractArray{S,N}, B <: AbstractArray{T,N}} |
|
40 |
|
41 """ |
|
42 `ZipVector{S,T,A,B}` |
|
43 |
|
44 One-dimensional `ZipArray`. |
|
45 """ |
|
46 ZipVector{S,T,A,B} = ZipArray{S,T,1,A,B} |
|
47 |
|
48 """ |
|
49 `AbstractZipVector{S,T}` |
|
50 |
|
51 One-dimensional `AbstractZipArray`. |
|
52 """ |
|
53 AbstractZipVector{S,T} = AbstractZipArray{S,T,1} |
|
54 |
|
55 |
|
56 function Base.IndexStyle( :: Type{<:ZipArray{S,T,N,A,B}}) where {S,T,N,A,B} |
|
57 return IndexStyle(A) |
|
58 end |
|
59 |
|
60 @inline function Base.size(z :: AbstractZipArray{S,T,N}) where {S,T,N} |
|
61 return size(z.a) |
|
62 end |
|
63 |
|
64 @inline function Base.getindex(z :: AbstractZipArray{S,T,N}, i) where {S,T,N} |
|
65 return (getindex(z.a, i), getindex(z.b, i)) |
|
66 end |
|
67 |
|
68 @inline function Base.setindex!(z :: AbstractZipArray{S,T,N}, (s, t) :: Tuple{S,T}, i) where {S,T,N} |
|
69 return (setindex!(z.a, s, i), setindex!(z.b, t, i)) |
|
70 end |
|
71 |
|
72 @inline function Base.pop!(z :: AbstractZipVector{S,T}) where {S,T} |
|
73 s = pop!(z.a) |
|
74 t = pop!(z.b) |
|
75 return (s, t) |
|
76 end |
|
77 |
|
78 @inline function Base.push!(z :: AbstractZipVector{S,T}, items :: Vararg{Tuple{S,T},M}) where {S,T,M} |
|
79 push!(z.a, s for (s, _) ∈ items) |
|
80 push!(z.b, t for (_, t) ∈ items) |
|
81 end |
|
82 |
|
83 end # module |
|
84 |