Can a C++ enumeration be made bigger than 64 bits? - c++

In my entity component system I track and query which components each entity has using a bit mask.
// Thanks to Shafik Yaghmour for the macro fix
#define BIT(x) (static_cast<std::uint64_t>(1) << x)
enum class components : std::uint64_t
{
foo = BIT( 0),
bar = BIT( 1),
// Many more omitted
baz = BIT(63)
};
// Operator | is used to build a mask of components. Some entities
// have dozens of components.
auto mask = components::foo | components::bar | components::baz
// Do something with the entity if it has the requisite components.
if ( entity->has_components( mask ) ) { ... }
I've hit the 64 bit limit of the enumeration. Can a C++ enumeration (portably) be made bigger than 64 bits?
Update 1: I'm aware of std::bitset, but I can't create a mask like auto mask = std::bitset<128>{ components::foo, components::baz } because std::bitset doesn't have a constructor that takes a std::initializer_list. If your answer tells me to use std::bitset please demonstrate this usage or similar.
Update 2: I hacked up a function to create a std::bitset from a std::initializer_list:
enum class components : std::size_t
{
foo,
bar,
baz,
count
};
template< typename enumeration, std::size_t bit_count = static_cast< std::size_t >( enumeration::count ) >
std::bitset< bit_count > make_bitset(std::initializer_list< enumeration > list)
{
assert(list.size() <= bit_count);
std::bitset< bit_count > bs{};
for (const auto i : list)
{
bs.set(static_cast< std::size_t >(i));
}
return bs;
}
// Which can create the mask like so:
auto mask = make_bitset< components >( {components::foo, components::baz} );

As others noted, the storage must be a std::bitset. But how to interface this to enumerations? Use operator overloading as outlined in this answer. The enumerators only need to store the bit index number, which buys you a little more space ;) .
Note, that code must be expurgated of shift operations, namely:
flag_bits( t bit ) // implicit
{ this->set( static_cast< int >( bit ) ); }
http://ideone.com/CAU0xq

Note, you current code has undefined behavior, the integer literal 1 has type int here:
#define BIT(x) (1 << x)
^
which will probably be 32 bits on most modern systems and so shifting by 32 bit or more is undefined behavior according to the draft C++ standard section 5.8 Shift operators which says:
The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.
The fix for this would be to use static_cast to convert 1 to uint64_t:
#define BIT(x) (static_cast<std::uint64_t>(1) << x)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Or as Potatoswatter points out you can use ULL suffix which is guaranteed to be 64 bit.
There is no portable way to use a larger type than uint64_t, some compilers such as gcc provide for a 128 bit integer type but again that is not portable.
std::bitset should provide the interface you need. You can use set to set any bit to any value and test to test the value of a specific bit. It provides binary or which should provide this functionality:
auto mask = components::foo | components::baz
for example:
#include <bitset>
#include <iostream>
int main()
{
std::bitset<128> foo ;
std::bitset<128> baz ;
foo.set(66,true ) ;
baz.set(80,true ) ;
std::cout << foo << std::endl ;
std::cout << baz << std::endl ;
std::bitset<128> mask = foo | baz ;
std::cout << mask << std::endl ;
return 0;
}

Use a std::bitset.
Addendum:
After I wrote the above answer the question has been updated with mention of std::bitset and some ungood ideas for how to use it, so far with 13 revisions.
I failed to foresee that there could be any difficulty using std::bitset, sorry. For it's just matter of not introducing needless complexity, of abstaining from that. For example, instead of the now suggested
#include <bitset>
enum class components : std::size_t
{
foo,
bar,
baz,
count
};
template< typename enumeration, std::size_t bit_count = static_cast< std::size_t >( enumeration::count ) >
std::bitset< bit_count > make_bitset(std::initializer_list< enumeration > list)
{
assert(list.size() <= bit_count);
std::bitset< bit_count > bs{};
for (const auto i : list)
{
bs.set(static_cast< std::size_t >(i));
}
return bs;
}
auto main() -> int
{
auto mask = make_bitset< components >( {components::foo, components::baz} );
}
just do e.g.
#include <bitset>
namespace component {
using std::bitset;
enum Enum{ foo, bar, baz };
enum{ max = baz, count = max + 1 };
using Set = bitset<count>;
auto operator|( Set const s, Enum const v )
-> Set
{ return s | Set().set( v, true ); }
} // namespace component
auto main() -> int
{
auto const mask = component::Set() | component::foo | component::baz;
}
or simply, without syntactic sugaring,
#include <bitset>
namespace component {
using std::bitset;
enum Enum{ foo, bar, baz };
enum{ max = baz, count = max + 1 };
using Set = bitset<count>;
} // namespace component
auto main() -> int
{
auto const mask = component::Set().set( component::foo ).set( component::baz );
}

Related

Using an already-defined struct as an anonymous member of a union

Let's say I have a 32-bit hardware register Reg that I want to be able to access either as a 32-bit value (e.g. Reg = 0x12345678) or as bitfields (e.g. Reg.lsw = 0xABCD). I can achieve this by declaring a union with anonymous struct member, and declaring assignment and conversion operators to/from uint32_t. In a little-endian environment, the code might look like this:
#include <cstdint>
#include <cstdio>
typedef union
{
uint32_t val ;
struct
{
uint32_t lsw : 16 ;
uint32_t msw : 16 ;
} ;
operator = (uint32_t n) { val = n ; }
operator uint32_t() const { return val ; }
} HWR ;
int main()
{
HWR Reg ;
Reg = 0x12345678 ;
Reg.lsw = 0xABCD ;
printf ("%X\n", uint32_t(Reg)) ;
}
But now let's say I have a whole bunch of these registers, each with its own bitfield layout, and I have a header file FieldDefs.h that declares these bitfield layouts as named structures. How can I use these named structures in the above code, so that I can access the 32-bit value and also the individual bitfields? I could do it like this:
#include "FieldDefs.h" // Defines struct MyHWR
typedef union
{
uint32_t val ;
struct MyHWR field ;
operator = (uint32_t n) { val = n ; }
operator uint32_t() const { return val ; }
} MyHWRUnion ;
But now instead of Reg.lsw =..., I need to type Reg.field.lsw =...
Is there any way (in C++17) to declare an already defined struct as an anonymous member of a union? I am using g++ version 7.3.0 if it matters.
union
{
// ...
struct
{
// ...
};
This is an anonymous struct. Anonymous structs are ill-formed in C++. Only unions may be anonyous. This is different from C where anonymous structs are allowed (since C11).
Is there any way (in C++17) to declare an already defined struct as an anonymous member of a union?
No. Unnamed members cannot have a named type.
You'll need to make a choice between the unnamed member and the pre-declared class. Given that the anonymous struct is non-standard in the first place, I recommend going with the named member and pre-defined class. Maybe give it a short name to minimise verbosity.
I suppose none will like this answer, neither OP (since requires g++ 9.1), neither C++ gurus (UB smells?), but I am still a little proud of tinkering it.
There is [[no_unique_address]] attribute coming in C++20 and g++ 9.1 already supports it (even without -std=c++2a flag).
How can it be utilized here?
By test and trials it seems that if we create proxy member val marked with it it will take address of object1.
Thus we can create Proxy class which has operator=(uint32_t) and operator uint32_t that treats this as uint32_t. The proxy object has no address, does not increase size of struct that utilizes it.
Bitfields names have to be added by inheritance, which got wrapped in simple template, for consistency named HWR.
Voilà, we have HWR<bitfield> object which can be assigned to uint32_t directly, by val member and gives access to bitfields names.
https://godbolt.org/z/N2xEmz
#include <bits/stdint-uintn.h>
#include <cstddef>
#include <cstdint>
#include <cstdio>
// Example bifields, I assumed you have such in "FieldDefs.h"
struct bitfield {
uint32_t lsw : 16;
uint32_t msw : 16;
};
struct ThisProxy {
uint32_t& operator=(uint32_t n) {
auto& uint = *reinterpret_cast<uint32_t*>(this);
uint = n;
return uint;
}
operator uint32_t() const { return *reinterpret_cast<const uint32_t*>(this); }
};
template <typename Bitfield>
struct HWR : Bitfield {
static_assert(sizeof(Bitfield) == 4, "Bad things would happen");
HWR& operator=(uint32_t n) {
this->val = n;
return *this;
}
operator uint32_t() const { return this->val; }
[[no_unique_address]] ThisProxy val;
};
int main() {
HWR<bitfield> Reg;
// Sanity check that proxy points at &Reg and does not increase size
static_assert(offsetof(HWR<bitfield>, val) == 0, "");
static_assert(sizeof(HWR<bitfield>) == 4, "");
Reg = 0x12345678;
Reg.val = 0x8765432A;
Reg.lsw = 0xABCA;
printf("%X\n%ld\n", uint32_t(Reg), sizeof(Reg));
return 0;
}
Edit:
As it turned out that access by Reg.val is not mandatory the trick with inheritance + reinterpret_cast can be reused in pre-C++20 code.
template <typename Bitfield> struct HWR : Bitfield {
static_assert(sizeof(Bitfield) == 4, "Bad things would happen");
HWR &operator=(uint32_t n) {
*reinterpret_cast<uint32_t *>(this) = n;
return *this;
}
operator uint32_t() const {
return *reinterpret_cast<const uint32_t *>(this);
}
};
There is still smell of reinterpret_cast and I need to find out oine thing to fully recommend this code. Whenever bitfield can be interpreted by underlying type uint32_t.
1 I am not sure whenever offset of 0 is guaranteed by P0840R2.
PS. g++ complains with warning: offsetof within non-standard-layout type ‘HWR<bitfield>’ is conditionally-supported [-Winvalid-offsetof], but I didn't try to find workaround for it.
PPS. No anonymous structs!

Is it possible to perform a string to int mapping at compile time?

Is it possible to perform a unique string to int mapping at compile time?
Let's say I have a template like this for profiling:
template <int profilingID>
class Profile{
public:
Profile(){ /* start timer */ }
~Profile(){ /* stop timer */ }
};
which I place at the beginning of function calls like this:
void myFunction(){
Profile<0> profile_me;
/* some computations here */
}
Now I'm trying to do something like the following, which is not possible since string literals cannot be used as a template argument:
void myFunction(){
Profile<"myFunction"> profile_me; // or PROFILE("myFunction")
/* some computations here */
}
I could declare global variables to overcome this issue, but I think it would be more elegant to avoid previous declarations. A simple mapping of the form
”myFunction” → 0
”myFunction1” → 1
…
”myFunctionN” → N
would be sufficient. But to this point neither using constexpr, template meta-programming nor macros I could find a way to accomplish such a mapping. Any ideas?
As #harmic has already mentioned in the comments, you should probably just pass the name to the constructor. This might also help reduce code bloat because you don't generate a new type for each function.
However, I don't want to miss the opportunity to show a dirty hack that might be useful in situations where the string cannot be passed to the constructor. If your strings have a maximum length that is known at compile-time, you can encode them into integers. In the following example, I'm only using a single integer which limits the maximum string length to 8 characters on my system. Extending the approach to multiple integers (with the splitting logic conveniently hidden by a small macro) is left as an exercise to the reader.
The code makes use of the C++14 feature to use arbitrary control structures in constexpr functions. In C++11, you'd have to write wrap as a slightly less straight-forward recursive function.
#include <climits>
#include <cstdint>
#include <cstdio>
#include <type_traits>
template <typename T = std::uintmax_t>
constexpr std::enable_if_t<std::is_integral<T>::value, T>
wrap(const char *const string) noexcept
{
constexpr auto N = sizeof(T);
T n {};
std::size_t i {};
while (string[i] && i < N)
n = (n << CHAR_BIT) | string[i++];
return (n << (N - i) * CHAR_BIT);
}
template <typename T>
std::enable_if_t<std::is_integral<T>::value>
unwrap(const T n, char *const buffer) noexcept
{
constexpr auto N = sizeof(T);
constexpr auto lastbyte = static_cast<char>(~0);
for (std::size_t i = 0UL; i < N; ++i)
buffer[i] = ((n >> (N - i - 1) * CHAR_BIT) & lastbyte);
buffer[N] = '\0';
}
template <std::uintmax_t Id>
struct Profile
{
char name[sizeof(std::uintmax_t) + 1];
Profile()
{
unwrap(Id, name);
std::printf("%-8s %s\n", "ENTER", name);
}
~Profile()
{
std::printf("%-8s %s\n", "EXIT", name);
}
};
It can be used like this:
void
function()
{
const Profile<wrap("function")> profiler {};
}
int
main()
{
const Profile<wrap("main")> profiler {};
function();
}
Output:
ENTER main
ENTER function
EXIT function
EXIT main
In principle you can. However, I doubt any option is practical.
You can set your key type to be a constexpr value type (this excludes std::string), initializing the value type you implement is not a problem either, just throw in there a constexpr constructor from an array of chars. However, you also need to implement a constexpr map, or hash table, and a constexpr hashing function. Implementing a constexpr map is the hard part. Still doable.
You could create a table:
struct Int_String_Entry
{
unsigned int id;
char * text;
};
static const Int_String_Entry my_table[] =
{
{0, "My_Function"},
{1, "My_Function1"},
//...
};
const unsigned int my_table_size =
sizeof(my_table) / sizeof(my_table[0]);
Maybe what you want is a lookup table with function pointers.
typedef void (*Function_Pointer)(void);
struct Int_vs_FP_Entry
{
unsigned int func_id;
Function_Point p_func;
};
static const Int_vs_FP_Entry func_table[] =
{
{ 0, My_Function},
{ 1, My_Function1},
//...
};
For more completion, you can combine all three attributes into another structure and create another table.
Note: Since the tables are declared as "static const", they are assembled during compilation time.
Why not just use an Enum like:
enum ProfileID{myFunction = 0,myFunction1 = 1, myFunction2 = 2 };
?
Your strings will not be loaded in runtime, so I don't understand the reason for using strings here.
It is an interesting question.
It is possible to statically-initialize a std::map as follows:
static const std::map<int, int> my_map {{1, 2}, {3, 4}, {5, 6}};
but I get that such initialization is not what you are looking for, so I took another approach after looking at your example.
A global registry holds a mapping between function name (an std::string) and run time (an std::size_t representing the number of milliseconds).
An AutoProfiler is constructed providing the name of the function, and it will record the current time. Upon destruction (which will happen as we exit the function) it will calculate the elapsed time and record it in the global registry.
When the program ends we print the contents of the map (to do so we utilize the std::atexit function).
The code looks as follows:
#include <cstdlib>
#include <iostream>
#include <map>
#include <chrono>
#include <cmath>
using ProfileMapping = std::map<std::string, std::size_t>;
ProfileMapping& Map() {
static ProfileMapping map;
return map;
}
void show_profiles() {
for(const auto & pair : Map()) {
std::cout << pair.first << " : " << pair.second << std::endl;
}
}
class AutoProfiler {
public:
AutoProfiler(std::string name)
: m_name(std::move(name)),
m_beg(std::chrono::high_resolution_clock::now()) { }
~AutoProfiler() {
auto end = std::chrono::high_resolution_clock::now();
auto dur = std::chrono::duration_cast<std::chrono::milliseconds>(end - m_beg);
Map().emplace(m_name, dur.count());
}
private:
std::string m_name;
std::chrono::time_point<std::chrono::high_resolution_clock> m_beg;
};
void foo() {
AutoProfiler ap("foo");
long double x {1};
for(std::size_t k = 0; k < 1000000; ++k) {
x += std::sqrt(k);
}
}
void bar() {
AutoProfiler ap("bar");
long double x {1};
for(std::size_t k = 0; k < 10000; ++k) {
x += std::sqrt(k);
}
}
void baz() {
AutoProfiler ap("baz");
long double x {1};
for(std::size_t k = 0; k < 100000000; ++k) {
x += std::sqrt(k);
}
}
int main() {
std::atexit(show_profiles);
foo();
bar();
baz();
}
I compiled it as:
$ g++ AutoProfile.cpp -std=c++14 -Wall -Wextra
and obtained:
$ ./a.out
bar : 0
baz : 738
foo : 7
You do not need -std=c++14, but you will need at least -std=c++11.
I realize this is not what you are looking for, but I liked your question and decided to pitch in my $0.02.
And notice that if you use the following definition:
using ProfileMapping = std::multi_map<std::string, std::size_t>;
you can record every access to each function (instead of ditching the new results once the first entry has been written, or overwriting the old results).
You could do something similar to the following. It's a bit awkward, but may do what you want a little more directly than mapping to an integer:
#include <iostream>
template <const char *name>
class Profile{
public:
Profile() {
std::cout << "start: " << name << std::endl;
}
~Profile() {
std::cout << "stop: " << name << std::endl;
}
};
constexpr const char myFunction1Name[] = "myFunction1";
void myFunction1(){
Profile<myFunction1Name> profile_me;
/* some computations here */
}
int main()
{
myFunction1();
}

How does one use an enum class as a set of flags?

Let's say I have a set of flags and a class like this:
/// <summary>Options controlling a search for files.</summary>
enum class FindFilesOptions : unsigned char
{
LocalSearch = 0,
RecursiveSearch = 1,
IncludeDotDirectories = 2
};
class FindFiles : boost::noncopyable
{
/* omitted */
public:
FindFiles(std::wstring const& pattern, FindFilesOptions options);
/* omitted */
}
and I want a caller to be able to select more than one option:
FindFiles handle(Append(basicRootPath, L"*"),
FindFilesOptions::RecursiveSearch | FindFilesOptions::IncludeDotDirectories);
Is it possible to support this in a strongly-typed way with C++11 enum class, or do I have to revert to untyped enumerations?
(I know the caller could static_cast to the underlying type and static_cast back, but I don't want the caller to have to do that)
It is certainly possible to use enum classes for bitmaps. It is, unfortunately, a bit painful to do so: You need to define the necessary bit operations on your type. Below is an example how this could look like. It would be nice if the enum classes could derive from some other type which could live in a suitable namespace defining the necessary operator boilerplate code.
#include <iostream>
#include <type_traits>
enum class bitmap: unsigned char
{
a = 0x01,
b = 0x02,
c = 0x04
};
bitmap operator& (bitmap x, bitmap y)
{
typedef std::underlying_type<bitmap>::type uchar;
return bitmap(uchar(x) & uchar(y));
}
bitmap operator| (bitmap x, bitmap y)
{
typedef std::underlying_type<bitmap>::type uchar;
return bitmap(uchar(x) | uchar(y));
}
bitmap operator^ (bitmap x, bitmap y)
{
typedef std::underlying_type<bitmap>::type uchar;
return bitmap(uchar(x) ^ uchar(y));
}
bool test(bitmap x)
{
return std::underlying_type<bitmap>::type(x);
}
int main()
{
bitmap v = bitmap::a | bitmap::b;
if (test(v & bitmap::a)) {
std::cout << "a ";
}
if (test(v & bitmap::b)) {
std::cout << "b ";
}
if (test(v & bitmap::c)) {
std::cout << "c ";
}
std::cout << '\n';
}
Templates play well with enum class so you can define sets of operators that work on sets of similar enumeration types. The key is to use a traits template to specify what interface(s) each enumeration conforms/subscribes to.
As a start:
enum class mood_flag {
jumpy,
happy,
upset,
count // size of enumeration
};
template<>
struct enum_traits< mood_flag > {
static constexpr bool bit_index = true;
};
template< typename t >
struct flag_bits : std::bitset< static_cast< int >( t::count ) > {
flag_bits( t bit ) // implicit
{ this->set( static_cast< int >( bit ) ); }
// Should be explicit but I'm lazy to type:
flag_bits( typename flag_bits::bitset set )
: flag_bits::bitset( set ) {}
};
template< typename e >
typename std::enable_if< enum_traits< e >::bit_index,
flag_bits< e > >::type
operator | ( flag_bits< e > set, e next )
{ return set | flag_bits< e >( next ); }
template< typename e >
typename std::enable_if< enum_traits< e >::bit_index,
flag_bits< e > >::type
operator | ( e first, e next )
{ return flag_bits< e >( first ) | next; }
http://ideone.com/kJ271Z
GCC 4.9 reported that some implicit member functions were constexpr while I was getting this to compile, so the templates should probably be so as well.
This should probably also have a free function to_scalar or something which returns an unsigned integer type given either an individual flag or a flag_bits set.
How about defining FindFiles so that it takes std::initializer_list of FindFilesOptions.
void FindFiles(std::wstring const& pattern, std::initializer_list<FindFilesOptions> options)
{
auto has_option = [&](FindFilesOptions const option)
{
return std::find(std::begin(options), std::end(options), option) != std::end(options);
};
if (has_option(FindFilesOptions::LocalSearch))
{
// ...
}
if (has_option(FindFilesOptions::RecursiveSearch))
{
// ...
}
if (has_option(FindFilesOptions::IncludeDotDirectories))
{
// ...
}
}
Then you could call it like so:
FindFiles({}, {FindFilesOptions::RecursiveSearch, FindFilesOptions::IncludeDotDirectories});
The problem is not the explicit enum type but the class scope.
With C++11, enum as compile time constant loose a lot of interest compared to a bunch of constexpr when you need operate on the value ( bitwise operation, incrementation, etc)
If you don't care about performance, change your options to set<FindFilesOptions>!

Typedef a bitfield / mask in C++

I have this problem in C++: can I typedef a bitfield whose values come from an enum?
Code will be more explainatory:
typedef {
AUDIO = 0x01,
VIDEO = 0x02,
SUBTITLE = 0x04,
DATA = 0x08,
GUARD,
ALL = 0xFF
} my_enum_e;
// I'd like to replace 'unsigned int' by 'my_enum_e' or similar
int myFunction( unsigned int mask )
{
// code
}
// called like this:
myFunction( AUDIO|VIDEO|DATA );
In the prototype of the function, I'd like to use my_enum_e as an input value type, so that when exploring the code, you can immediately know which values you're supposed to put in there.
Now, changing the prototype to
int myFunction( my_enum_e mask );
makes the compiler whine about a cast error. I cant fix it by casting the function calls like this:
int myFunction( my_enum_e mask )
{
// code
}
myFunction( (my_enum_e)(VIDEO|AUDIO|DATA) );
But I find this quite horrible, and I'm not even sure it is legal (could it truncate the value??).
Do you have a solution?
Add an explicit overload for | and possibly other operators.
my_enum_e operator|(my_enum_e a, my_enum_e b)
{ return my_enum_e(unsigned(a)|unsigned(b)); }
One can write a macro that defines all needed operators for a given bitmask type.
#define BITMASK_OPERATORS(T) T operator|(T a, T b) { return T(unsigned(a)|unsigned(b)); } \
T operator^(T a, T b) ...
How about implementing a special function to deal with this:
template <typename Enum>
Enum bitField(unsigned bits) {
return static_cast<Enum>(bits);
}
It adds expressiveness to what you're doing:
myFunction(bitField<my_enum_e>(VIDEO|AUDIO|DATA));
If you want more sophistication, you can do this:
template <typename Enum>
struct BitField {
Enum value;
BitField(Enum value) : value(value) {}
BitField operator|(Enum more) {
return BitField(value | more);
}
BitField operator&(Enum more) {
return BitField(value & more);
}
BitField operator~() {
return BitField(~value);
}
operator Enum() {
return value;
}
}
Which will allow you to write
myFunction(BitField<my_enum_e>(VIDEO) | AUDIO | DATA);
As you performing a bitwise operation the compiler consider VIDEO|AUDIO|DATA as an integer value, so you have to cast it with *my_enum_e*.
I recommend that you look at this thread: Which Typesafe Enum in C++ Are You Using? - The mentioned implemention in the [Boost Vault] (filename enum_rev4.6.zip). 1 provides also the possibility to declare a BOOST_BITFIELD :
BOOST_BITFIELD(my_enum_e,
(AUDIO) (0x01)
(VIDEO) (0x02)
(SUBTITLE) (0x04)
(DATA) (0x08)
);
you can then declare your function:
int myFunction( const my_enum_e & in_enum )
{
if ( in_enum[AUDIO] ) ...
}
The usage is then
void callerFunction()
{
my_enum_e mask;
mask.set(my_enum_e::AUDIO);
mask.set(my_enum_e::VIDEO | my_enum_e::SUBTITLE );
cout << mask << " = " << hex << mask.value() << endl; // will print: AUDIO|VIDEO|SUBTITLE = 0x7
myFunction( mask );
}
The documentation of the api is not that good. But the packages comes with a test that shows several usages.
One way around it is to typedef int MY_FLAGS; and then #define all your values instead:
#define AUDIO 0x01 etc. That way the compiler won't moan and you still get types in your function calls:
int myFunction( MY_FLAGS mask );
myFunction( VIDEO|AUDIO|DATA );

Can I write the contents of vector<bool> to a stream directly from the internal buffer?

I know vector< bool > is "evil", and dynamic_bitset is preferred (bitset is not suitable) but I am using C++ Builder 6 and I don't really want to pursue the Boost route for such an old version. I tried :
int RecordLen = 1;
int NoBits = 8;
std::ofstream Binary( FileNameBinary );
vector< bool > CaseBits( NoBits, 0 );
Binary.write( ( const char * ) & CaseBits[ 0 ], RecordLen);
but the results are incorrect. I suspect that the implementation may mean this is a stupid thing to try, but I don't know.
Operator[] for vector <bool> doesn't return a reference (because bits are not addressable), so taking the return value's address is going to be fraught with problems. Have you considered std::deque <bool>?
the bool vector specialization does not return a reference to bool.
see here, bottom of the page.
It's too late for me to decide how compliant this is, but it works for me: give the bitvector a custom allocator to alias the bits to your own buffer.
Can someone weigh in with whether the rebound allocator inside the vector is required to be copy-constructed from the one passed in? Works on GCC 4.2.1. I seem to recall that the functionality is required for C++0x, and since it's not incompatible with anything in C++03 and is generally useful, support may already be widespread.
Of course, it's implementation-defined whether bits are stored forwards or backwards or left- or right-justified inside whatever storage vector<bool> uses, so take great care.
#include <vector>
#include <iostream>
#include <iomanip>
using namespace std;
template< class T >
struct my_alloc : allocator<T> {
template< class U > struct rebind {
typedef my_alloc<U> other;
};
template< class U >
my_alloc( my_alloc<U> const &o ) {
buf = o.buf;
}
my_alloc( void *b ) { buf = b; }
// noncompliant with C++03: no default constructor
T *allocate( size_t, const void *hint=0 ) {
return static_cast< T* >( buf );
}
void deallocate( T*, size_t ) { }
void *buf;
};
int main() {
unsigned long buf[ 2 ];
vector<bool, my_alloc<bool> > blah( 128, false, my_alloc<bool>( buf ) );
blah[3] = true;
blah[100] = true;
cerr << hex << setw(16) << buf[0] << " " << setw(16) << buf[1] << endl;
}