I'm currently trying to come up with a clever way of implementing flags that include the states "default" and (optional) "toggle" in addition to the usual "true" and "false".
The general problem with flags is, that one has a function and wants to define its behaviour (either "do something" or "don't do something") by passing certain parameters.
Single flag
With a single (boolean) flag the solution is simple:
void foo(...,bool flag){
if(flag){/*do something*/}
}
Here it is especially easy to add a default, by just changing the function to
void foo(...,bool flag=true)
and call it without the flag parameter.
Multiple flags
Once the number of flags increases, the solution i usually see and use is something like this:
typedef int Flag;
static const Flag Flag1 = 1<<0;
static const Flag Flag2 = 1<<1;
static const Flag Flag3 = 1<<2;
void foo(/*other arguments ,*/ Flag f){
if(f & Flag1){/*do whatever Flag1 indicates*/}
/*check other flags*/
}
//call like this:
foo(/*args ,*/ Flag1 | Flag3)
This has the advantage, that you don't need a parameter for each flag, which means the user can set the flags he likes and just forget about the ones he don't care about. Especially you dont get a call like foo (/*args*/, true, false, true) where you have to count which true/false denotes which flag.
The problem here is:
If you set a default argument, it is overwritten as soon as the user specifies any flag. It is not possible to do somethink like Flag1=true, Flag2=false, Flag3=default.
Obviously, if we want to have 3 options (true, false, default) we need to pass at least 2 bits per flag. So while it might not be neccessary, i guess it should be easy for any implementation to use the 4th state to indicate a toggle (= !default).
I have 2 approaches to this, but i'm not really happy with both of them:
Approach 1: Defining 2 Flags
I tried using something like this up to now:
typedef int Flag;
static const Flag Flag1 = 1<<0;
static const Flag Flag1False= 1<<1;
static const Flag Flag1Toggle = Flag1 | Flag1False;
static const Flag Flag2= 1<<2;
static const Flag Flag2False= 1<<3;
static const Flag Flag2Toggle = Flag2 | Flag2False;
void applyDefault(Flag& f){
//do nothing for flags with default false
//for flags with default true:
f = ( f & Flag1False)? f & ~Flag1 : f | Flag1;
//if the false bit is set, it is either false or toggle, anyway: clear the bit
//if its not set, its either true or default, anyway: set
}
void foo(/*args ,*/ Flag f){
applyDefault(f);
if (f & Flag1) //do whatever Flag1 indicates
}
However what i don't like about this is, that there are two different bits used for each flag. This leads to the different code for "default-true" and "default-false" flags and to the neccessary if instead of some nice bitwise operation in applyDefault().
Approach 2: Templates
By defining a template-class like this:
struct Flag{
virtual bool apply(bool prev) const =0;
};
template<bool mTrue, bool mFalse>
struct TFlag: public Flag{
inline bool apply(bool prev) const{
return (!prev&&mTrue)||(prev&&!mFalse);
}
};
TFlag<true,false> fTrue;
TFlag<false,true> fFalse;
TFlag<false,false> fDefault;
TFlag<true,true> fToggle;
i was able to condense the apply into a single bitwise operation, with all but 1 argument known at compile time. So using the TFlag::apply directly compiles (using gcc) to the same machine code as a return true;, return false;, return prev; or return !prev; would, which is pretty efficient, but that would mean i have to use template-functions if i want to pass a TFlag as argument. Inheriting from Flag and using a const Flag& as argument adds the overhead of a virtual function call, but saves me from using templates.
However i have no idea how to scale this up to multiple flags...
Question
So the question is:
How can i implement multiple flags in a single argument in C++, so that a user can easily set them to "true", "false" or "default" (by not setting the specific flag) or (optional) indicate "whatever is not default"?
Is a class with two ints, using a similar bitwise operation like the template-approach with its own bitwise-operators the way to go? And if so, is there a way to give the compiler the option to do most of the bitwise operations at compile-time?
Edit for clarification:
I don't want to pass the 4 distinct flags "true", "false", "default", "toggle" to a function.
E.g. think of a circle that gets drawn where the flags are used for "draw border", "draw center", "draw fill color", "blurry border", "let the circle hop up and down", "do whatever other fancy stuff you can do with a circle", ....
And for each of those "properties" i want to pass a flag with value either true, false, default or toggle.
So the function might decide to draw the border, fill color and center by default, but none of the rest. A call, roughly like this:
draw_circle (DRAW_BORDER | DONT_DRAW_CENTER | TOGGLE_BLURRY_BORDER) //or
draw_circle (BORDER=true, CENTER=false, BLURRY=toggle)
//or whatever nice syntax you come up with....
should draw the border (specified by flag), not draw the center (specified by flag), blurry the border (the flag says: not the default) and draw the fill color (not specified, but its default).
If i later decide to not draw the center by default anymore but blurry the border by default, the call should draw the border (specified by flag), not draw the center (specified by flag), not blurry the border (now blurrying is default, but we don't want default) and draw the fill color (no flag for it, but its default).
Not exactly pretty, but very simple (building from your Approach 1):
#include <iostream>
using Flag = int;
static const Flag Flag1 = 1<<0;
static const Flag Flag2 = 1<<2;
// add more flags to turn things off, etc.
class Foo
{
bool flag1 = true; // default true
bool flag2 = false; // default false
void applyDefault(Flag& f)
{
if (f & Flag1)
flag1 = true;
if (f & Flag2)
flag2 = true;
// apply off flags
}
public:
void operator()(/*args ,*/ Flag f)
{
applyDefault(f);
if (flag1)
std::cout << "Flag 1 ON\n";
if (flag2)
std::cout << "Flag 2 ON\n";
}
};
void foo(/*args ,*/ Flag flags)
{
Foo f;
f(flags);
}
int main()
{
foo(Flag1); // Flag1 ON
foo(Flag2); // Flag1 ON\nFlag2 ON
foo(Flag1 | Flag2); // Flag1 ON\nFlag2 ON
return 0;
}
Your comments and answers pointed me towards a solution that i like and wanted to share with you:
struct Default_t{} Default;
struct Toggle_t{} Toggle;
struct FlagSet{
uint m_set;
uint m_reset;
constexpr FlagSet operator|(const FlagSet other) const{
return {
~m_reset & other.m_set & ~other.m_reset |
~m_set & other.m_set & other.m_reset |
m_set & ~other.m_set,
m_reset & ~other.m_reset |
~m_set & ~other.m_set & other.m_reset|
~m_reset & other.m_set & other.m_reset};
}
constexpr FlagSet& operator|=(const FlagSet other){
*this = *this|other;
return *this;
}
};
struct Flag{
const uint m_bit;
constexpr FlagSet operator= (bool val) const{
return {(uint)val<<m_bit,(!(uint)val)<<m_bit};
}
constexpr FlagSet operator= (Default_t) const{
return {0u,0u};
}
constexpr FlagSet operator= (Toggle_t) const {
return {1u<<m_bit,1u<<m_bit};
}
constexpr uint operator& (FlagSet i) const{
return i.m_set & (1u<<m_bit);
}
constexpr operator FlagSet() const{
return {1u<<m_bit,0u}; //= set
}
constexpr FlagSet operator|(const Flag other) const{
return (FlagSet)*this|(FlagSet)other;
}
constexpr FlagSet operator|(const FlagSet other) const{
return (FlagSet)*this|other;
}
};
constexpr uint operator& (FlagSet i, Flag f){
return f & i;
}
So basically the FlagSet holds two integers. One for set, one for reset. Different combinations represent different actions for that particular bit:
{false,false} = Default (D)
{true ,false} = Set (S)
{false,true } = Reset (R)
{true ,true } = Toggle (T)
The operator| is using a rather complex bitwise operation, designed to fullfill
D|D = D
D|R = R|D = R
D|S = S|D = S
D|T = T|D = T
T|T = D
T|R = R|T = S
T|S = S|T = R
S|S = S
R|R = R
S|R = S (*)
R|S = R (*)
The non-commutative behaviour in (*) is due to the fact, that we somehow need the ability to decide which one is the "default" and which one is the "user defined" one. So in case of conflicting values, the left one takes precedence.
The Flag class represents a single flag, basically one of the bits. Using the different operator=() overloads enables some kind of "Key-Value-Notation" to convert directly to a FlagSet with the bit-pair at position m_bit set to one of the previously defined pairs. By default (operator FlagSet()) this converts to a Set(S) action on the given bit.
The class also provides some overloads for bitwise-OR that auto convert to FlagSet and operator&() to actually compare the Flag with a FlagSet. In this comparison both Set(S) and Toggle(T) are considered true while both Reset(R) and Default(D) are considered false.
Using this is incredibly simple and very close to the "usual" Flag-implementation:
constexpr Flag Flag1{0};
constexpr Flag Flag2{1};
constexpr Flag Flag3{2};
constexpr auto NoFlag1 = (Flag1=false); //Just for convenience, not really needed;
void foo(FlagSet f={0,0}){
f |= Flag1|Flag2; //This sets the default. Remember: default right, user left
cout << ((f & Flag1)?"1":"0");
cout << ((f & Flag2)?"2":"0");
cout << ((f & Flag3)?"3":"0");
cout << endl;
}
int main() {
foo();
foo(Flag3);
foo(Flag3|(Flag2=false));
foo(Flag3|NoFlag1);
foo((Flag1=Toggle)|(Flag2=Toggle)|(Flag3=Toggle));
return 0;
}
Output:
120
123
103
023
003
Test it on ideone
One last word about efficiency: While i didn't test it without all the constexpr keywords, with them this code:
bool test1(){
return Flag1&((Flag1=Toggle)|(Flag2=Toggle)|(Flag3=Toggle));
}
bool test2(){
FlagSet f = Flag1|Flag2 ;
return f & Flag1;
}
bool test3(FlagSet f){
f |= Flag1|Flag2 ;
return f & Flag1;
}
compiles to (usign gcc 5.3 on gcc.godbolt.org)
test1():
movl $1, %eax
ret
test2():
movl $1, %eax
ret
test3(FlagSet):
movq %rdi, %rax
shrq $32, %rax
notl %eax
andl $1, %eax
ret
and while i'm not totally familiar with Assembler-Code, this looks like very basic bitwise operations and probably the fastest you can get without inlining the test-functions.
If I understand the question you can solve the problem by creating a simple class with implicit constructor from bool and default constructor:
class T
{
T(bool value):def(false), value(value){} // implicit constructor from bool
T():def(true){}
bool def; // is flag default
bool value; // flag value if flag isn't default
}
and using it in function like this:
void f(..., T flag = T());
void f(..., true); // call with flag = true
void f(...); // call with flag = default
If I understand correctly, you want a simple way to pass one or more flags to a function as a single parameter, and/or a simple way for an object to keep track of one or more flags in a single variable, correct? A simple approach would be to specify the flags as a typed enum, with an unsigned underlying type large enough to hold all the flags you need. For example:
/* Assuming C++11 compatibility. If you need to work with an older compiler, you'll have
* to manually insert the body of flag() into each BitFlag's definition, and replace
* FLAG_INVALID's definition with something like:
* FLAG_INVALID = static_cast<flag_t>(-1) -
* (FFalse + FTrue + FDefault + FToggle),
*/
#include <climits>
// For CHAR_BIT.
#include <cstdint>
// For uint8_t.
// Underlying flag type. Change as needed. Should remain unsigned.
typedef uint8_t flag_t;
// Helper functions, to provide cleaner syntax to the enum.
// Not actually necessary, they'll be evaluated at compile time either way.
constexpr flag_t flag(int f) { return 1 << f; }
constexpr flag_t fl_validate(int f) {
return (f ? (1 << f) + fl_validate(f - 1) : 1);
}
constexpr flag_t register_invalids(int f) {
// The static_cast is a type-independent maximum value for unsigned ints. The compiler
// may or may not complain.
// (f - 1) compensates for bits being zero-indexed.
return static_cast<flag_t>(-1) - fl_validate(f - 1);
}
// List of available flags.
enum BitFlag : flag_t {
FFalse = flag(0), // 0001
FTrue = flag(1), // 0010
FDefault = flag(2), // 0100
FToggle = flag(3), // 1000
// ...
// Number of defined flags.
FLAG_COUNT = 4,
// Indicator for invalid flags. Can be used to make sure parameters are valid, or
// simply to mask out any invalid ones.
FLAG_INVALID = register_invalids(FLAG_COUNT),
// Maximum number of available flags.
FLAG_MAX = sizeof(flag_t) * CHAR_BIT
};
// ...
void func(flag_t f);
// ...
class CL {
flag_t flags;
// ...
};
Note that this assumes that FFalse and FTrue should be distinct flags, both of which can be specified at the same time. If you want them to be mutually exclusive, a couple small changes would be necessary:
// ...
constexpr flag_t register_invalids(int f) {
// Compensate for 0th and 1st flags using the same bit.
return static_cast<flag_t>(-1) - fl_validate(f - 2);
}
// ...
enum BitFlag : flag_t {
FFalse = 0, // 0000
FTrue = flag(0), // 0001
FDefault = flag(1), // 0010
FToggle = flag(2), // 0100
// ...
Alternatively, instead of modifying the enum itself, you could modify flag():
// ...
constexpr flag_t flag(int f) {
// Give bit 0 special treatment as "false", shift all other flags down to compensate.
return (f ? 1 << (f - 1) : 0);
}
// ...
constexpr flag_t register_invalids(int f) {
return static_cast<flag_t>(-1) - fl_validate(f - 2);
}
// ...
enum BitFlag : flag_t {
FFalse = flag(0), // 0000
FTrue = flag(1), // 0001
FDefault = flag(2), // 0010
FToggle = flag(3), // 0100
// ...
While I believe this to be the simplest approach, and possibly the most memory-efficient if you choose the smallest possible underlying type for flag_t, it is likely also the least useful. [Also, if you end up using this or something similar, I would suggest hiding the helper functions in a namespace, to prevent unnecessary clutter in the global namespace.]
A simple example.
Is there a reason we cannot use an enum for this? Here is a solution that I have used recently:
// Example program
#include <iostream>
#include <string>
enum class Flag : int8_t
{
F_TRUE = 0x0, // Explicitly defined for readability
F_FALSE = 0x1,
F_DEFAULT = 0x2,
F_TOGGLE = 0x3
};
struct flags
{
Flag flag_1;
Flag flag_2;
Flag flag_3;
Flag flag_4;
};
int main()
{
flags my_flags;
my_flags.flag_1 = Flag::F_TRUE;
my_flags.flag_2 = Flag::F_FALSE;
my_flags.flag_3 = Flag::F_DEFAULT;
my_flags.flag_4 = Flag::F_TOGGLE;
std::cout << "size of flags: " << sizeof(flags) << "\n";
std::cout << (int)(my_flags.flag_1) << "\n";
std::cout << (int)(my_flags.flag_2) << "\n";
std::cout << (int)(my_flags.flag_3) << "\n";
std::cout << (int)(my_flags.flag_4) << "\n";
}
Here, we get the following output:
size of flags: 4
0
1
2
3
It's not quite memory efficient this way. Each Flag is 8 bits compared to two bools at one bit each, for a 4x memory increase. However, we are afforded the benefits of enum class which prevents some stupid programmer mistakes.
Now, I have another solution for when memory is critical. Here we pack 4 flags into an 8-bit struct. This one I came up with for a data editor, and it worked perfectly for my uses. However there may be downsides that I am now aware of.
// Example program
#include <iostream>
#include <string>
enum Flag
{
F_TRUE = 0x0, // Explicitly defined for readability
F_FALSE = 0x1,
F_DEFAULT = 0x2,
F_TOGGLE = 0x3
};
struct PackedFlags
{
public:
bool flag_1_0:1;
bool flag_1_1:1;
bool flag_2_0:1;
bool flag_2_1:1;
bool flag_3_0:1;
bool flag_3_1:1;
bool flag_4_0:1;
bool flag_4_1:1;
public:
Flag GetFlag1()
{
return (Flag)(((int)flag_1_1 << 1) + (int)flag_1_0);
}
Flag GetFlag2()
{
return (Flag)(((int)flag_2_1 << 1) + (int)flag_2_0);
}
Flag GetFlag3()
{
return (Flag)(((int)flag_3_1 << 1) + (int)flag_3_0);
}
Flag GetFlag4()
{
return (Flag)(((int)flag_4_1 << 1) + (int)flag_4_0);
}
void SetFlag1(Flag flag)
{
flag_1_0 = (flag & (1 << 0));
flag_1_1 = (flag & (1 << 1));
}
void SetFlag2(Flag flag)
{
flag_2_0 = (flag & (1 << 0));
flag_2_1 = (flag & (1 << 1));
}
void SetFlag3(Flag flag)
{
flag_3_0 = (flag & (1 << 0));
flag_3_1 = (flag & (1 << 1));
}
void SetFlag4(Flag flag)
{
flag_4_0 = (flag & (1 << 0));
flag_4_1 = (flag & (1 << 1));
}
};
int main()
{
PackedFlags my_flags;
my_flags.SetFlag1(F_TRUE);
my_flags.SetFlag2(F_FALSE);
my_flags.SetFlag3(F_DEFAULT);
my_flags.SetFlag4(F_TOGGLE);
std::cout << "size of flags: " << sizeof(my_flags) << "\n";
std::cout << (int)(my_flags.GetFlag1()) << "\n";
std::cout << (int)(my_flags.GetFlag2()) << "\n";
std::cout << (int)(my_flags.GetFlag3()) << "\n";
std::cout << (int)(my_flags.GetFlag4()) << "\n";
}
Output:
size of flags: 1
0
1
2
3
I'm playing with lock-free algorithms in C and C++ and recently stumbled upon a behavior I don't quite understand. If you have the following code, running it will give you something like
reader started
writer started
iters=79895047, less=401131, eq=48996928, more=30496988
Aren't std::atomics are expected to be sequentially-consistent? If so, why does the reader sometimes see b being updated before a? I also tried to do various tricks involving memory fences with no success. The full compilable code can be seen at https://github.com/akamaus/fence_test
What's wrong with the example?
std::atomic<uint> a(0);
std::atomic<uint> b(0);
volatile bool stop = false;
void *reader(void *p) {
uint64_t iter_counter = 0;
uint cnt_less = 0,
cnt_eq = 0,
cnt_more = 0;
uint aa, bb;
printf("reader started\n");
while(!stop) {
iter_counter++;
aa = a.load(std::memory_order_seq_cst);
bb = b.load(std::memory_order_seq_cst);
if (aa < bb) {
cnt_less++;
} else if (aa > bb) {
cnt_more++;
} else {
cnt_eq++;
}
}
printf("iters=%lu, less=%u, eq=%u, more=%u\n", iter_counter, cnt_less, cnt_eq, cnt_more);
return NULL;
}
void *writer(void *p) {
printf("writer started\n");
uint counter = 0;
while(!stop) {
a.store(counter, std::memory_order_seq_cst);
b.store(counter, std::memory_order_seq_cst);
counter++;
}
}
Sequentially consistent memory ordering implies that the modification order (of the atomic objects manipulated with seq cst) observed by all threads is consistent. The program behaves as if all those operations happen interleaved in a single total order. Consider the following cases:
Writer Reader
a == 0
a = 1
b = 1
b == 1
Result: aa < bb.
Writer Reader
a = 1
a == 1
b == 0
b = 1
Result: aa > bb
With a lock, e.g. a mutex, you can make sure that the operations don't interleave.
I have the following bitfield struct:
struct DescriptorByte
{
unsigned short IsImmedCalc : 1;
unsigned short IsPrefix : 1;
unsigned short NoMemOp : 1;
unsigned short Size : 5;
};
I want to create an table for holding many DescriptorByte struct, so i created this:
struct OpcodeList
{
DescriptorByte ADD_8_MO;
DescriptorByte ADD_32_MO;
DescriptorByte ADD_8_OM;
DescriptorByte ADD_32_OM;
DescriptorByte ADD_8_OI = { TRUE, FALSE, TRUE, 1 + 1 };
DescriptorByte ADD_32_OI = { TRUE, FALSE, TRUE, 1 + 4 };
DescriptorByte PUSH_ES = { TRUE, FALSE, TRUE, 1 };
};
So is this the same as having an struct with each member beign 1 byte long?. Also i want to be able to reference the initializator member like this:
DescriptorByte ADD_8_OI = { IsImmedCalc = true, Size = 1 };
but visual studio is not letting me. The idea behind all of this is having a table of DescriptorByte, is this the best approach? also what is the best initialization method? thanks.
"is this the same as having a struct with each member being 1 byte long?"
Your compiler might add padding if you do not use #pragma pack or something similar.
But there isn't any padding required in this specific case, so essentially the answer is yes.
Just change the unsigned short to unsigned char and each member will be 1 byte long.
Add '.' on the left side of each field:
DescriptorByte ADD_8_OI = { .IsImmedCalc = true, .Size = 1 };
Alternatively, just write the actual values in the correct order (missing ones will be set to 0):
DescriptorByte ADD_8_OI = { true, 1 };
EDIT: Posted this thinking it was a C# question, sorry! Leaving it here for others.
C# does not support bit-fields. However, you can still 'emulate' that behavior using a single member variable of the appropriate size along with various getter properties.
In your example, you want to use an unsigned 8-bit integer value (byte) and encapsulate those bitfields. Have no fear, you can still use a struct to do all this to make marshaling and interop easier.
So let's take your DescriptorByte and recreate what you are looking to do:
struct DescriptorByte
{
static readonly byte IsImmedCalcFlag = 0x80; // 1000 0000
static readonly byte IsPrefixFlag = 0x40; // 0100 0000
static readonly byte NoMemOpFlag = 0x20; // 0010 0000
static readonly byte FlagsBitMask = 0xE0; // 1110 0000
static readonly byte SizeBitMask = 0x1F; // 0001 1111
byte field;
public bool IsImmedCalc
{
get { return (field & IsImmedCalcFlag) > 0; }
set
{
if (value)
field = (byte)(field | IsImmedCalcFlag); // Set the bit
else
field = (byte)(field & ~IsImmedCalcFlag); // Clear the bit
}
}
public bool IsPrefix
{
get { return (field & IsPrefixFlag) > 0; }
set
{
if (value)
field = (byte)(field | IsPrefixFlag); // Set the bit
else
field = (byte)(field & ~IsPrefixFlag); // Clear the bit
}
}
public bool NoMemOp
{
get { return (field & NoMemOpFlag) > 0; }
set
{
if (value)
field = (byte)(field | NoMemOpFlag); // Set the bit
else
field = (byte)(field & ~NoMemOpFlag); // Clear the bit
}
}
public byte Size
{
get { return (byte)(field & SizeBitMask); }
set { field = (byte)((field & FlagsBitMask) | (value & SizeBitMask)); }
}
}
How could I make a function with flags like how Windows' CreateWindow(...style | style,...), for example, a createnum function:
int CreateNum(flag flags) //???
{
int num = 0;
if(flags == GREATER_THAN_TEN)
num = 11;
if(flags == EVEN && ((num % 2) == 1)
num++;
else if(flags == ODD && ((num % 2) == 0)
num++;
return num;
}
//called like this
int Number = CreateNum(GREATER_THAN_TEN | EVEN);
Is this possible, and if so, how?
You can define an enum specifying "single bit" values (note that the enclosing struct is acting here only as a naming context, so that you can write e.g. MyFlags::EVEN):
struct MyFlags{
enum Value{
EVEN = 0x01,
ODD = 0x02,
ANOTHER_FLAG = 0x04,
YET_ANOTHER_FLAG = 0x08,
SOMETHING_ELSE = 0x10,
SOMETHING_COMPLETELY_DIFFERENT = 0x20
};
};
and then use it like this:
int CreateNum(MyFlags::Value flags){
if (flags & MyFlags::EVEN){
// do something...
}
}
void main(){
CreateNum((MyFlags::Value)(MyFlags::EVEN | MyFlags::ODD));
}
or simply like this:
int CreateNum(int flags){
if (flags & MyFlags::EVEN){
// do something...
}
}
void main(){
CreateNum(MyFlags::EVEN | MyFlags::ODD);
}
You could also simply declare integer constants, but the enum is clearer in my opinion.
Note: I updated the post to take some comments into account, thanks!
I upvoted orsogufo's answer, but I always liked doing the following for defining the values:
enum Value{
EVEN = (1<<0),
ODD = (1<<2),
ANOTHER_FLAG = (1<<3),
YET_ANOTHER_FLAG = (1<<4),
SOMETHING_ELSE = (1<<5),
SOMETHING_COMPLETELY_DIFFERENT = (1<<6),
ANOTHER_EVEN = EVEN|ANOTHER_FLAG
};
<< is the shift operator. Incrementing the right side lets you generate sequential bit masks by moving the 1 over, one bit at a time. This has the same values for the bare flags, but reads easier to my eyes and makes it obvious if you skip or duplicate a value.
I also like combining some common flag combinations when appropriate.
You can use const int like this:
const int FLAG1 = 0x0001;
const int FLAG2 = 0x0010;
const int FLAG3 = 0x0100;
// ...
And when you use it:
int CreateNum(int flags)
{
if( flags & FLAG1 )
// FLAG1 is present
if( flags & FLAG2 )
// FLAG2 is present
// ...
}
Of course you can put one or more flag in your flags using the | operator.
Use powers of two as the individual constants, like
enum Flags { EVEN = 0x1, ODD = 0x2, GREATER_TEN = 0x4 };
and you use the logical and operator '&' for testing, like
if( flags & GREATER_THAN_TEN)
num = 11;
if( (flags & EVEN) && (num % 2) == 1 )
num++;
else if ( (flags & ODD) && (num % 2) == 0 )
num++;
return num;
You've got your tests wrong. What you want is something like (flags & EVEN), where EVEN is an integer with a single bit set (1, 2, 4, 8, 16 - some power of 2). (The integer can be an int or an enum. You could have a macro, but that's generally not a good idea.)
You can use the notation you listed, by overloading flags::operator==(flagvalue f), but it's a bad idea.
enum flags {
EVEN = 0x0100,
ODD = 0x0200,
BELOW_TEN = 0x0400,
ABOVETEN = 0x0800,
HUNDRED = 0x1000,
MASK = 0xff00
};
void some_func(int id_and_flags)
{
int the_id = id_and_flags & ~MASK;
int flags = id_and_flags & MASK;
if ((flags & EVEN) && (the_id % 2) == 1)
++the_id;
if ((flags & ODD) && (the_id % 2) == 0)
++the_id;
// etc
}
Illustrates masking of bit fields too which can be useful when you just need to bolt on a simplistic bit of extra functionality without adding any extra data structure.