因为项目需要,要大量定义类似的枚举类型。
typedef enum test{
test_1,test_2,test3....
}test;
手工写实在太多了,而且容易出错,于考虑用可变参数宏:__VA_ARGS__
来实现,关键就是要实现对__VA_ARGS__
中每个参数元素的遍历。
下面是现实代码,真正调用的宏只有一个FL_FOREACH
,
FL_FOREACH
实现对__VA_ARGS__
中的每个参数执行指定的函数宏fun
,fun
允许有一个外部输入参数funarg
类似于C++11 STL库中的for_each
函数
代码中用到的
FL_ARG_COUNT
宏参见前一篇博客《c/c++:计算可变参数宏__VA_ARGS__
的参数个数》
#define FL_DOARG0(s,f,a,o)
#define FL_DOARG1(s,f,a,v,...) f(a,v)
#define FL_DOARG2(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG1(s,f,a,__VA_ARGS__)
#define FL_DOARG3(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG2(s,f,a,__VA_ARGS__)
#define FL_DOARG4(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG3(s,f,a,__VA_ARGS__)
#define FL_DOARG5(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG4(s,f,a,__VA_ARGS__)
#define FL_DOARG6(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG5(s,f,a,__VA_ARGS__)
#define FL_DOARG7(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG6(s,f,a,__VA_ARGS__)
#define FL_DOARG8(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG7(s,f,a,__VA_ARGS__)
#define FL_DOARG9(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG8(s,f,a,__VA_ARGS__)
#define FL_DOARG10(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG9(s,f,a,__VA_ARGS__)
#define FL_DOARG11(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG10(s,f,a,__VA_ARGS__)
#define FL_DOARG12(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG11(s,f,a,__VA_ARGS__)
#define FL_DOARG13(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG12(s,f,a,__VA_ARGS__)
#define FL_DOARG14(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG13(s,f,a,__VA_ARGS__)
#define FL_DOARG15(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG14(s,f,a,__VA_ARGS__)
#define FL_DOARG16(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG15(s,f,a,__VA_ARGS__)
#define FL_DOARG17(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG16(s,f,a,__VA_ARGS__)
#define FL_DOARG18(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG17(s,f,a,__VA_ARGS__)
#define FL_DOARG19(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG18(s,f,a,__VA_ARGS__)
#define FL_DOARG20(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG19(s,f,a,__VA_ARGS__)
#define FL_DOARG21(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG20(s,f,a,__VA_ARGS__)
#define FL_DOARG22(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG21(s,f,a,__VA_ARGS__)
#define FL_DOARG23(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG22(s,f,a,__VA_ARGS__)
#define FL_DOARG24(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG23(s,f,a,__VA_ARGS__)
#define FL_DOARG25(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG24(s,f,a,__VA_ARGS__)
#define FL_DOARG26(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG25(s,f,a,__VA_ARGS__)
#define FL_DOARG27(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG26(s,f,a,__VA_ARGS__)
#define FL_DOARG28(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG27(s,f,a,__VA_ARGS__)
#define FL_DOARG29(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG28(s,f,a,__VA_ARGS__)
#define FL_DOARG30(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG29(s,f,a,__VA_ARGS__)
#define FL_DOARG31(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG30(s,f,a,__VA_ARGS__)
#define FL_DOARG32(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG31(s,f,a,__VA_ARGS__)
#define FL_DOARG33(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG32(s,f,a,__VA_ARGS__)
#define FL_DOARG34(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG33(s,f,a,__VA_ARGS__)
#define FL_DOARG35(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG34(s,f,a,__VA_ARGS__)
#define FL_DOARG36(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG35(s,f,a,__VA_ARGS__)
#define FL_DOARG37(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG36(s,f,a,__VA_ARGS__)
#define FL_DOARG38(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG37(s,f,a,__VA_ARGS__)
#define FL_DOARG39(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG38(s,f,a,__VA_ARGS__)
#define FL_DOARG40(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG39(s,f,a,__VA_ARGS__)
#define FL_DOARG41(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG40(s,f,a,__VA_ARGS__)
#define FL_DOARG42(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG41(s,f,a,__VA_ARGS__)
#define FL_DOARG43(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG42(s,f,a,__VA_ARGS__)
#define FL_DOARG44(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG43(s,f,a,__VA_ARGS__)
#define FL_DOARG45(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG44(s,f,a,__VA_ARGS__)
#define FL_DOARG46(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG45(s,f,a,__VA_ARGS__)
#define FL_DOARG47(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG46(s,f,a,__VA_ARGS__)
#define FL_DOARG48(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG47(s,f,a,__VA_ARGS__)
#define FL_DOARG49(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG48(s,f,a,__VA_ARGS__)
#define FL_DOARG50(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG49(s,f,a,__VA_ARGS__)
#define FL_DOARG51(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG50(s,f,a,__VA_ARGS__)
#define FL_DOARG52(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG51(s,f,a,__VA_ARGS__)
#define FL_DOARG53(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG52(s,f,a,__VA_ARGS__)
#define FL_DOARG54(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG53(s,f,a,__VA_ARGS__)
#define FL_DOARG55(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG54(s,f,a,__VA_ARGS__)
#define FL_DOARG56(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG55(s,f,a,__VA_ARGS__)
#define FL_DOARG57(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG56(s,f,a,__VA_ARGS__)
#define FL_DOARG58(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG57(s,f,a,__VA_ARGS__)
#define FL_DOARG59(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG58(s,f,a,__VA_ARGS__)
#define FL_DOARG60(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG59(s,f,a,__VA_ARGS__)
#define FL_DOARG61(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG60(s,f,a,__VA_ARGS__)
#define FL_DOARG62(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG61(s,f,a,__VA_ARGS__)
#define FL_DOARG63(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG62(s,f,a,__VA_ARGS__)
#define FL_DOARG64(s,f,a,v,...) FL_DOARG1(s,f,a,v) s FL_DOARG63(s,f,a,__VA_ARGS__)
#define FL_FOREACH_(sepatator,fun,funarg,...) \
FL_CONCAT(FL_DOARG,FL_ARG_COUNT(__VA_ARGS__))(sepatator,fun,funarg,__VA_ARGS__)
#define FL_FOREACH(sepatator,fun,funarg,...) \
FL_FOREACH_(sepatator,fun,funarg,__VA_ARGS__)
// 为动态参数 __VA_ARGS__ 每一个参数调用 fun 宏,最大支持64个参数
// sepatator 分隔符
// fun 函数宏
// funarg 函数宏的参数
有了FL_FOREACH
,就可以实现前述的需求了:
#define enum_elem(p,n) p##n,
// 定义一个名为clsName的枚举类型,动态参数提供枚举类型的元素,最多支持64个元素
// clsName##_为元素名前缀
#define FL_DEF_ENUM(clsName,...)\
enum _##clsName{\
FL_FOREACH(,enum_elem,clsName##_,__VA_ARGS__)\
/* must be last position,for competing enum's number */\
clsName##_LAST_ID \
}clsName;
调用示例:
// 定义4个元素
FL_DEF_ENUM(FL_TEST0, 0, 1, 2, 4)
宏展开代码 (eclipse视图):
// 定义10个元素
FL_DEF_ENUM(FL_TEST, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
// 最大64个
FL_DEF_ENUM(FL_TEST2,\
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\
10,11,12,13,14,15,16,17,18,19,\
20,21,22,23,24,25,26,27,28,29,\
30,31,32,33,34,35,36,37,38,39,\
40,41,42,43,44,45,46,47,48,49,\
50,51,52,53,54,55,56,57,58,59,\
60,61,62,63\
)
FL_TEST
类型(eclipse视图)