Skip to content

Commit

Permalink
Implement iteration over GAP iterators (#967)
Browse files Browse the repository at this point in the history
  • Loading branch information
fingolfin authored Sep 30, 2024
1 parent c8ce260 commit 5ba3c3f
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/adapter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,8 @@ function Base.iterate(obj::GapObj)
# we can still allow iteration util some large bound
iterate(obj, (1, typemax(Int)))
end
elseif Wrappers.IsIterator(obj)
iterate(obj, Wrappers.ShallowCopy(obj))
elseif Wrappers.IsCollection(obj)
iterate(obj, Wrappers.Iterator(obj)::GapObj)
else
Expand All @@ -506,6 +508,9 @@ function Base.iterate(obj::GapObj, iter::GapObj)
end
end

Base.IteratorEltype(::Type{GapObj}) = Base.EltypeUnknown()
Base.IteratorSize(::Type{GapObj}) = Base.SizeUnknown()

# copy and deepcopy:
# The following is just a preliminary solution,
# in order to avoid Julia crashes when one calls `deepcopy` for a `GapObj`.
Expand Down
2 changes: 1 addition & 1 deletion src/constructors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ function (::Type{T})(obj::GapObj) where {T<:UnitRange}
result = obj[1]:obj[len]
end

return convert(T, result)
return convert(T, result)::T
end


Expand Down
1 change: 1 addition & 0 deletions src/wrappers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import GAP: @wrap
@wrap IsCollection(x::Any)::Bool
@wrap IsDoneIterator(x::Any)::Bool
@wrap IsEmpty(x::Any)::Bool
@wrap IsIterator(x::Any)::Bool
@wrap IsList(x::Any)::Bool
@wrap IsMatrixObj(x::Any)::Bool
@wrap IsPackageLoaded(x::GapObj)::Bool
Expand Down
14 changes: 13 additions & 1 deletion test/adapter.jl
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
@testset "iteration" begin
# iterating over a GAP plain list, which uses index based iteration
l = GAP.evalstr("[1, 2, 3]")
lj = collect(l)
@test lj isa Vector{Any}
@test lj isa Vector{Int}
@test lj == [1, 2, 3]
lj = collect(Int, l)
@test lj isa Vector{Int}
@test lj == [1, 2, 3]

# iterating over a GAP object (here, a group) which creates a GAP Iterator object
s = GAP.Globals.SymmetricGroup(3)
xs = []
for x in s
push!(xs, x)
end
@test length(xs) == 6

# iterating over a GAP iterator
gap_iter = GAP.Globals.IteratorOfCombinations(GAP.Obj([1,1,1]))
# iterate twice to verify we don't "eat up" the GAP iterator
# and don't otherwise change its state
for i in 1:2
collect(gap_iter)
vs = Vector{Int}.(gap_iter)
@test vs == [[], [1], [1, 1], [1, 1, 1]]
end
end

@testset "deepcopy" begin
Expand Down

0 comments on commit 5ba3c3f

Please sign in to comment.