Skip to content

Commit

Permalink
Change KeyIterator to KeySet.
Browse files Browse the repository at this point in the history
`keys(::Associative)` now returns an `AbstractSet`.
  • Loading branch information
Andy Ferris authored and andyferris committed Nov 18, 2017
1 parent 9e7e08c commit 417c3e8
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 26 deletions.
26 changes: 13 additions & 13 deletions base/associative.jl
Expand Up @@ -14,7 +14,7 @@ end

const secret_table_token = :__c782dbf1cf4d6a2e5e3865d7e95634f2e09b5902__

haskey(d::Associative, k) = in(k,keys(d))
haskey(d::Associative, k) = in(k, keys(d))

function in(p::Pair, a::Associative, valcmp=(==))
v = get(a,p[1],secret_table_token)
Expand All @@ -35,29 +35,29 @@ function summary(t::Associative)
return string(typeof(t), " with ", n, (n==1 ? " entry" : " entries"))
end

struct KeyIterator{T<:Associative}
struct KeySet{K, T <: Associative{K}} <: AbstractSet{K}
dict::T
end
KeySet(dict::Associative) = KeySet{keytype(dict), typeof(dict)}(dict)

struct ValueIterator{T<:Associative}
dict::T
end

summary(iter::T) where {T<:Union{KeyIterator,ValueIterator}} =
summary(iter::T) where {T<:Union{KeySet,ValueIterator}} =
string(T.name, " for a ", summary(iter.dict))

show(io::IO, iter::Union{KeyIterator,ValueIterator}) = show(io, collect(iter))
show(io::IO, iter::Union{KeySet,ValueIterator}) = show(io, collect(iter))

length(v::Union{KeyIterator,ValueIterator}) = length(v.dict)
isempty(v::Union{KeyIterator,ValueIterator}) = isempty(v.dict)
_tt1(::Type{Pair{A,B}}) where {A,B} = A
length(v::Union{KeySet,ValueIterator}) = length(v.dict)
isempty(v::Union{KeySet,ValueIterator}) = isempty(v.dict)
_tt2(::Type{Pair{A,B}}) where {A,B} = B
eltype(::Type{KeyIterator{D}}) where {D} = _tt1(eltype(D))
eltype(::Type{ValueIterator{D}}) where {D} = _tt2(eltype(D))

start(v::Union{KeyIterator,ValueIterator}) = start(v.dict)
done(v::Union{KeyIterator,ValueIterator}, state) = done(v.dict, state)
start(v::Union{KeySet,ValueIterator}) = start(v.dict)
done(v::Union{KeySet,ValueIterator}, state) = done(v.dict, state)

function next(v::KeyIterator, state)
function next(v::KeySet, state)
n = next(v.dict, state)
n[1][1], n[2]
end
Expand All @@ -67,7 +67,7 @@ function next(v::ValueIterator, state)
n[1][2], n[2]
end

in(k, v::KeyIterator) = get(v.dict, k, secret_table_token) !== secret_table_token
in(k, v::KeySet) = get(v.dict, k, secret_table_token) !== secret_table_token

"""
keys(iterator)
Expand Down Expand Up @@ -100,7 +100,7 @@ julia> collect(keys(a))
'a'
```
"""
keys(a::Associative) = KeyIterator(a)
keys(a::Associative) = KeySet(a)

"""
values(a::Associative)
Expand Down
4 changes: 2 additions & 2 deletions base/dict.jl
Expand Up @@ -588,7 +588,7 @@ false
```
"""
haskey(h::Dict, key) = (ht_keyindex(h, key) >= 0)
in(key, v::KeyIterator{<:Dict}) = (ht_keyindex(v.dict, key) >= 0)
in(key, v::KeySet{<:Any, <:Dict}) = (ht_keyindex(v.dict, key) >= 0)

"""
getkey(collection, key, default)
Expand Down Expand Up @@ -720,7 +720,7 @@ end
isempty(t::Dict) = (t.count == 0)
length(t::Dict) = t.count

@propagate_inbounds function next(v::KeyIterator{<:Dict}, i)
@propagate_inbounds function next(v::KeySet{<:Any, <:Dict}, i)
return (v.dict.keys[i], skip_deleted(v.dict,i+1))
end
@propagate_inbounds function next(v::ValueIterator{<:Dict}, i)
Expand Down
2 changes: 1 addition & 1 deletion base/env.jl
Expand Up @@ -78,7 +78,7 @@ similar(::EnvDict) = Dict{String,String}()
getindex(::EnvDict, k::AbstractString) = access_env(k->throw(KeyError(k)), k)
get(::EnvDict, k::AbstractString, def) = access_env(k->def, k)
get(f::Callable, ::EnvDict, k::AbstractString) = access_env(k->f(), k)
in(k::AbstractString, ::KeyIterator{EnvDict}) = _hasenv(k)
in(k::AbstractString, ::KeySet{String, EnvDict}) = _hasenv(k)
pop!(::EnvDict, k::AbstractString) = (v = ENV[k]; _unsetenv(k); v)
pop!(::EnvDict, k::AbstractString, def) = haskey(ENV,k) ? pop!(ENV,k) : def
delete!(::EnvDict, k::AbstractString) = (_unsetenv(k); ENV)
Expand Down
4 changes: 2 additions & 2 deletions base/precompile.jl
Expand Up @@ -38,7 +38,7 @@ precompile(Tuple{getfield(Base, Symbol("#kw##listen")), Array{Any, 1}, typeof(Ba
precompile(Tuple{typeof(Base.ndigits0z), UInt16})
precompile(Tuple{typeof(Base.dec), UInt16, Int64, Bool})
precompile(Tuple{typeof(Base.Libc.strerror), Int32})
precompile(Tuple{typeof(Base.copy!), Array{Any, 1}, Base.KeyIterator{Base.Dict{Any, Any}}})
precompile(Tuple{typeof(Base.copy!), Array{Any, 1}, Base.KeySet{Any, Base.Dict{Any, Any}}})
precompile(Tuple{typeof(Base.promoteK), Type{Any}})
precompile(Tuple{typeof(Core.Inference.length), Tuple{Core.Inference.Const, DataType, Core.Inference.Const, Core.Inference.Const}})
precompile(Tuple{typeof(Core.Inference.getindex), Tuple{Core.Inference.Const, DataType, Core.Inference.Const, Core.Inference.Const}, Int64})
Expand Down Expand Up @@ -321,7 +321,7 @@ precompile(Tuple{typeof(Base.LineEdit.add_specialisations), Base.Dict{Char, Any}
precompile(Tuple{typeof(Base.setindex!), Base.Dict{Char, Any}, Base.Dict{Char, Any}, Char})
precompile(Tuple{typeof(Base.ht_keyindex2), Base.Dict{Char, Any}, Char})
precompile(Tuple{typeof(Base._setindex!), Base.Dict{Char, Any}, Base.Dict{Char, Any}, Char, Int64})
precompile(Tuple{typeof(Base.setdiff), Base.KeyIterator{Base.Dict{Any, Any}}, Base.KeyIterator{Base.Dict{Any, Any}}})
precompile(Tuple{typeof(Base.setdiff), Base.KeySet{Any, Base.Dict{Any, Any}}, Base.KeySet{Any, Base.Dict{Any, Any}}})
precompile(Tuple{typeof(Base.LineEdit.keymap_merge), Base.Dict{Char, Any}, Base.Dict{Any, Any}})
precompile(Tuple{typeof(Base.LineEdit.postprocess!), Base.Dict{Char, Any}})
precompile(Tuple{typeof(Base.LineEdit.keymap_unify), Array{Base.Dict{Any, Any}, 1}})
Expand Down
4 changes: 2 additions & 2 deletions base/replutil.jl
Expand Up @@ -4,10 +4,10 @@
show(io::IO, ::MIME"text/plain", x) = show(io, x)

# multiline show functions for types defined before multimedia.jl:
function show(io::IO, ::MIME"text/plain", iter::Union{KeyIterator,ValueIterator})
function show(io::IO, ::MIME"text/plain", iter::Union{KeySet,ValueIterator})
print(io, summary(iter))
isempty(iter) && return
print(io, ". ", isa(iter,KeyIterator) ? "Keys" : "Values", ":")
print(io, ". ", isa(iter,KeySet) ? "Keys" : "Values", ":")
limit::Bool = get(io, :limit, false)
if limit
sz = displaysize(io)
Expand Down
3 changes: 2 additions & 1 deletion base/set.jl
@@ -1,5 +1,7 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

eltype(::Type{AbstractSet{T}}) where {T} = T

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

Expand All @@ -23,7 +25,6 @@ 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}()

Expand Down
10 changes: 5 additions & 5 deletions test/replutil.jl
Expand Up @@ -624,33 +624,33 @@ end
@test String(take!(buf)) == "Base.ImmutableDict{$Int,$Int} with 1 entry: …"
show(io, MIME"text/plain"(), keys(d))
@test String(take!(buf)) ==
"Base.KeyIterator for a Base.ImmutableDict{$Int,$Int} with 1 entry. Keys: …"
"Base.KeySet for a Base.ImmutableDict{$Int,$Int} with 1 entry. Keys: …"

io = IOContext(io, :displaysize => (5, 80))
show(io, MIME"text/plain"(), d)
@test String(take!(buf)) == "Base.ImmutableDict{$Int,$Int} with 1 entry:\n 1 => 2"
show(io, MIME"text/plain"(), keys(d))
@test String(take!(buf)) ==
"Base.KeyIterator for a Base.ImmutableDict{$Int,$Int} with 1 entry. Keys:\n 1"
"Base.KeySet for a Base.ImmutableDict{$Int,$Int} with 1 entry. Keys:\n 1"
d = Base.ImmutableDict(d, 3=>4)
show(io, MIME"text/plain"(), d)
@test String(take!(buf)) == "Base.ImmutableDict{$Int,$Int} with 2 entries:\n ⋮ => ⋮"
show(io, MIME"text/plain"(), keys(d))
@test String(take!(buf)) ==
"Base.KeyIterator for a Base.ImmutableDict{$Int,$Int} with 2 entries. Keys:\n"
"Base.KeySet for a Base.ImmutableDict{$Int,$Int} with 2 entries. Keys:\n"

io = IOContext(io, :displaysize => (6, 80))
show(io, MIME"text/plain"(), d)
@test String(take!(buf)) ==
"Base.ImmutableDict{$Int,$Int} with 2 entries:\n 3 => 4\n 1 => 2"
show(io, MIME"text/plain"(), keys(d))
@test String(take!(buf)) ==
"Base.KeyIterator for a Base.ImmutableDict{$Int,$Int} with 2 entries. Keys:\n 3\n 1"
"Base.KeySet for a Base.ImmutableDict{$Int,$Int} with 2 entries. Keys:\n 3\n 1"
d = Base.ImmutableDict(d, 5=>6)
show(io, MIME"text/plain"(), d)
@test String(take!(buf)) ==
"Base.ImmutableDict{$Int,$Int} with 3 entries:\n 5 => 6\n ⋮ => ⋮"
show(io, MIME"text/plain"(), keys(d))
@test String(take!(buf)) ==
"Base.KeyIterator for a Base.ImmutableDict{$Int,$Int} with 3 entries. Keys:\n 5\n"
"Base.KeySet for a Base.ImmutableDict{$Int,$Int} with 3 entries. Keys:\n 5\n"
end

0 comments on commit 417c3e8

Please sign in to comment.