M
Marcel Müller
I have quite often the following demand:
An integral parameter to a function or object contains a bit vector with
flags. But I do not want to use the generic type int for this purpose.
Mostly because it prevents the compiler from checking types more strictly.
As work-around I currently use a code fragment like the one shown below.
But this uses a macro.
The question is: is there a more C++ like way for this purpose that does
not demand on macros?
#define FLAGSATTRIBUTE(T) \
inline static T operator|(T l, T r) \
{ return (T)((unsigned)l|r); } \
inline static T operator&(T l, T r) \
{ return (T)((unsigned)l&r); } \
inline static T& operator|=(T& l, T r) \
{ return l = (T)((unsigned)l|r); } \
inline static T& operator&=(T& l, T r) \
{ return l = (T)((unsigned)l&r); } \
inline static T operator*(bool l, T r) \
{ return (T)(l*(unsigned)r); } \
inline static T operator*(T l, bool r) \
{ return (T)((unsigned)l*r); } \
inline static T operator~(T a) \
{ return (T)~(unsigned)a; }
class MyObject
{public:
enum Flag
{ Flag_None = 0x00,
Flag_1 = 0x01,
Flag_2 = 0x02,
Flag_3 = 0x04
//...
};
Flag flags;
//...
};
FLAGSATTRIBUTE(MyObject::Flag)
// valid expressions:
MyObject o;
int i;
o.flags = MyObject::Flag_None;
o.flags |= MyObject::Flag_2;
o.flags = (i == 7) * MyObject::Flag_3;
o.flags &= ~MyObject::Flag_1;
// invalid expressions
o.flags = 0;
o.flags = i;
o.flags = MyObject::Flag_1 + MyObject::Flag_2;
Marcel
An integral parameter to a function or object contains a bit vector with
flags. But I do not want to use the generic type int for this purpose.
Mostly because it prevents the compiler from checking types more strictly.
As work-around I currently use a code fragment like the one shown below.
But this uses a macro.
The question is: is there a more C++ like way for this purpose that does
not demand on macros?
#define FLAGSATTRIBUTE(T) \
inline static T operator|(T l, T r) \
{ return (T)((unsigned)l|r); } \
inline static T operator&(T l, T r) \
{ return (T)((unsigned)l&r); } \
inline static T& operator|=(T& l, T r) \
{ return l = (T)((unsigned)l|r); } \
inline static T& operator&=(T& l, T r) \
{ return l = (T)((unsigned)l&r); } \
inline static T operator*(bool l, T r) \
{ return (T)(l*(unsigned)r); } \
inline static T operator*(T l, bool r) \
{ return (T)((unsigned)l*r); } \
inline static T operator~(T a) \
{ return (T)~(unsigned)a; }
class MyObject
{public:
enum Flag
{ Flag_None = 0x00,
Flag_1 = 0x01,
Flag_2 = 0x02,
Flag_3 = 0x04
//...
};
Flag flags;
//...
};
FLAGSATTRIBUTE(MyObject::Flag)
// valid expressions:
MyObject o;
int i;
o.flags = MyObject::Flag_None;
o.flags |= MyObject::Flag_2;
o.flags = (i == 7) * MyObject::Flag_3;
o.flags &= ~MyObject::Flag_1;
// invalid expressions
o.flags = 0;
o.flags = i;
o.flags = MyObject::Flag_1 + MyObject::Flag_2;
Marcel