Introduction
Dealing in both the embedded and GUI world, there are many times where I find that I want to store large numbers of BOOL
flags or enum
s that have a limited range, say 0 to 7 for example, but I do not want to take up an INT
to store such a thing to disk. Historically, I have followed the steps of those before me at work and created integers and masks to grab the correct bit to store or retrieve the value. Recently, a coworker came up with a nice idea of abstracting this to be viewed as an array. I decided that I wanted to try that idea from scratch and created CABMBitSet
template class.
The idea was to be able to access a bit with the array �[]
� operator for setting and retrieving the value such that it would accept a BOOL
for setting the value and present a BOOL
when retrieving the value. Then I wanted to go a step further.
Why limit the interface to BOOL
? Very often, I store enum
values where the range of the enum
is rather small and certainly not 32,000(ish). So I created CFlexBitSet
template class. This one allows you to not only define how many elements are in the array, but also how many bits each element needs and how it should appear (class type (BOOL
, int
, etc.)) to the outside code.
Both allow you to:
- Set/Get the value with the �
[]
� operator.
- Get the bit values in string format (intended for debugging mostly).
- Get/Set the array of bits from your own array of
UINT32
values that would be saved to disk.
Background
Most will find this code overkill... That�s ok. I wrote it for fun and to make my life easier. If you find it useful, that�s just a bonus.
Also, you will see commenting in the code in the style of CCDoc. If you don�t have the tool (just an EXE) and would like to reproduce the documentation, a quick search for CCDoc will find it at SF. The documentation is included in the demo project download if you want to check out the HTML documentation...
Using the code
Using it is fairly straightforward. Below I show the general type of interaction and leave the saving to file up to the user. I noted another article that had the user code pass in a (FILE*)
for saving / retrieving the value. I decided against this as there are too many things one may want to do with the data before sending to the file, besides the user code may not want to use a (FILE*)
for persisting to disk. Therefore, that part is left to the user code.
- typedef the template to your needs - For this step, you need to know how many elements you are working with.
typedef CFlexBitSet<10,1,BOOL> CFlexBitSet_10_BOOL;
typedef CFlexBitSet<17,2,int> CFlexBitSet_17_int2;
typedef CABMBitSet<17> CBitSetBOOL17;
- Declare an instance of the variable for use.
CFlexBitSet_10_BOOL m_BitSet;
CFlexBitSet_17_int2 m_BitSet2int;
CBitSetBOOL17 m_BoolSet;
- Set or get values from the variable.
m_BitSet2int[ m_iElement ] = m_iSetValue;
m_BitSet[2] = TRUE;
m_BoolSet[3] = TRUE;
if ( m_BoolSet[2] ) {
...
}
if ( m_BitSet[2] ) {
...
}
If(m_BitSet2int[ m_iElement ] == iSomeTestValue){
...
}
- Get or Set the value (as a whole) from outside storage (for persisting data between instances).
UINT32* pTest = NULL;
int SizeArray;
BitSet.GetRawData(pTest, SizeArray);
StoreUINT32ArrayToFile( pTest, SizeArray );
< ... time passes and we need to get it from the file ... >
GetFileStoredUINTArrayFromFile( pTest, SizeArray );
BitSet.SetRawData(pTest, SizeArray);
delete[] pTest;
Points of Interest
- Q: Hey, why did you make this a template class? This could have been done in a more flexible manner if you made the template parameters part of the constructor.
A: Hmmmm... you have a point there. However, I wrote it as a template anyway. Maybe I should change it, but for now, this seems to suit all my needs.
- Q: What�s with the CCDoc comments?
A: Ever since I started trying CCDoc, I fell in love with it. I often write code that I want to use later but when I want to use it, I want a document that I can refer to without having to trod through the code. CCDoc provides that type of documentation that I find useful... as long as I comment it sufficiently.
- Q: Why two classes? The
CFlexBitSet
can do the duty of both.
A: True. But I wrote the CABMBitSet
for the immediate need of a large set of BOOL
flags that I needed to store. But after I wrote that one, I wanted to see how much it would take to convert it to handle elements that might need 2, 3, or more bits (up to 31) in the same manner.
- Q: In your example, you use hard coded index numbers to access certain elements. Is that wise?
A: Of course not. In practice, I would substitute either values that were �#define
� or an enum
. But hey, in an example, I wanted to keep it simple.
- Q: Why should I use your code?
A: You shouldn�t. ...unless it suits your needs and you do not want to write it all over again. Knowing is half the battle, ...do unto others..., etc.
- Q: I like the way you used an internal class to allow the use of �
[]
� operator for set and get.
A: Thanks, but I can�t take the credit for that idea. I got that from a friend of mine, JAS, and he has also found that idea out there on the web somewhere. I just wanted to make sure the idea was formally placed out there... or rather, here. Can I call this code mine? Not really. I do not even claim complete ownership of the idea. But hey, I can�t stop you either, nor would I try. Hehehe, but then again, why would you?
- Q: Hey, want to go grab a beer?
A: Sure, let�s go!
- Q: Why does the dialog use Courier New for the font?
A: Because the string representation GetStrRepresentation(TRUE,FALSE);
uses two lines and without a fixed pitch font, and that can look goofy. If you want to get around this in your testing, then send it to a MessageBox( ... )
and then when the box appears, hit <ctrl>+c, open Notepad, and paste it there. Notepad, I believe by default, uses a fixed pitch font.
History
(2005-03-27) My initial release.