Sign in to follow this  

Using 'Flags'

This topic is 4305 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Okay. I know it's declared as an int, but I have no idea where to go from there. In many functions I've used, I can pass different flags ( SDL_SRCALPHA | SDL_OPENGL ), or whatever. Now, I want to make my own function which'll take flags. Can someone point me to a tutorial on how to do it, or just post an explanation? Thanks in advance, :) Erondial

Share this post


Link to post
Share on other sites
Flags work by using the distinct bits in an integer to represent on/off values.

For instance, you can decide that bit 1 means "GREEN", bit 2 means "BLUE", bit 3 means "RED" and bit 4 means "ALPHA" (for instance, when selecting which channels to read from a file). So you would create the following values:


enum ColorFlags {
GREEN = 0x1,
BLUE = 0x2,
RED = 0x4,
ALPHA = 0x8
};


Then, the | operation mixes the bits: it's a bitwise or operation. For instance:


00010101
| 10101001
----------
10111101


Finally, to determine if a flag is set, you use the bitwise and operator, &. For instance, to check if the GREEN flag is set, you'd use if( flags & GREEN ). Applied to GREEN | RED | ALPHA, it would work this way:


00001101
& 00000001
----------
00000001 // non-zero


Applied to RED | BLUE, it would be:


00000110
& 00000001
----------
00000000 // zero


The result is zero if the flag is not set, and is equal to the flag if the flag is set.

Share this post


Link to post
Share on other sites
To define your flags I would recommend using a helper enum:

enum Bits {
BIT0 = (1 << 0),
BIT1 = (1 << 1),
BIT2 = (1 << 2),
...
BIT31 = (1 << 31),
};


Then to declare your flags you can simply write:

enum ColorFlags {
GREEN = BIT0,
BLUE = BIT1,
RED = BIT2,
ALPHA = BIT3
};

Share this post


Link to post
Share on other sites
A clean, type-safe way of doing flags in C++:

namespace MY_FLAG_TYPE_NS {
typedef enum {
NO_FLAG = 0,
FLAG_1 = 1<<0,
FLAG_2 = 1<<1,
FLAG_3 = 1<<2,
FLAG_4 = 1<<3,
FLAG_5 = 1<<4,
// etc...
} MY_FLAG_TYPE;
// some operators that are useful on flags:
MY_FLAG_TYPE operator|(MY_FLAG_TYPE left, MY_FLAG_TYPE right) {return (MY_FLAG_TYPE)(left|right);}

// implement as well:
MY_FLAG_TYPE operator&(...){...}
MY_FLAG_TYPE operator^(...){...}
MY_FLAG_TYPE operator~(...){...)
}
using MY_FLAG_TYPE_NS::MY_FLAG_TYPE;

// example use:
// void do_stuff( MY_FLAG_TYPE flags );
//
// use of the do_stuff function:
// do_stuff( MY_FLAG_TYPE_NS::FLAG_1 | MY_FLAG_TYPE_NS::FLAG_5 );
// or:
// using namespace MY_FLAG_TYPE_NS;
// do_stuff( FLAG_1 | FLAG_3 );
//
// To test if a flag is set:
// void func( MY_FLAG_TYPE flag ) {
// if (flag & MY_FLAG_TYPE_NS::FLAG_1) {
// ... (code goes here)
// } else if (flag & MY_FLAG_TYPE_NS::FLAG_3) {
// ... (code goes here)
// }
// }


Naturally, you would pick good names for MY_FLAG_TYPE and the flags (FLAG_1, FLAG_2) that are valid.

By using an enum instead of an int, and defining the operators one likes to use on a flag, you allow the the code to be more type-safe. It also makes your code self-documenting -- just by looking at your function's signature and the types of the variables, you can tell what flags your function accepts.

HTH.

[Edited by - NotAYakk on March 1, 2006 7:10:04 PM]

Share this post


Link to post
Share on other sites

This topic is 4305 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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