# \[ANN\] New package: BitFlags.jl — An enum-like type for bit flags

**URL:** https://discourse.julialang.org/t/ann-new-package-bitflags-jl-an-enum-like-type-for-bit-flags/14912
**Category:** Community
**Tags:** enum
**Created:** [September 13, 2018, 2:52pm UTC](https://discourse.julialang.org/t/ann-new-package-bitflags-jl-an-enum-like-type-for-bit-flags/14912 "2018-09-13T14:52:56Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![jmert](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmert/32/3161_2.png) [@jmert](https://discourse.julialang.org/u/jmert)
#### Post date: [September 13, 2018, 2:52pm UTC](https://discourse.julialang.org/t/ann-new-package-bitflags-jl-an-enum-like-type-for-bit-flags/14912/1 "2018-09-13T14:52:56Z")

</div>

I’d like to announce [`BitFlags.jl`](https://github.com/jmert/BitFlags.jl), a package that provides an `@enum`-like macro that constructs types tailored for use with bit flags. It’s largely a borrowing of the `Enum` code with minor modifications, so almost all the credit goes to everyone who worked on the Base implementation. What it provides on top of a regular `Enum` is:

- Automatic power-of-two numbering, and enforcement that members are a power of two
- Binary AND (`&`) and OR (`|`) operations are defined
- Pretty-printing of values as combinations of members

For example, my motivation was to make data structures dumped from memory easier to introspect — e.g.

```julia
julia> # Setup dummy data — could be file instead

julia> buf = IOBuffer(); write(buf, Int32(1), UInt32(11), Int64(100)); seekstart(buf);

julia> using BitFlags

julia> @bitflag DummyFeatures::UInt32 begin
           FEAT_ACTIVE
           FEAT_READ
           FEAT_WRITE
           FEAT_BACKUP
           FEAT_SHARED
       end

julia> struct DummyHeader
           version::Int32
           features::DummyFeatures
           payload_size::Int64
       end

julia> reinterpret(DummyHeader, read(buf, sizeof(DummyHeader)))[1]
DummyHeader(1, FEAT_ACTIVE | FEAT_READ | FEAT_BACKUP::DummyFeatures = 0x0000000b, 100)

```

Hopefully others can derive some utility from this simple package.

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [September 13, 2018, 3:13pm UTC](https://discourse.julialang.org/t/ann-new-package-bitflags-jl-an-enum-like-type-for-bit-flags/14912/2 "2018-09-13T15:13:42Z")

</div>

Cool. Should be coming to Base sometime too: [RFC: EnumSet type by simonbyrne · Pull Request #19470 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/19470)

---

<div class="post-metadata">

### Author: ![jmert](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmert/32/3161_2.png) [@jmert](https://discourse.julialang.org/u/jmert)
#### Post date: [September 13, 2018, 3:24pm UTC](https://discourse.julialang.org/t/ann-new-package-bitflags-jl-an-enum-like-type-for-bit-flags/14912/3 "2018-09-13T15:24:08Z")

</div>

Ah, interesting! I’d tried searching for such a feature last weekend and apparently never came up with the right search query to bring up that PR.

---

<div class="post-metadata">

### Author: ![caprilo](https://avatars.discourse-cdn.com/v4/letter/c/67e7ee/32.png) [@caprilo](https://discourse.julialang.org/u/caprilo)
#### Post date: [February 18, 2019, 7:33pm UTC](https://discourse.julialang.org/t/ann-new-package-bitflags-jl-an-enum-like-type-for-bit-flags/14912/4 "2019-02-18T19:33:40Z")

</div>

Hi. Thanks! This is really helpful.

I found one behavior of the code which I don’t know if is expected: the bitwise and operation between two constants cuases an error. For example:

@bitflag flag begin  
f1  
f2  
f3  
end

---

<div class="post-metadata">

### Author: ![caprilo](https://avatars.discourse-cdn.com/v4/letter/c/67e7ee/32.png) [@caprilo](https://discourse.julialang.org/u/caprilo)
#### Post date: [February 18, 2019, 7:33pm UTC](https://discourse.julialang.org/t/ann-new-package-bitflags-jl-an-enum-like-type-for-bit-flags/14912/5 "2019-02-18T19:33:43Z")

</div>

[sorry, I pressed ‘Reply’ too early by error]

```julia
f1 & f2 # causes an error

```

also

```julia
g = f1 | f2
g & f1 #causes error

```

And this is important to check if the flag is present or not. I believe the zero flag should be permitted 🙂

---

<div class="post-metadata">

### Author: ![jmert](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmert/32/3161_2.png) [@jmert](https://discourse.julialang.org/u/jmert)
#### Post date: [March 10, 2019, 6:41pm UTC](https://discourse.julialang.org/t/ann-new-package-bitflags-jl-an-enum-like-type-for-bit-flags/14912/6 "2019-03-10T18:41:36Z")

</div>

If you explicitly permit a zero-valued item, then it works without type conversions:

```julia
julia> using BitFlags

julia> @bitflag flag begin
       f1
       f2
       f3
       fnone = 0
       end

julia> f1 & f2
fnone::flag = 0x00000000

```

(I don’t see an error in the second case you gave — did you mean to do `g & f3`?

This behavior was specifically chosen because you may want to enforce at least one flag bit being set for any given realization/instantiation of the bit falgs. You can also cast to regular integers to compare to zero:

```julia
julia> Int(g) & Int(f3)
0

```

I debated with myself on exactly how to handle this case, and I figured allowing explicitly-zero flags in the definition was a reasonable solution.

---

<div class="post-metadata">

### Author: ![caprilo](https://avatars.discourse-cdn.com/v4/letter/c/67e7ee/32.png) [@caprilo](https://discourse.julialang.org/u/caprilo)
#### Post date: [March 10, 2019, 7:12pm UTC](https://discourse.julialang.org/t/ann-new-package-bitflags-jl-an-enum-like-type-for-bit-flags/14912/7 "2019-03-10T19:12:16Z")

</div>

Great! That indeed solves the problem. Thank you very much.
