Skip to content

Commit

Permalink
Implement iteration protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
giordano committed May 17, 2022
1 parent da82de1 commit fe8a413
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
fail-fast: false
matrix:
version:
- '1.0'
- '1.6'
- '1'
- 'nightly'
os:
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ authors = ["Mosè Giordano"]
version = "0.1.0"

[compat]
julia = "1"
julia = "1.6"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Expand Down
24 changes: 24 additions & 0 deletions src/StarWarsArrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,36 @@ Base.setindex!(A::StarWarsArray, v, i::Int) =
Base.setindex!(A::StarWarsArray{T,N}, v, i::Vararg{Int,N}) where {T,N} =
setindex!(parent(A), v, index.(i, size(parent(A)), order(A))...)

# Axes
Base.axes(A::StarWarsArray{T,N,P,OriginalOrder}) where {T,N,P} =
map(i->index.(i, length(A), order(A)), machete_view_index.(size(A)))

Base.axes(A::StarWarsArray{T,N,P,MacheteOrder}) where {T,N,P} =
map(i->index.(i .+ 1, length(A), MacheteOrder), machete_view_index.(size(A)))

# Iteration
function iterate_revindex(i::Int, ::Type{OriginalOrder})
if 1 <= i <= 3
return i + 3
elseif 4 <= i <= 6
return i - 3
end
return i
end
function iterate_revindex(i::Int, ::Type{MacheteOrder})
if 1 <= i <= 2
return i + 3
elseif 3 <= i <= 4
return i - 1
end
return i + 1
end

function Base.iterate(A::StarWarsArray, i=1)
i in 1:length(A) || return nothing
return A[iterate_revindex(i, order(A))], i + 1
end

# Showing. Note: this is awful, but it does what I want
Base.show(io::IO, m::MIME"text/plain", A::StarWarsArray{T,N}) where {T,N} =
show(io, m, view(parent(A), axes(A)...))
Expand Down
16 changes: 16 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,14 @@ import StarWarsArrays: StarWarsError, order
v[4] = -42
@test v[4] == -42
@test axes(v) == ([4, 5, 6, 1, 2, 3, 7, 8, 9],)
@test eachindex(v) == [4, 5, 6, 1, 2, 3, 7, 8, 9]
@test length(v) == 9
@test size(v) == (9,)
for (idx, x) in enumerate(v)
# Explanation: iterating over `v` should be equivalent to iterating over its parent,
# because the iteration protocol should follow the order 4, 5, 6, 1, 2, 3, ...
@test x == parent(v)[idx]
end

m = StarWarsArray(reshape(collect(1:81), 9, 9), OriginalOrder)
@test order(m) == OriginalOrder
Expand All @@ -36,6 +42,9 @@ import StarWarsArrays: StarWarsError, order
@test axes(m) == ([4, 5, 6, 1, 2, 3, 7, 8, 9], [4, 5, 6, 1, 2, 3, 7, 8, 9])
@test length(m) == 81
@test size(m) == (9, 9)
for (idx, x) in enumerate(m)
@test x == parent(m)[idx]
end

@test_throws ArgumentError StarWarsArray(rand(2), OriginalOrder)
@test_throws ArgumentError StarWarsArray(rand(8, 2), OriginalOrder)
Expand All @@ -56,8 +65,12 @@ end
v[4] = -42
@test v[4] == -42
@test axes(v) == ([3, 4, 1, 2, 5, 6, 7, 8],)
@test eachindex(v) == [3, 4, 1, 2, 5, 6, 7, 8]
@test length(v) == 8
@test size(v) == (8,)
for (idx, x) in enumerate(v)
@test x == parent(v)[idx]
end

m = StarWarsArray(reshape(collect(1:81), 9, 9), MacheteOrder)
@test order(m) == MacheteOrder
Expand All @@ -81,6 +94,9 @@ end
@test axes(m) == ([3, 4, 1, 2, 5, 6, 7, 8], [3, 4, 1, 2, 5, 6, 7, 8])
@test length(m) == 64
@test size(m) == (8, 8)
for (idx, x) in enumerate(m)
@test x == parent(m)[idx]
end

@test_throws ArgumentError StarWarsArray(rand(4), MacheteOrder)
@test_throws ArgumentError StarWarsArray(rand(6, 2, 9), MacheteOrder)
Expand Down

0 comments on commit fe8a413

Please sign in to comment.