In the master branch of DataStructures.jl, I have written new iteration methods for the three sorted containers, SortedSet
, SortedDict
, and SortedMultiDict
. The main structure that defines an iteration is:
struct IterableObject{C <: SortedContainer,
R <: RangeTypes,
Kv <: KVIterTypes,
T <: TokenIterTypes,
D <: IterDirection}
m::C
r::R
end
(See: DataStructures.jl/sorted_container_iteration.jl at master · JuliaCollections/DataStructures.jl · GitHub) So a loop like:
for (st,k) in semitokens(Iterators.Reverse(keys(s)))
end
will compile into one of those objects. The five parameters are: C, the underlying container, R, whether the iteration is over the whole container or a range of it, Kv, whether the iteration is keys
, values
, or both, T, whether the iteration is also supposed to return tokens or semitokens, and D, whether the iteration is forward or reverse.
This new structure extends and cleans up previous code, but it falls short in one respect. The original plan for SortedDict
was to make it, as much as possible, a plug-in replacement for Dict
. However, the new iteration code fails one compatibility test:
julia> d = Dict(1=>"a", 2=>"b");
julia> k = keys(d)
KeySet for a Dict{Int64, String} with 2 entries. Keys:
2
1
julia> isa(k,AbstractSet)
true
julia> g = SortedDict(1=>"a", 2=>"b");
julia> k = keys(g)
DataStructures.IterableObject{SortedDict{Int64, String, Base.Order.ForwardOrdering}, DataStructures.EntireContainer, DataStructures.KeysIter, DataStructures.NoTokens, DataStructures.ForwardIter}(SortedDict(1 => "a", 2 => "b"), DataStructures.EntireContainer())
julia> isa(k,AbstractSet)
false
So my question is whether it is possible to declare that particular parameterized instances of IterableObject
, namely, instances when C
is a SortedDict
, Kv
is KeysIter
, and T
is NoTokens
be a subtype of AbstractSet
. The only solution that comes to mind requires a lot of special-casing.