简体   繁体   中英

Large number of bitwise enums

I've got a question regarding bitwise enums that I just can't seem to resolve. I've got a number of flags that are represented by a bitwise enum as in the following example:

enum
{
    EnumNone=0,
    EnumOne = 1<<0,
    EnumTwo = 1<<1,
    EnumThree = 1<<2,
    EnumFour = 1<<3
};
typedef NSUInteger MyEnum;

All is fine with the above example. Based on my research and various helpful posts in stackoverflow ( this for example ), I've concluded that, using the above example, I'm essentially given 32 options (or shifts if you will), each option representing 1 bit in a 32-bit series of options, which basically tells me that I can go all the way to EnumThirtyTwo = 1 << 31 .

My question is this:

Suppose I've more than 32, say 75 flags for example, to represent using a bitwise enum. How would that best be represented?

enum
{
    EnumNone=0,
    EnumOne = 1<<0,
    EnumTwo = 1<<1,
    EnumThree = 1<<2,
    EnumFour = 1<<3,
    ...
    ...
    EnumSeventyFive = 1<<75
};
typedef NSUInteger MyEnum;

Would it be a simple matter of changing the declaration of my enum type, say, to: typedef long int MyEnum; or typedef long MyEnum ?

You can use a few simple macros/functions and a struct containing a char array of sufficient size - gives you call-by-value semantics, ie just like real enums. Eg something along the lines of (typed directly into answer):

typedef struct
{
    char bits[10]; // enough for 80 bits...
} SeventyFiveFlags;

typedef enum
{
   EnumOne = 0,
   ...
   EnumSeventyFive = 74
} SeventyFiveFlagNames;

NS_INLINE BOOL testFlag(SeventyFiveFlags flags, SeventyFiveFlagNames bit)
{
   return (flags.bits[bit >> 3] & (1 << (bit & 0x7))) != 0;
}

However you can also use the bitstring(3) functions/macros if you are OK with call-by-reference semantics. These create (heap or stack) bit strings of any length. Use your enum to provide symbolic names for the bit numbers rather than masks, eg:

#include <bitstring.h>

typedef enum
{
   EnumOne = 0,
   ...
   EnumSeventyFive = 74,
   SeventyFiveFlagsSize = 75
} SeventyFiveFlagNames;

typedef bitstr_t *SeventyFiveFlags;

// local (stack) declaration & use
SeventyFiveFlags seventyFive;
bit_decl(seventyFive, SeventyFiveFlagsSize); // declare
bit_nclear(seventyFive, EnumOne, EnumSeventyFive); // set all false

if( bit_test(seventyFive, EnumFortyTwo) ) // test

You can always wrap this up as a class if heap allocation only is OK.

Maybe I am talking about something irrelevant.

I think having too much flag in an enum is not a good practise. Having this large amount of flag, there must be ways to group them up like:

enum
{
    EnumNone=0,
    EnumOne = 1<<0,
    EnumTwo = 1<<1,
    EnumThree = 1<<2,
    EnumFour = 1<<3
};
typedef NSUInteger widthRelated;

enum
{
    EnumNone=0,
    EnumOne = 1<<0,
    EnumTwo = 1<<1,
    EnumThree = 1<<2,
    EnumFour = 1<<3
};
typedef NSUInteger heightRelated;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM