This is a simple C++ wrapper class for handling bitmasks. It's missing a few more-or-less non-critical features (like the ability to test two Bitmask objects against each other, for instance) but the basics are there, and it works pretty well. It's certainly safer than just globbing some &|^ operator cruft all through the code, and definitely more readable. With a couple of exceptions (mainly tweaked comments) it's straight from the code library I use at work.
/* * bitmask.h * * This wrapper provides a checked, typesafe mechanism for * storing bitmasks. Each bit's value is defined in an enum * separately, and the enum is provided to the template. * The storage size of the bitmask can be explicitly set as * well using template parameters. * * Note that this object has literally no overhead versus * simply writing the bitfield ops by hand in raw code: the * storage of each instance is minimal and controlled by the * templated storage type; there are no virtual members and * therefore no vtabl for the objects; and all operations * are inlined by the compiler so there is no function call * overhead for manipulating or checking the bitmask. * */#pragma oncetemplateclass Bitmask{public: Bitmask(Holder defval = 0) : Bitfield(defval) { } // Sets all bitmask bits which are set in "flags" inline void Set(FlagEnum flags) { Bitfield |= flags; } // Clears all bitmask bits which are set in "flags" inline void Clear(FlagEnum flags) { Bitfield &= (~flags); } // Return true if ANY of the bits set in "flags" are // also set for the bitmask inline bool Test(FlagEnum flags) const { return ((Bitfield & flags) != 0); } // Return true only if ALL bits set in "flags" are // also set for the bitmask inline bool TestAllFlags(FlagEnum flags) const { return ((Bitfield & flags) == flags); }protected: Holder Bitfield;};
Here's a quick sample usage, adapting nobodynews' example from the original thread:
#include "bitmask.h"enum WindowAppearanceFlags : unsigned{ WA_FullScreen = 0x001, WA_ScrollBarX = 0x002, WA_ScrollBarY = 0x004, WA_NoResize = 0x008, WA_NoMinimize = 0x010};typedef Bitmask<unsigned, WindowAppearanceFlags> WindowAppearanceBitmask;void Foo(){ WindowAppearanceBitmask foomask; foomask.Set(WA_FullScreen | WA_NoResize); // Do stuff if(foomask.Test(WA_NoMinimize)) { // etc. }}
No idea if anyone will find that useful or not, but hey, can't hurt [smile]
I personally just use multiple Set() calls, since overloading | for all the dozens of enums in practical use is just annoying.
Also, in the places I use it, combinations of fields usually have specific meanings - so e.g. if I need to test FlagA and FlagB at the same time, there's a good reason why. In that case, I just set up an additional enum constant FlagAB that has the bits set for both A and B. That way I can descriptively refer to the combination, rely on type safety, and don't have to mess with lots of operator overloads. The only downside to that trick is that you have to be careful when shuffling the constants around.