Here's what I got:
enum X {
NONE = 0x00000000,
FLAG_1 = 0x00000001,
FLAG_2 = 0x00000002,
FLAG_3 = 0x00000004,
FLAG_4 = 0x00000008,
FLAG_5 = 0x00000010,
// ...
FLAG_32 = 0x80000000
}
Is there a way to make "bit numbering" automatic so I could like insert a flag so all that goes next get "renumbered"?
I'm just designing an API and I want to keep related flags together, ordered in a specific sequence. The problem is when I add something that goes in the middle I have to manually reassign all numbering that goes after the inserted item. Let's say in my example I want to add FLAG_2A = 0x00000004, and FLAG_3 should be 0x00000008 and so on. Is there a "full auto" way of doing it?
OK, here's the first thing that comes to mind:
#include <stdio.h>
enum { __FLAGS1_BASE = __COUNTER__ };
#define __FLAGS1_CT 1 << (__COUNTER__ - __FLAGS1_BASE - 1)
typedef enum __TEST1 {
FLAG1_0 = 0,
FLAG1_1 = __FLAGS1_CT,
FLAG1_2 = __FLAGS1_CT,
FLAG1_3 = __FLAGS1_CT,
FLAG1_4 = __FLAGS1_CT
} TEST1;
enum { __FLAGS2_BASE = __COUNTER__ };
#define __FLAGS2_CT 1 << (__COUNTER__ - __FLAGS2_BASE - 1)
typedef enum __TEST2 {
FLAG2_0 = 0,
FLAG2_1 = __FLAGS2_CT,
FLAG2_2 = __FLAGS2_CT,
FLAG2_3 = __FLAGS2_CT,
FLAG2_4 = __FLAGS2_CT
} TEST2;
int main() {
printf("X = %u\n", FLAG2_3); // should output 4.
return 0;
}
Is it the only way, or is there something simpler than that?
I threw together a quick implementation of the MAKE_FLAGS macro HolyBlackCat suggested:
#define E3(...) E2(E2(E2(E2(E2(E2(E2(__VA_ARGS__)))))))
#define E2(...) E1(E1(E1(E1(E1(E1(E1(E1(__VA_ARGS__))))))))
#define E1(...) __VA_ARGS__
#define EMPTY()
#define TUPLE_AT_2(x,y,...) y
#define CHECK(...) TUPLE_AT_2(__VA_ARGS__,0,)
#define EQ_END_END ,1
#define CAT(a,b) CAT_(a,b)
#define CAT_(a,b) a##b
#define LOOP_() LOOP
#define LOOP(x,y,...) CAT(LOOP, CHECK(EQ_END_##y))(x,y,__VA_ARGS__)
#define LOOP1(x,...)
#define LOOP0(x,y,...) y = x << 1, LOOP_ EMPTY() ()(y,__VA_ARGS__)
#define HEAD(x,...) x
#define MAKE_FLAGS(name,...) typedef enum { HEAD(__VA_ARGS__,) = 1, E3(LOOP(__VA_ARGS__, END)) } name
MAKE_FLAGS(MyEnum, flag1, flag2, flag3, flag4);
// expands to:
// typedef enum { flag1 = 1, flag2 = flag1 << 1, flag3 = flag2 << 1, flag4 = flag3 << 1, } MyEnum;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With