Sign in to follow this  
Xentropy

Change storage size of an STL bitset?

Recommended Posts

Is it possible to create a bitset<16> that only uses 2 bytes instead of 4? From what I gather from the STL documentation I have, sizeof(bitset<N>) is undefined (i.e. defined by the implementation and not the standard), so I'm guessing the answer is no, but if that is the case, I'd like suggestions as to how to implement the following: I need to read records in a database file that was written by an old Pascal program. The file format is fixed the way it is and cannot reasonably be changed. Some of the fields are 16-bit bitfields. I'm currently reading them as unsigned shorts and performing bit operator manipulations on them manually to test various flags, but would vastly prefer using the STL where possible. (This forum is constantly saying not to reinvent the wheel.) The problem is if I create a structure like the following:
struct fileRecord {
    unsigned short value1;
    char value2[6];
    double value3;
    bitset<16> value4;
    unsigned long value5;
};
...then sizeof(fileRecord) ends up being 20 instead of 18, because sizeof(bitset<16>) is 4 instead of 2. (It appears that the base type for a storage word is unsigned long, at least in .NET 2005's implementation.) Reading entire records at once therefore becomes impossible. I'd like a solution that uses bitsets for code clarity but doesn't involve converting unsigned shorts to bitsets manually after reading the file, but from what I can tell such a solution doesn't exist. I only see three options: 1) Read the data as unsigned short and perform manual bit manipulations. (Good speed and simple read code, but overly complex post-read accessor code.) 2) Read the data as unsigned short and then convert it to bitsets after the file is read, via bitset<16> flags[i] = record[i].shortValue. (Speed and memory penalty due to data type conversion time and allocating space for an unsigned short and a bitset<16>, plus only using the lower 16 bits of each bitset, but post-read accessor code after the conversion would be clearer.) 3) Read the data one portion of the structure at a time (or even one field at a time) instead of entire structures at once, so I can read two bytes of data into the four-byte bitset memory block. (Speed penalty reading the file, and more confusing code storing the read data due to breaking up structures haphazardly, but clearer code post-read.) Am I missing something or am I correct in assuming I'm stuck with the way I'm currently doing things without compromising a lot of speed or just moving the complicated code around instead of eliminating it? I'm open to other alternatives! Thanks in advance.

Share this post


Link to post
Share on other sites
Well, the problem is that you need to align that last long (value5) on a 2-byte boundary instead of 4. You can change your default project alignment properties, or you can look into the #pragma pack() directive.

Also if you want named fields for your bitset, you can use a bit field.

Share this post


Link to post
Share on other sites
Quote:
Original post by ajas95
Well, the problem is that you need to align that last long (value5) on a 2-byte boundary instead of 4. You can change your default project alignment properties, or you can look into the #pragma pack() directive.


If you're talking about what I think you are, I already changed the compiler options because some of the structure data is single chars and I was having trouble getting the structures to be the right size without setting "struct member alignment" to 1 byte.

My issue is even without a structure involved, bitsets allocate memory in blocks of 4 bytes. I was wondering if there was any way to change this without implementing my own custom bitset type or just using bit manipulation on a short. Sorry if I was unclear.

Quote:
Also if you want named fields for your bitset, you can use a bit field.


I was just using enums for the flag names. Could you point me to information on "bit fields"? I was of the impression the only standard types that meet my needs were vector<bool> and bitset<N>, and since bitsets have the sorts of member functions that fit my needs perfectly, I'd prefer those.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this