Skip to content

Commit

Permalink
Report the key-value name mapping with a NamedTuple
Browse files Browse the repository at this point in the history
  • Loading branch information
jmert committed Nov 11, 2022
1 parent 7b3874d commit 2378d5d
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
7 changes: 3 additions & 4 deletions src/BitFlags.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function Base.print(io::IO, x::T) where T<:BitFlag
multi = (haszero(T) ? !iszero(xi) : true) && !compact && !ispow2(xi)
first = true
sep = compact ? "|" : " | "
for (i, sym) in Iterators.reverse(namemap(T))
for (sym, i) in Iterators.reverse(pairs(namemap(T)))
if (first && iszero(i) && iszero(xi)) || !iszero(xi & i)
if first
multi && print(io, "(")
Expand Down Expand Up @@ -87,7 +87,7 @@ function Base.show(io::IO, m::MIME"text/plain", t::Type{<:BitFlag})
print(io, "BitFlag ")
Base.show_datatype(io, t)
print(io, ":")
for (i, sym) in namemap(t)
for (sym, i) in pairs(namemap(t))
print(io, "\n", sym, " = ")
show(io, Integer(i))
end
Expand Down Expand Up @@ -245,15 +245,14 @@ function _bitflag_impl(__module__::Module, typename::Symbol, basetype::Type{<:Un
ebasetype = esc(basetype)

n = length(names)
namemap = Vector{Tuple{basetype, Symbol}}(undef, n)
instances = Vector{Expr}(undef, n)
flagconsts = Vector{Expr}(undef, n)
@inbounds for ii in 1:length(names)
sym, val = names[ii], values[ii]
namemap[ii] = (val, sym)
instances[ii] = :(bitcast($etypename, $val))
flagconsts[ii] = :(const $(esc(sym)) = bitcast($etypename, $val))
end
namemap = NamedTuple{(names...,)}((values...,))

blk = quote
# bitflag definition
Expand Down
27 changes: 27 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,33 @@ end
@test Integer(flag7b) === UInt8(2)
#end

#@testset "Internal definitions" begin
# Underlying integer types
@test BitFlags.basetype(Flag5) === UInt32
@test BitFlags.basetype(Flag6) === UInt8

# Whether flag has an explicit zero
@test !BitFlags.haszero(Flag3)
@test BitFlags.haszero(Flag4)

# Key-Value mapping
@test BitFlags.namemap(Flag5) isa NamedTuple{(:flag5a, :flag5b), NTuple{2, UInt32}}
@test BitFlags.namemap(Flag6) isa NamedTuple{(:flag6a, :flag6b, :flag6c), NTuple{3, UInt8}}
# Ensure the mapping can be used in a type-inferrable way
function isset_nt(x::B) where {T, B <: BitFlag{T}}
nm = BitFlags.namemap(B)
K, V = keys(nm), values(nm)
tf = (BitFlags.haszero(B) && iszero(T(x))) ? iszero.(V) : (!iszero).(V .& T.(x))
return NamedTuple{K}(tf)
end
@test @inferred isset_nt(flag3a) == (; flag3a = true, flag3b = false, flag3c = false)
@test @inferred isset_nt(flag3b) == (; flag3a = false, flag3b = true, flag3c = false)
@test @inferred isset_nt(flag3b | flag3c) == (; flag3a = false, flag3b = true, flag3c = true)
@test @inferred isset_nt(flag4a) == (; flag4a = true, flag4b = false, flag4c = false)
@test @inferred isset_nt(flag4b) == (; flag4a = false, flag4b = true, flag4c = false)
@test @inferred isset_nt(flag4b | flag4c) == (; flag4a = false, flag4b = true, flag4c = true)
#end

#@testset "Error conditions" begin

@test_throws ArgumentError("no arguments given for BitFlag Foo"
Expand Down

0 comments on commit 2378d5d

Please sign in to comment.