Skip to content

Commit

Permalink
Support defining custom hashes for generated bitflags
Browse files Browse the repository at this point in the history
Duplicates improvement made to Base's Enums:
JuliaLang/julia#49777 and JuliaLang/julia#49964
  • Loading branch information
jmert committed Nov 12, 2023
1 parent 6cfdb19 commit 030489b
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/BitFlags.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ Base.:&(x::T, y::T) where {T<:BitFlag} = T(Integer(x) & Integer(y))

Base.broadcastable(x::BitFlag) = Ref(x)

_bitflag_hash(x::BitFlag, h::UInt) = invoke(hash, Tuple{Any, UInt}, x, h)
Base.hash(x::BitFlag, h::UInt) = _bitflag_hash(x, h)

function Base.print(io::IO, x::T) where T<:BitFlag
compact = get(io, :compact, false)::Bool
xi = Integer(x)
Expand Down Expand Up @@ -267,7 +270,7 @@ function _bitflag_impl(__module__::Module, typename::Symbol, basetype::Type{<:Un
Base.typemin(x::Type{$etypename}) = $etypename($lo)
Base.typemax(x::Type{$etypename}) = $etypename($hi)
let flag_hash = hash($etypename)
Base.hash(x::$etypename, h::UInt) = hash(flag_hash, hash(Integer(x), h))
BitFlags._bitflag_hash(x::$etypename, h::UInt) = hash(flag_hash, hash(Integer(x), h))
end
Base.instances(::Type{$etypename}) = ($(instances...),)
$(flagconsts...)
Expand Down
5 changes: 5 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ end
# Hashing
@test Int(flag2a) == Int(flag3a) # same numerical value, but
@test hash(flag2a) != hash(flag3a) # unique hashes as BitFlag
@test which(hash, (Flag1, UInt)).sig != Tuple{typeof(hash), Flag1, UInt}
struct NonstandardBitFlag <: BitFlags.BitFlag{UInt8} end
let x = NonstandardBitFlag(), h = zero(UInt)
@test hash(x, h) == invoke(hash, Tuple{Any, UInt}, x, h)
end

# Broadcasting
@test [flag1a, flag1b] .| flag1c == [flag1a | flag1c, flag1b | flag1c]
Expand Down

0 comments on commit 030489b

Please sign in to comment.