tags:

views:

158

answers:

4

I need to use bit flags with more than 32 bits (33 to be exact right now). I tried and find std::bitset doesn't handle more than 32 bits (ulong). Do I have to use vector or there's a way to make bitset to work?

I am limited to c++98 in this project so I can't use boost.

Thanks.

Edit:

I'd like to do something like this:

const uint64    kBigNumber = 1LL << 33;
std::bitset<33> myBitSet;
...
switch(myBitSet) {
    case kBigNumber:
    // do something
    ...
}
+5  A: 

Would std::vector<bool> work for you? It can be resized, is reasonably fast and has a small footprint. It's also part of the STL.

andand
Yet not STL-compliant, excitingly
chrispy
+5  A: 

std::bitset should work with more or less arbitrary sizes -- it's not normally limited to the size of an unsigned long (though it can look that way, because there's a constructor that builds a bitset based on the bits in an unsigned long).

If that won't work, vector<bool> may be useful for you, though you should be aware that it's pretty much a vector in name only -- it is not really a container (i.e., doesn't conform to the normal container requirements).

Jerry Coffin
+3  A: 

I've just retested std::bitset with 65 bits and on my 32-bit Linux it works fine and as expected.

Notable exception is the to_ulong() method which throws exception if any set bit would be truncated during the conversion. Now I think about it and that is rather obvious: there is no other way as to prevent application from getting truncated data. And the behavior is also documented.


To the Edit with switch/case. Why do you need std::bitset then? You platform apparently already supports 64 bit numbers - use them. std::bitset is designed to be used as an light-weight bit array with static memory allocation. It is not intended to be used as a replacement for number.

Dummy00001
I am using plain 64-bit unsigned right now. I am exploring different ways to do it and also to plan for the future where the flags can be more than 64 bits.
Stephen Chu
You can use only integer types for switch/case in C/C++. `uint64_t` (or whatever widest integer type your compiler supports) is as far you would be able to jump on 32bit arch. And more then 64 flags - this sounds like a bad idea. Ask here on SO how to avoid that.
Dummy00001
+1  A: 

You can use the to_string on your bitset and covert it back using strtoull

const uint64    kBigNumber = 1LL << 33;
std::bitset<33> myBitSet;
...
unsigned long long bitSetLong = strtoull(myBitSet.to_string<char,char_traits<char>,allocator<char> >().c_str(), NULL, 2);
switch(bitSetLong) {
    case kBigNumber:
    // do something
    ...
}

Note the above can work only till 64 bits.

aeh