Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I wanted a bit vector that I could use as a compact sorted set of enum values: an inline-allocated, fixed-size array of bits supporting efficient and convenient set operations and iteration.
The C++ standard library offers
std::bitset
, but the API is far from ideal for this purpose. It's positioned as an abstract bit-vector rather than as a set. To use it as a set, you have to turn your values into indices, which for enums means explicitly casting them all in the caller. There's also no iteration operation, so to find the elements of the set, you have to iterate over all possible indices, test whether they're in the set, and (if so) cast the current index back to the enum. Not only is that much more awkward than normal iteration, but it's also substantially less efficient than what you can get by counting trailing zeroes in a mask.LLVM and Swift offer a number of other bit vectors, but they're all dynamically allocated because they're meant to track arbitrary sets. That's not a non-starter for my use case, which is in textual serialization and so rather slow anyway, but it's also not very hard to whip together the optimal data structure here.
I have committed the cardinal sin of C++ data structure design and provided the operations as ordinary methods instead of operators.