Skip to content

Commit

Permalink
Merge 45e0d07 into 0d99898
Browse files Browse the repository at this point in the history
  • Loading branch information
kmsquire committed Jan 16, 2017
2 parents 0d99898 + 45e0d07 commit ec4d76c
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 668 deletions.
3 changes: 2 additions & 1 deletion src/DataStructures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ module DataStructures
include("heaps.jl")

include("dict_support.jl")
include("hash_dict.jl")
include("ordered_dict.jl")
include("ordered_set.jl")
include("default_dict.jl")
Expand Down Expand Up @@ -119,4 +118,6 @@ module DataStructures

@deprecate DefaultOrderedDict(default, ks, vs) DefaultOrderedDict(default, zip(ks, vs))
@deprecate DefaultOrderedDict{K,V}(::Type{K}, ::Type{V}, default) DefaultOrderedDict{K,V}(default)

@deprecate push!(d::DefaultDictBase, p::Tuple) push!(d, p[1] => p[2])
end
33 changes: 24 additions & 9 deletions src/default_dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# DefaultDictBase is the main class used to in Default*Dicts.
#
# Each related (immutable) Default*Dict class contains a single
# DefautlDictBase object as a member, and delegates almost all
# DefaultDictBase object as a member, and delegates almost all
# functions to this object.
#
# The main rationale for doing this instead of using type aliases is
Expand Down Expand Up @@ -49,30 +49,45 @@ DefaultDictBase{F,D<:Associative}(default::F, d::D) = (K=keytype(d); V=valtype(d
getkey, pop!, delete!, start, done, next,
isempty, length ]

push!(d::DefaultDictBase, p::Pair) = (setindex!(d.d, p.second, p.first); d)
push!(d::DefaultDictBase, p) = push!(d, p[1] => p[2])
push!(d::DefaultDictBase, p, q) = push!(push!(d, p), q)
push!(d::DefaultDictBase, p, q, r) = push!(push!(push!(d, p), q), r...)

similar{K,V,F}(d::DefaultDictBase{K,V,F}) = DefaultDictBase{K,V,F}(d.default)
in{T<:DefaultDictBase}(key, v::Base.KeyIterator{T}) = key in keys(v.dict.d)
next{T<:DefaultDictBase}(v::Base.KeyIterator{T}, i) = (v.dict.d.keys[i], Base.skip_deleted(v.dict.d,i+1))
next{T<:DefaultDictBase}(v::Base.ValueIterator{T}, i) = (v.dict.d.vals[i], Base.skip_deleted(v.dict.d,i+1))

getindex(d::DefaultDictBase, key) = get!(d.d, key, d.default)

const _K = TypeVar(:K)
const _V = TypeVar(:V)

function getindex{F<:Base.Callable}(d::DefaultDictBase{_K,_V,F}, key)
return get!(d.d, key) do
d.default()
end
end

################

# Here begins the actual definition of the DefaultDict and
# DefaultOrderedDict classes. As noted above, these are simply
# wrappers around a DefaultDictBase object, and delegate all functions
# to that object

for (DefaultDict,O) in [(:DefaultDict, :Unordered), (:DefaultOrderedDict, :Ordered)]
for _Dict in [:Dict, :OrderedDict]
DefaultDict = Symbol("Default"*string(_Dict))
@eval begin
immutable $DefaultDict{K,V,F} <: Associative{K,V}
d::DefaultDictBase{K,V,F,HashDict{K,V,$O}}
d::DefaultDictBase{K,V,F,$_Dict{K,V}}

$DefaultDict(x, ps::Pair{K,V}...) = new(DefaultDictBase{K,V,F,HashDict{K,V,$O}}(x, ps...))
$DefaultDict(x, kv::AbstractArray{Tuple{K,V}}) = new(DefaultDictBase{K,V,F,HashDict{K,V,$O}}(x, kv))
$DefaultDict(x, ps::Pair{K,V}...) = new(DefaultDictBase{K,V,F,$_Dict{K,V}}(x, ps...))
$DefaultDict(x, kv::AbstractArray{Tuple{K,V}}) = new(DefaultDictBase{K,V,F,$_Dict{K,V}}(x, kv))
$DefaultDict(x, d::$DefaultDict) = $DefaultDict(x, d.d)
$DefaultDict(x, d::HashDict) = new(DefaultDictBase{K,V,F,HashDict{K,V,$O}}(x, d))
$DefaultDict(x) = new(DefaultDictBase{K,V,F,HashDict{K,V,$O}}(x))
$DefaultDict(x, d::$_Dict) = new(DefaultDictBase{K,V,F,$_Dict{K,V}}(x, d))
$DefaultDict(x) = new(DefaultDictBase{K,V,F,$_Dict{K,V}}(x))
end

## Constructors
Expand All @@ -85,7 +100,7 @@ for (DefaultDict,O) in [(:DefaultDict, :Unordered), (:DefaultOrderedDict, :Order
$DefaultDict{K,V,F}(default::F, kv::AbstractArray{Tuple{K,V}}) = $DefaultDict{K,V,F}(default, kv)
$DefaultDict{K,V,F}(default::F, ps::Pair{K,V}...) = $DefaultDict{K,V,F}(default, ps...)

$DefaultDict{F}(default::F, d::Associative) = ((K,V)= (Base.keytype(d), Base.valtype(d)); $DefaultDict{K,V,F}(default, HashDict(d)))
$DefaultDict{F}(default::F, d::Associative) = ((K,V)= (Base.keytype(d), Base.valtype(d)); $DefaultDict{K,V,F}(default, $_Dict(d)))

# Constructor syntax: DefaultDictBase{Int,Float64}(default)
@compat (::Type{$DefaultDict{K,V}}){K,V}() = throw(ArgumentError("$DefaultDict: no default specified"))
Expand All @@ -96,7 +111,7 @@ for (DefaultDict,O) in [(:DefaultDict, :Unordered), (:DefaultOrderedDict, :Order
# Most functions are simply delegated to the wrapped DefaultDictBase object
@delegate $DefaultDict.d [ sizehint!, empty!, setindex!,
getindex, get, get!, haskey,
getkey, pop!, delete!, start, next,
getkey, push!, pop!, delete!, start, next,
done, isempty, length ]

similar{K,V,F}(d::$DefaultDict{K,V,F}) = $DefaultDict{K,V,F}(d.d.default)
Expand Down
8 changes: 4 additions & 4 deletions src/dict_support.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# support function
# support functions

# This is defined in Base, but probably not meant for external consumption,
# so it's redefined here.
# These functions are defined in Base, but are not exported,
# so they are redefined here.
_tablesz(x::Integer) = x < 16 ? 16 : one(x)<<((sizeof(x)<<3)-leading_zeros(x-1))

hashindex(key, sz) = (reinterpret(Int,(hash(key))) & (sz-1)) + 1
Loading

0 comments on commit ec4d76c

Please sign in to comment.