|
1 | | -# Based on code from M. Bauman Stackexchange answer + Gitter discussion |
| 1 | +abstract AbstractVectorOfArray{T, N} <: AbstractArray{T, N} |
2 | 2 |
|
3 | | -type VectorOfArray{T, N, A} <: AbstractArray{T, N} |
| 3 | +# Based on code from M. Bauman Stackexchange answer + Gitter discussion |
| 4 | +type VectorOfArray{T, N, A} <: AbstractVectorOfArray{T, N} |
4 | 5 | data::A # A <: AbstractVector{<: AbstractArray{T, N - 1}} |
5 | 6 | end |
6 | 7 |
|
7 | 8 | VectorOfArray{T, N}(vec::AbstractVector{T}, dims::NTuple{N}) = VectorOfArray{eltype(T), N, typeof(vec)}(vec) |
8 | 9 | # Assume that the first element is representative all all other elements |
9 | 10 | VectorOfArray(vec::AbstractVector) = VectorOfArray(vec, (size(vec[1])..., length(vec))) |
10 | 11 |
|
11 | | - |
12 | | -Base.endof(VA::VectorOfArray) = endof(VA.data) |
13 | | -Base.size(VA::VectorOfArray) = (size(VA.data[1])..., length(VA.data)) |
14 | | -#TODO: should we redefine length to be over the VA.data? Currently it is the number of total elements |
15 | | - |
16 | | -@inline function Base.getindex{T, N}(VA::VectorOfArray{T, N}, I::Vararg{Int, N}) |
17 | | - VA.data[I[end]][Base.front(I)...] |
18 | | -end |
| 12 | +# Interface for the linear indexing. This is just a view of the underlying nested structure |
| 13 | +@inline Base.endof(VA::AbstractVectorOfArray) = endof(VA.data) |
| 14 | +@inline Base.length(VA::AbstractVectorOfArray) = length(VA.data) |
19 | 15 | # Linear indexing will be over the container elements, not the individual elements |
20 | 16 | # unlike an true AbstractArray |
21 | | -@inline Base.getindex{T, N}(VA::VectorOfArray{T, N}, I::Int) = VA.data[I] |
22 | | -@inline Base.getindex{T, N}(VA::VectorOfArray{T, N}, I::Colon) = VA.data[I] |
23 | | -@inline Base.getindex{T, N}(VA::VectorOfArray{T, N}, I::AbstractArray{Int}) = VA.data[I] |
| 17 | +@inline Base.getindex{T, N}(VA::AbstractVectorOfArray{T, N}, I::Int) = VA.data[I] |
| 18 | +@inline Base.getindex{T, N}(VA::AbstractVectorOfArray{T, N}, I::Colon) = VA.data[I] |
| 19 | +@inline Base.getindex{T, N}(VA::AbstractVectorOfArray{T, N}, I::AbstractArray{Int}) = VA.data[I] |
24 | 20 |
|
25 | | -Base.copy(VA::VectorOfArray) = VectorOfArray(copy(VA.data), size(VA)) |
| 21 | +# Interface for the two dimensional indexing, a more standard AbstractArray interface |
| 22 | +@inline Base.size(VA::AbstractVectorOfArray) = (size(VA.data[1])..., length(VA.data)) |
| 23 | +@inline Base.getindex{T, N}(VA::AbstractVectorOfArray{T, N}, I::Vararg{Int, N}) = VA.data[I[end]][Base.front(I)...] |
26 | 24 |
|
27 | | -Base.sizehint!{T, N}(VA::VectorOfArray{T, N}, i) = sizehint!(VA.data, i) |
| 25 | +# The iterator will be over the subarrays of the container, not the individual elements |
| 26 | +# unlike an true AbstractArray |
| 27 | +Base.start{T, N}(VA::AbstractVectorOfArray{T, N}) = 1 |
| 28 | +Base.next{T, N}(VA::AbstractVectorOfArray{T, N}, state) = (VA[state], state + 1) |
| 29 | +Base.done{T, N}(VA::AbstractVectorOfArray{T, N}, state) = state >= length(VA.data) + 1 |
28 | 30 |
|
29 | | -Base.push!{T, N}(VA::VectorOfArray{T, N}, new_item::AbstractVector) = push!(VA.data, new_item) |
| 31 | +# Growing the array simply adds to the container vector |
| 32 | +Base.copy(VA::AbstractVectorOfArray) = typeof(VA)(copy(VA.data)) |
| 33 | +Base.sizehint!{T, N}(VA::AbstractVectorOfArray{T, N}, i) = sizehint!(VA.data, i) |
| 34 | +Base.push!{T, N}(VA::AbstractVectorOfArray{T, N}, new_item::AbstractVector) = push!(VA.data, new_item) |
30 | 35 |
|
31 | | -function Base.append!{T, N}(VA::VectorOfArray{T, N}, new_item::VectorOfArray{T, N}) |
| 36 | +function Base.append!{T, N}(VA::AbstractVectorOfArray{T, N}, new_item::AbstractVectorOfArray{T, N}) |
32 | 37 | for item in copy(new_item) |
33 | 38 | push!(VA, item) |
34 | 39 | end |
35 | 40 | return VA |
36 | 41 | end |
37 | 42 |
|
38 | | - |
39 | | -# The iterator will be over the subarrays of the container, not the individual elements |
40 | | -# unlike an true AbstractArray |
41 | | -Base.start{T, N}(VA::VectorOfArray{T, N}) = 1 |
42 | | -Base.next{T, N}(VA::VectorOfArray{T, N}, state) = (VA[state], state + 1) |
43 | | -Base.done{T, N}(VA::VectorOfArray{T, N}, state) = state >= length(VA.data) + 1 |
44 | | - |
45 | 43 | # conversion tools |
46 | | -vecarr_to_arr(VA::VectorOfArray) = cat(length(size(VA)), VA.data...) |
| 44 | +vecarr_to_arr(VA::AbstractVectorOfArray) = cat(length(size(VA)), VA.data...) |
0 commit comments