RFC: a macro for iterating flags

Hello,

One of the things I really like about hacking on the LLVM/Swift code base is the strong commitment to fully covered switch statements. It makes experimenting/learning/etc very approachable and straightforward.

Unfortunately, this design pattern doesn't work when the enum is used to hold flags.

I've often wished that adding a new flag would cause the same kind of compiler errors as normal switch statements. It would make ensuring correctness and completeness much easier to do.

Towards that end, I'd like to propose a simple (albeit somewhat gross) macro:

#define FOREACH_FLAG(FLAGS) \
  for (auto _flags_ = (FLAGS); (long long)_flags_; \
    _flags_ = decltype(_flags_)(((long long)_flags_ - 1) & (long long)_flags_)) \
    switch (decltype(_flags_)(-(long long)_flags_ & (long long)_flags_))

And here is an example that prints "A" and "C":

Example e = Example::A | Example::C;
FOREACH_FLAG (e) {
case Example::A: printf("A\n"); break;
case Example::B: printf("B\n"); break;
case Example::C: printf("C\n"); break;
case Example::D: printf("D\n"); break;
}

What do people think? Is the trade off worth it? I know it's kind of gross but I would really appreciate having a zillion compiler errors when adding a new flag and I imagine many others would as well.

Thanks for any feedback,
Dave

1 Like
Terms of Service

Privacy Policy

Cookie Policy