Free code!

Published June 18, 2006
Advertisement
I originally dropped this in a thread in For Beginners, but after thinking about it for a minute I decided maybe someone else could find it handy too, so I'll stick a copy here where it will get a little better visibility.


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]
0 likes 4 comments

Comments

ApochPiQ
Good catch - that was an oversight in my translation of the example usage.

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.
June 18, 2006 07:48 AM
jollyjeffers
Neat trick, but I've tended to solve the readability of such constructs (often used when checking D3D caps bits) via macros. Yes, I know thats A Bad Thing™, but it works [razz]

Cheers,
Jack
June 18, 2006 07:54 AM
nobodynews
Holy crap. I'm not sure what's more surprising: that I'm referenced in someone's journal or that I actually have been reading that journal off and on for a few weeks.

Edit: Like the code, by the way. I'm definately saving this post for future reference.
June 22, 2006 12:29 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement