Repository navigation
Subtype IntSet and SparseIntSet to AbstractSet{Int} - #983
Conversation
Enable AbstractSet algorithms while keeping concrete container types. Add emptymutable/copymutable/filter! (and SparseIntSet delete!) so filter, setdiff, and Base's intersect!(::AbstractSet, ::AbstractSet) stay correct. Resolve symdiff!/intersect! AbstractSet dispatch. Fixes JuliaCollections#908
|
|
||
| Base.symdiff(s::IntSet, ns) = symdiff!(copy(s), ns) | ||
| Base.symdiff!(s::IntSet, ns) = (for n in ns; symdiff!(s, n); end; s) | ||
| Base.symdiff!(s::IntSet, ns::AbstractSet) = (for n in ns; symdiff!(s, n); end; s) |
There was a problem hiding this comment.
is this needed just to break ambiguity?
|
|
||
| #Is there a more performant way to do this? | ||
| Base.intersect!(s1::SparseIntSet, ns) = copy!(s1, intersect(s1, ns)) | ||
| Base.intersect!(s1::SparseIntSet, ns::AbstractSet) = copy!(s1, intersect(s1, ns)) |
There was a problem hiding this comment.
again is this needed just to break ambiguity?
| Base.symdiff!(s::IntSet, ns) = (for n in ns; symdiff!(s, n); end; s) | ||
| Base.symdiff!(s::IntSet, ns::AbstractSet) = (for n in ns; symdiff!(s, n); end; s) |
There was a problem hiding this comment.
It is tempting to write this as:
| Base.symdiff!(s::IntSet, ns) = (for n in ns; symdiff!(s, n); end; s) | |
| Base.symdiff!(s::IntSet, ns::AbstractSet) = (for n in ns; symdiff!(s, n); end; s) | |
| for T in (AbstractSet, Any) | |
| Base.symdiff!(s::IntSet, ns::T) = (for n in ns; symdiff!(s, n); end; s) | |
| end |
To make it clear that they are actually identical
|
Yes — those twins exist only to break the diamond with Base's Pushed a small follow-up that writes each pair as |
Makes identical ambiguity-breakers explicit for IntSet symdiff! and SparseIntSet intersect! (BitSet-style).
|
Can we add a comment saying that we define both to break method errors for ambiguity? |
|
Done - comments on both the IntSet |
oxinabox asked for an explicit note on both IntSet symdiff! and SparseIntSet intersect! dual definitions.
Neither
IntSetnorSparseIntSetsubtypedAbstractSet, so generic setalgorithms and APIs that dispatch on
AbstractSetignored them.Make both
<: AbstractSet{Int}and add the helpers Base's set fallbacks need:emptymutable/copymutablesofilterandsetdiffreturn the sameconcrete type instead of falling back to
Setfilter!viaunsafe_filter!(BitSet pattern) sointersect!(s::AbstractSet, s2::AbstractSet)worksdelete!forSparseIntSet(was onlypop!) for the filter! pathsymdiff!(::IntSet, ::AbstractSet)andintersect!(::SparseIntSet, ::AbstractSet)for unambiguous dispatch
Same-type
==/</<=methods remain more specific (unchanged). Cross-typeequality with
Set/ between the two types becomes available via AbstractSetfallbacks.
Docs note the
AbstractSet{Int}relationship.Fixes #908