Skip to content

Commit

Permalink
WIP: Make sets indexable
Browse files Browse the repository at this point in the history
 * All `AbstractSet`s can be indexed. They are containers with equal
   values and keys, much like `Base.OneTo(n)`. This will enable a
   certain semantic with `keys` and indexing common across arrays,
   associatives and sets.
  • Loading branch information
Andy Ferris committed Nov 12, 2017
1 parent 6a23e23 commit 0da600d
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 6 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,9 @@ Library improvements
This supersedes the old behavior of reinterpret on Arrays. As a result, reinterpreting
arrays with different alignment requirements (removed in 0.6) is once again allowed ([#23750]).

* `AbstractSet`s are now indexable, such that `set[x] == x` and `keys(set) == set`
([#24508]).

Compiler/Runtime improvements
-----------------------------

Expand Down
4 changes: 1 addition & 3 deletions base/bitset.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@ very large integers), use [`Set`](@ref) instead.
"""
BitSet(itr) = union!(BitSet(), itr)

eltype(::Type{BitSet}) = Int
similar(s::BitSet) = BitSet()
empty(s::BitSet) = BitSet()
copy(s1::BitSet) = copy!(BitSet(), s1)
function copy!(dest::BitSet, src::BitSet)
resize!(dest.bits, length(src.bits))
copy!(dest.bits, src.bits)
dest
end
eltype(s::BitSet) = Int
sizehint!(s::BitSet, n::Integer) = (n > length(s.bits) && _resize0!(s.bits, n); s)

# An internal function for setting the inclusion bit for a given integer n >= 0
Expand Down
19 changes: 16 additions & 3 deletions base/set.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

# AbstractSet

# AbstractSets are idempotent under indexing:
keys(set::AbstractSet) = set
@inline function getindex(set::AbstractSet, x)
@boundscheck if x set
throw(KeyError(x))
end
return x
end
eltype(set::Type{<:AbstractSet{T}}) where {T} = T

# Set

mutable struct Set{T} <: AbstractSet{T}
dict::Dict{T,Void}

Expand All @@ -23,9 +37,8 @@ function Set(g::Generator)
return Set{T}(g)
end

eltype(::Type{Set{T}}) where {T} = T
similar(s::Set{T}) where {T} = Set{T}()
similar(s::Set, T::Type) = Set{T}()
similar(s::AbstractSet, T::Type) = Set{T}() # default empty set type

function show(io::IO, s::Set)
print(io, "Set")
Expand Down Expand Up @@ -64,7 +77,7 @@ rehash!(s::Set) = (rehash!(s.dict); s)
start(s::Set) = start(s.dict)
done(s::Set, state) = done(s.dict, state)
# NOTE: manually optimized to take advantage of Dict representation
next(s::Set, i) = (s.dict.keys[i], skip_deleted(s.dict, i+1))
@propagate_inbounds next(s::Set, i) = (s.dict.keys[i], skip_deleted(s.dict, i+1))

"""
union(s1,s2...)
Expand Down

0 comments on commit 0da600d

Please sign in to comment.