-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
allow specializing Base.hash
for enum types without overwriting method
#49777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -21,6 +21,14 @@ Base.cconvert(::Type{T}, x::Enum{T2}) where {T<:Integer,T2<:Integer} = T(x)::T | |||||||||
Base.write(io::IO, x::Enum{T}) where {T<:Integer} = write(io, T(x)) | ||||||||||
Base.read(io::IO, ::Type{T}) where {T<:Enum} = T(read(io, basetype(T))) | ||||||||||
|
||||||||||
""" | ||||||||||
_enum_hash(x::Enum, h::UInt) | ||||||||||
|
||||||||||
Compute hash for an enum value `x`. This internal method will be specialized | ||||||||||
for every enum type created through [`@enum`](@ref). | ||||||||||
""" | ||||||||||
_enum_hash(x::Enum, h::UInt) = hash(x, h) | ||||||||||
Base.hash(x::Enum, h::UInt) = _enum_hash(x, h) | ||||||||||
Comment on lines
+30
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fallback for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indeed, the assumption was that using
Suggested change
Could you test and open a pull request? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess I can when I find the time, but I am not the one who caused this so it is more tempting for me to press the revert button. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. opened #49964 |
||||||||||
Base.isless(x::T, y::T) where {T<:Enum} = isless(basetype(T)(x), basetype(T)(y)) | ||||||||||
|
||||||||||
Base.Symbol(x::Enum) = namemap(typeof(x))[Integer(x)]::Symbol | ||||||||||
|
@@ -206,8 +214,12 @@ macro enum(T::Union{Symbol,Expr}, syms...) | |||||||||
Enums.namemap(::Type{$(esc(typename))}) = $(esc(namemap)) | ||||||||||
Base.typemin(x::Type{$(esc(typename))}) = $(esc(typename))($lo) | ||||||||||
Base.typemax(x::Type{$(esc(typename))}) = $(esc(typename))($hi) | ||||||||||
let enum_hash = hash($(esc(typename))) | ||||||||||
Base.hash(x::$(esc(typename)), h::UInt) = hash(enum_hash, hash(Integer(x), h)) | ||||||||||
let type_hash = hash($(esc(typename))) | ||||||||||
# Use internal `_enum_hash` to allow users to specialize | ||||||||||
# `Base.hash` for their own enum types without overwriting the | ||||||||||
# method we would define here. This avoids a warning for | ||||||||||
# precompilation. | ||||||||||
Enums._enum_hash(x::$(esc(typename)), h::UInt) = hash(type_hash, hash(Integer(x), h)) | ||||||||||
end | ||||||||||
let insts = (Any[ $(esc(typename))(v) for v in $values ]...,) | ||||||||||
Base.instances(::Type{$(esc(typename))}) = insts | ||||||||||
|
Uh oh!
There was an error while loading. Please reload this page.