大量按位枚举

时间:2012-06-20 17:57:35

标签: objective-c enums bit-manipulation

我有一个关于按位枚举的问题,我似乎无法解决。我有一些由按位枚举表示的标志,如下例所示:

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

上面的例子一切都很好。基于我的研究和stackoverflow中的各种有用的帖子(this for example),我得出结论,使用上面的例子,我基本上给出了32个选项(或者如果你愿意的话,可以移位),每个选项代表1位一个32位的系列选项,基本上告诉我,我可以一直到EnumThirtyTwo = 1 << 31

我的问题是:

假设我使用按位枚举来表示超过32,例如75个标志。如何最好地代表?

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

将枚举类型的声明更改为:typedef long int MyEnum;typedef long MyEnum会不会很简单?

2 个答案:

答案 0 :(得分:3)

您可以使用一些简单的宏/函数和一个struct包含足够大小的char数组 - 为您提供按值调用语义,即就像真实的枚举。例如。 (直接输入答案):

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;
}

但是如果你对 call-by-reference 语义没问题,你也可以使用bitstring(3)函数/宏。这些创建(堆或堆栈)任意长度的位串。使用枚举为位数而不是掩码提供符号名称,例如:

#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

如果只有堆分配正常,你总是可以将它作为一个包装。

答案 1 :(得分:0)

也许我在谈论无关紧要的事情。

我认为在枚举中有太多旗帜并不是一个好习惯。拥有这么大量的旗帜,必须有方法将它们分组,如:

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;