Original Post
This class is essentially a bitset, designed to be used in place of many bool variables. It is designed to save space while being nearly as fast as using bools. It can be a big memory saver if you are dealing with a lot of bools, since you can store eight bools in one byte of memory using this method. The most effective way to use this class is to create an enumeration for your values and pass these enumerated values to the functions in this class.
Please look critically at this class. I want it to be as fast and optimized as possible, so if you have any suggestions or things that I may have overlooked, I am eager to hear them.
By the way, I''d love to be able to provide some sort of indexing operator that allowed the user to set the flag, as well as retrieve it, in this fashion:
Flags[1] = true; //not necessarily this syntax
If anyone has a suggestion for how to do this, I''d greatly appreciate it.
Also, can someone comment on the platform independence of this implementation? The only thing I''m not sure about is using memory.h and the memset function.
Without further ado, the FlagSet class...
//FlagSet.h
#pragma once
#include <memory.h>
//Macros for generating bitmasks
#define PostFlag(Var, Flag) (Var |= (1 << Flag))
#define RemoveFlag(Var, Flag) (Var &= (~(1 << Flag)))
#define FlagValue(Var, Flag) ((Var & (1 << Flag)) ? true : false)
typedef char STORAGETYPE; //type used to store our bits
const long STORESIZE = sizeof(STORAGETYPE) * 8;
const unsigned int DEFAULTFLAGS = 32; //Use four bytes by default
class FlagSet
{
public:
FlagSet(unsigned int NumFlags = DEFAULTFLAGS);
~FlagSet();
void SetNumFlags(unsigned int NumFlags);
void SetFlag(long Flag, bool FlagOn);
bool GetFlag(long Flag) const;
bool operator[](long Flag) const;
private:
STORAGETYPE* pFlags;
};
inline bool FlagSet::GetFlag(long Flag) const
//Get a flag''s value
{
return FlagValue(pFlags[(long)(Flag / STORESIZE)], Flag % STORESIZE);
}
inline void FlagSet::SetFlag(long Flag, bool FlagOn)
//Set a flag to true or false
{
FlagOn ? PostFlag(pFlags[(long)(Flag / STORESIZE)], Flag % STORESIZE)
: RemoveFlag(pFlags[(long)(Flag / STORESIZE)], Flag % STORESIZE);
}
inline bool FlagSet::operator[](long Flag) const
{
return GetFlag(Flag);
}
//FlagSet.cpp
#include "FlagSet.h"
FlagSet::FlagSet(unsigned int NumFlags) : pFlags(0)
{
SetNumFlags(NumFlags);
}
FlagSet::~FlagSet()
{
delete [] pFlags;
}
void FlagSet::SetNumFlags(unsigned int NumFlags)
//Sets number of used flags. Also clears any currently stored data
{
long NumBytes = NumFlags / STORESIZE;
if(pFlags)
delete [] pFlags;
if(NumFlags % STORESIZE)
++NumBytes;
pFlags = new STORAGETYPE[NumBytes];
memset(pFlags, 0, NumBytes);
}